web: migrate remaining list views to web
This commit is contained in:
		| @ -1,109 +0,0 @@ | |||||||
| {% extends "administration/base.html" %} |  | ||||||
|  |  | ||||||
| {% load i18n %} |  | ||||||
| {% load authentik_utils %} |  | ||||||
|  |  | ||||||
| {% block content %} |  | ||||||
| <section class="pf-c-page__main-section pf-m-light"> |  | ||||||
|     <div class="pf-c-content"> |  | ||||||
|         <h1> |  | ||||||
|             <i class="pf-icon pf-icon-migration"></i> |  | ||||||
|             {% trans 'Invitations' %} |  | ||||||
|         </h1> |  | ||||||
|         <p>{% trans "Create Invitation Links to enroll Users, and optionally force specific attributes of their account." %} |  | ||||||
|         </p> |  | ||||||
|     </div> |  | ||||||
| </section> |  | ||||||
| <section class="pf-c-page__main-section pf-m-no-padding-mobile"> |  | ||||||
|     <div class="pf-c-card"> |  | ||||||
|         {% if object_list %} |  | ||||||
|         <div class="pf-c-toolbar"> |  | ||||||
|             <div class="pf-c-toolbar__content"> |  | ||||||
|                 {% include 'partials/toolbar_search.html' %} |  | ||||||
|                 <div class="pf-c-toolbar__bulk-select"> |  | ||||||
|                     <ak-modal-button href="{% url 'authentik_admin:stage-invitation-create' %}"> |  | ||||||
|                         <ak-spinner-button slot="trigger" class="pf-m-primary"> |  | ||||||
|                             {% trans 'Create' %} |  | ||||||
|                         </ak-spinner-button> |  | ||||||
|                         <div slot="modal"></div> |  | ||||||
|                     </ak-modal-button> |  | ||||||
|                     <button role="ak-refresh" class="pf-c-button pf-m-primary"> |  | ||||||
|                         {% trans 'Refresh' %} |  | ||||||
|                     </button> |  | ||||||
|                 </div> |  | ||||||
|                 {% include 'partials/pagination.html' %} |  | ||||||
|             </div> |  | ||||||
|         </div> |  | ||||||
|         <table class="pf-c-table pf-m-compact pf-m-grid-xl" role="grid"> |  | ||||||
|             <thead> |  | ||||||
|                 <tr role="row"> |  | ||||||
|                     <th role="columnheader" scope="col">{% trans 'ID' %}</th> |  | ||||||
|                     <th role="columnheader" scope="col">{% trans 'Created by' %}</th> |  | ||||||
|                     <th role="columnheader" scope="col">{% trans 'Expiry' %}</th> |  | ||||||
|                     <th role="cell"></th> |  | ||||||
|                 </tr> |  | ||||||
|             </thead> |  | ||||||
|             <tbody role="rowgroup"> |  | ||||||
|                 {% for invitation in object_list %} |  | ||||||
|                 <tr role="row"> |  | ||||||
|                     <td role="cell"> |  | ||||||
|                         <span> |  | ||||||
|                             {{ invitation.invite_uuid }} |  | ||||||
|                         </span> |  | ||||||
|                     </td> |  | ||||||
|                     <td role="cell"> |  | ||||||
|                         <span> |  | ||||||
|                             {{ invitation.created_by }} |  | ||||||
|                         </span> |  | ||||||
|                     </td> |  | ||||||
|                     <td role="cell"> |  | ||||||
|                         <span> |  | ||||||
|                             {{ invitation.expiry|default:"-" }} |  | ||||||
|                         </span> |  | ||||||
|                     </td> |  | ||||||
|                     <td> |  | ||||||
|                         <ak-modal-button href="{% url 'authentik_admin:stage-invitation-delete' pk=invitation.pk %}"> |  | ||||||
|                             <ak-spinner-button slot="trigger" class="pf-m-danger"> |  | ||||||
|                                 {% trans 'Delete' %} |  | ||||||
|                             </ak-spinner-button> |  | ||||||
|                             <div slot="modal"></div> |  | ||||||
|                         </ak-modal-button> |  | ||||||
|                     </td> |  | ||||||
|                 </tr> |  | ||||||
|                 {% endfor %} |  | ||||||
|             </tbody> |  | ||||||
|         </table> |  | ||||||
|         <div class="pf-c-pagination pf-m-bottom"> |  | ||||||
|             {% include 'partials/pagination.html' %} |  | ||||||
|         </div> |  | ||||||
|         {% else %} |  | ||||||
|         <div class="pf-c-toolbar"> |  | ||||||
|             <div class="pf-c-toolbar__content"> |  | ||||||
|                 {% include 'partials/toolbar_search.html' %} |  | ||||||
|             </div> |  | ||||||
|         </div> |  | ||||||
|         <div class="pf-c-empty-state"> |  | ||||||
|             <div class="pf-c-empty-state__content"> |  | ||||||
|                 <i class="pf-icon pf-icon-migration pf-c-empty-state__icon" aria-hidden="true"></i> |  | ||||||
|                 <h1 class="pf-c-title pf-m-lg"> |  | ||||||
|                     {% trans 'No Invitations.' %} |  | ||||||
|                 </h1> |  | ||||||
|                 <div class="pf-c-empty-state__body"> |  | ||||||
|                 {% if request.GET.search != "" %} |  | ||||||
|                     {% trans "Your search query doesn't match any invitations." %} |  | ||||||
|                 {% else %} |  | ||||||
|                     {% trans 'Currently no invitations exist. Click the button below to create one.' %} |  | ||||||
|                 {% endif %} |  | ||||||
|                 </div> |  | ||||||
|                 <ak-modal-button href="{% url 'authentik_admin:stage-invitation-create' %}"> |  | ||||||
|                     <ak-spinner-button slot="trigger" class="pf-m-primary"> |  | ||||||
|                         {% trans 'Create' %} |  | ||||||
|                     </ak-spinner-button> |  | ||||||
|                     <div slot="modal"></div> |  | ||||||
|                 </ak-modal-button> |  | ||||||
|             </div> |  | ||||||
|         </div> |  | ||||||
|         {% endif %} |  | ||||||
|     </div> |  | ||||||
| </section> |  | ||||||
| {% endblock %} |  | ||||||
| @ -1,125 +0,0 @@ | |||||||
| {% extends "administration/base.html" %} |  | ||||||
|  |  | ||||||
| {% load i18n %} |  | ||||||
| {% load authentik_utils %} |  | ||||||
|  |  | ||||||
| {% block content %} |  | ||||||
| <section class="pf-c-page__main-section pf-m-light"> |  | ||||||
|     <div class="pf-c-content"> |  | ||||||
|         <h1> |  | ||||||
|             <i class="pf-icon pf-icon-plugged"></i> |  | ||||||
|             {% trans 'Prompts' %} |  | ||||||
|         </h1> |  | ||||||
|         <p>{% trans "Single Prompts that can be used for Prompt Stages." %}</p> |  | ||||||
|     </div> |  | ||||||
| </section> |  | ||||||
| <section class="pf-c-page__main-section pf-m-no-padding-mobile"> |  | ||||||
|     <div class="pf-c-card"> |  | ||||||
|         {% if object_list %} |  | ||||||
|         <div class="pf-c-toolbar"> |  | ||||||
|             <div class="pf-c-toolbar__content"> |  | ||||||
|                 {% include 'partials/toolbar_search.html' %} |  | ||||||
|                 <div class="pf-c-toolbar__bulk-select"> |  | ||||||
|                     <ak-modal-button href="{% url 'authentik_admin:stage-prompt-create' %}"> |  | ||||||
|                         <ak-spinner-button slot="trigger" class="pf-m-primary"> |  | ||||||
|                             {% trans 'Create' %} |  | ||||||
|                         </ak-spinner-button> |  | ||||||
|                         <div slot="modal"></div> |  | ||||||
|                     </ak-modal-button> |  | ||||||
|                     <button role="ak-refresh" class="pf-c-button pf-m-primary"> |  | ||||||
|                         {% trans 'Refresh' %} |  | ||||||
|                     </button> |  | ||||||
|                 </div> |  | ||||||
|                 {% include 'partials/pagination.html' %} |  | ||||||
|             </div> |  | ||||||
|         </div> |  | ||||||
|         <table class="pf-c-table pf-m-compact pf-m-grid-xl" role="grid"> |  | ||||||
|             <thead> |  | ||||||
|                 <tr role="row"> |  | ||||||
|                     <th role="columnheader" scope="col">{% trans 'Field' %}</th> |  | ||||||
|                     <th role="columnheader" scope="col">{% trans 'Label' %}</th> |  | ||||||
|                     <th role="columnheader" scope="col">{% trans 'Type' %}</th> |  | ||||||
|                     <th role="columnheader" scope="col">{% trans 'Order' %}</th> |  | ||||||
|                     <th role="columnheader" scope="col">{% trans 'Flows' %}</th> |  | ||||||
|                     <th role="cell"></th> |  | ||||||
|                 </tr> |  | ||||||
|             </thead> |  | ||||||
|             <tbody role="rowgroup"> |  | ||||||
|                 {% for prompt in object_list %} |  | ||||||
|                 <tr role="row"> |  | ||||||
|                     <th role="columnheader"> |  | ||||||
|                         <div> |  | ||||||
|                             <div>{{ prompt.field_key }}</div> |  | ||||||
|                         </div> |  | ||||||
|                     </th> |  | ||||||
|                     <td role="cell"> |  | ||||||
|                         <div> |  | ||||||
|                             {{ prompt.label }} |  | ||||||
|                         </div> |  | ||||||
|                     </td> |  | ||||||
|                     <td role="cell"> |  | ||||||
|                         <div> |  | ||||||
|                             {{ prompt.type }} |  | ||||||
|                         </div> |  | ||||||
|                     </td> |  | ||||||
|                     <td role="cell"> |  | ||||||
|                         <div> |  | ||||||
|                             {{ prompt.order }} |  | ||||||
|                         </div> |  | ||||||
|                     </td> |  | ||||||
|                     <td role="cell"> |  | ||||||
|                         <ul> |  | ||||||
|                             {% for flow in prompt.flow_set.all %} |  | ||||||
|                             <li>{{ flow.slug }}</li> |  | ||||||
|                             {% empty %} |  | ||||||
|                             <li>-</li> |  | ||||||
|                             {% endfor %} |  | ||||||
|                         </ul> |  | ||||||
|                     </td> |  | ||||||
|                     <td> |  | ||||||
|                         <ak-modal-button href="{% url 'authentik_admin:stage-prompt-update' pk=prompt.pk %}"> |  | ||||||
|                             <ak-spinner-button slot="trigger" class="pf-m-secondary"> |  | ||||||
|                                 {% trans 'Update' %} |  | ||||||
|                             </ak-spinner-button> |  | ||||||
|                             <div slot="modal"></div> |  | ||||||
|                         </ak-modal-button> |  | ||||||
|                         <ak-modal-button href="{% url 'authentik_admin:stage-prompt-delete' pk=prompt.pk %}"> |  | ||||||
|                             <ak-spinner-button slot="trigger" class="pf-m-danger"> |  | ||||||
|                                 {% trans 'Delete' %} |  | ||||||
|                             </ak-spinner-button> |  | ||||||
|                             <div slot="modal"></div> |  | ||||||
|                         </ak-modal-button> |  | ||||||
|                     </td> |  | ||||||
|                 </tr> |  | ||||||
|                 {% endfor %} |  | ||||||
|             </tbody> |  | ||||||
|         </table> |  | ||||||
|         <div class="pf-c-pagination pf-m-bottom"> |  | ||||||
|             {% include 'partials/pagination.html' %} |  | ||||||
|         </div> |  | ||||||
|         {% else %} |  | ||||||
|         <div class="pf-c-toolbar"> |  | ||||||
|             <div class="pf-c-toolbar__content"> |  | ||||||
|                 {% include 'partials/toolbar_search.html' %} |  | ||||||
|             </div> |  | ||||||
|         </div> |  | ||||||
|         <div class="pf-c-empty-state"> |  | ||||||
|             <div class="pf-c-empty-state__content"> |  | ||||||
|                 <i class="pf-icon pf-icon-plugged pf-c-empty-state__icon" aria-hidden="true"></i> |  | ||||||
|                 <h1 class="pf-c-title pf-m-lg"> |  | ||||||
|                     {% trans 'No Stage Prompts.' %} |  | ||||||
|                 </h1> |  | ||||||
|                 <div class="pf-c-empty-state__body"> |  | ||||||
|                 {% if request.GET.search != "" %} |  | ||||||
|                     {% trans "Your search query doesn't match any stage prompts." %} |  | ||||||
|                 {% else %} |  | ||||||
|                     {% trans 'Currently no stage prompts exist. Click the button below to create one.' %} |  | ||||||
|                 {% endif %} |  | ||||||
|                 </div> |  | ||||||
|                 <a href="{% url 'authentik_admin:stage-prompt-create' %}?back={{ request.get_full_path }}" class="pf-c-button pf-m-primary" type="button">{% trans 'Create' %}</a> |  | ||||||
|             </div> |  | ||||||
|         </div> |  | ||||||
|         {% endif %} |  | ||||||
|     </div> |  | ||||||
| </section> |  | ||||||
| {% endblock %} |  | ||||||
| @ -153,11 +153,6 @@ urlpatterns = [ | |||||||
|         name="stage-binding-delete", |         name="stage-binding-delete", | ||||||
|     ), |     ), | ||||||
|     # Stage Prompts |     # Stage Prompts | ||||||
|     path( |  | ||||||
|         "stages_prompts/", |  | ||||||
|         stages_prompts.PromptListView.as_view(), |  | ||||||
|         name="stage-prompts", |  | ||||||
|     ), |  | ||||||
|     path( |     path( | ||||||
|         "stages_prompts/create/", |         "stages_prompts/create/", | ||||||
|         stages_prompts.PromptCreateView.as_view(), |         stages_prompts.PromptCreateView.as_view(), | ||||||
| @ -174,11 +169,6 @@ urlpatterns = [ | |||||||
|         name="stage-prompt-delete", |         name="stage-prompt-delete", | ||||||
|     ), |     ), | ||||||
|     # Stage Invitations |     # Stage Invitations | ||||||
|     path( |  | ||||||
|         "stages/invitations/", |  | ||||||
|         stages_invitations.InvitationListView.as_view(), |  | ||||||
|         name="stage-invitations", |  | ||||||
|     ), |  | ||||||
|     path( |     path( | ||||||
|         "stages/invitations/create/", |         "stages/invitations/create/", | ||||||
|         stages_invitations.InvitationCreateView.as_view(), |         stages_invitations.InvitationCreateView.as_view(), | ||||||
|  | |||||||
| @ -5,37 +5,15 @@ from django.contrib.auth.mixins import ( | |||||||
| ) | ) | ||||||
| from django.contrib.messages.views import SuccessMessageMixin | from django.contrib.messages.views import SuccessMessageMixin | ||||||
| from django.http import HttpResponseRedirect | from django.http import HttpResponseRedirect | ||||||
| from django.urls import reverse_lazy |  | ||||||
| from django.utils.translation import gettext as _ | from django.utils.translation import gettext as _ | ||||||
| from django.views.generic import ListView | from guardian.mixins import PermissionRequiredMixin | ||||||
| from guardian.mixins import PermissionListMixin, PermissionRequiredMixin |  | ||||||
|  |  | ||||||
| from authentik.admin.views.utils import ( | from authentik.admin.views.utils import DeleteMessageView | ||||||
|     DeleteMessageView, |  | ||||||
|     SearchListMixin, |  | ||||||
|     UserPaginateListMixin, |  | ||||||
| ) |  | ||||||
| from authentik.lib.views import CreateAssignPermView | from authentik.lib.views import CreateAssignPermView | ||||||
| from authentik.stages.invitation.forms import InvitationForm | from authentik.stages.invitation.forms import InvitationForm | ||||||
| from authentik.stages.invitation.models import Invitation | from authentik.stages.invitation.models import Invitation | ||||||
|  |  | ||||||
|  |  | ||||||
| class InvitationListView( |  | ||||||
|     LoginRequiredMixin, |  | ||||||
|     PermissionListMixin, |  | ||||||
|     UserPaginateListMixin, |  | ||||||
|     SearchListMixin, |  | ||||||
|     ListView, |  | ||||||
| ): |  | ||||||
|     """Show list of all invitations""" |  | ||||||
|  |  | ||||||
|     model = Invitation |  | ||||||
|     permission_required = "authentik_stages_invitation.view_invitation" |  | ||||||
|     template_name = "administration/stage_invitation/list.html" |  | ||||||
|     ordering = "-expires" |  | ||||||
|     search_fields = ["created_by__username", "expires", "fixed_data"] |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class InvitationCreateView( | class InvitationCreateView( | ||||||
|     SuccessMessageMixin, |     SuccessMessageMixin, | ||||||
|     LoginRequiredMixin, |     LoginRequiredMixin, | ||||||
| @ -49,7 +27,7 @@ class InvitationCreateView( | |||||||
|     permission_required = "authentik_stages_invitation.add_invitation" |     permission_required = "authentik_stages_invitation.add_invitation" | ||||||
|  |  | ||||||
|     template_name = "generic/create.html" |     template_name = "generic/create.html" | ||||||
|     success_url = reverse_lazy("authentik_admin:stage-invitations") |     success_url = "/" | ||||||
|     success_message = _("Successfully created Invitation") |     success_message = _("Successfully created Invitation") | ||||||
|  |  | ||||||
|     def form_valid(self, form): |     def form_valid(self, form): | ||||||
| @ -68,5 +46,5 @@ class InvitationDeleteView( | |||||||
|     permission_required = "authentik_stages_invitation.delete_invitation" |     permission_required = "authentik_stages_invitation.delete_invitation" | ||||||
|  |  | ||||||
|     template_name = "generic/delete.html" |     template_name = "generic/delete.html" | ||||||
|     success_url = reverse_lazy("authentik_admin:stage-invitations") |     success_url = "/" | ||||||
|     success_message = _("Successfully deleted Invitation") |     success_message = _("Successfully deleted Invitation") | ||||||
|  | |||||||
| @ -4,42 +4,16 @@ from django.contrib.auth.mixins import ( | |||||||
|     PermissionRequiredMixin as DjangoPermissionRequiredMixin, |     PermissionRequiredMixin as DjangoPermissionRequiredMixin, | ||||||
| ) | ) | ||||||
| from django.contrib.messages.views import SuccessMessageMixin | from django.contrib.messages.views import SuccessMessageMixin | ||||||
| from django.urls import reverse_lazy |  | ||||||
| from django.utils.translation import gettext as _ | from django.utils.translation import gettext as _ | ||||||
| from django.views.generic import ListView, UpdateView | from django.views.generic import UpdateView | ||||||
| from guardian.mixins import PermissionListMixin, PermissionRequiredMixin | from guardian.mixins import PermissionRequiredMixin | ||||||
|  |  | ||||||
| from authentik.admin.views.utils import ( | from authentik.admin.views.utils import DeleteMessageView | ||||||
|     DeleteMessageView, |  | ||||||
|     SearchListMixin, |  | ||||||
|     UserPaginateListMixin, |  | ||||||
| ) |  | ||||||
| from authentik.lib.views import CreateAssignPermView | from authentik.lib.views import CreateAssignPermView | ||||||
| from authentik.stages.prompt.forms import PromptAdminForm | from authentik.stages.prompt.forms import PromptAdminForm | ||||||
| from authentik.stages.prompt.models import Prompt | from authentik.stages.prompt.models import Prompt | ||||||
|  |  | ||||||
|  |  | ||||||
| class PromptListView( |  | ||||||
|     LoginRequiredMixin, |  | ||||||
|     PermissionListMixin, |  | ||||||
|     UserPaginateListMixin, |  | ||||||
|     SearchListMixin, |  | ||||||
|     ListView, |  | ||||||
| ): |  | ||||||
|     """Show list of all prompts""" |  | ||||||
|  |  | ||||||
|     model = Prompt |  | ||||||
|     permission_required = "authentik_stages_prompt.view_prompt" |  | ||||||
|     ordering = "order" |  | ||||||
|     template_name = "administration/stage_prompt/list.html" |  | ||||||
|     search_fields = [ |  | ||||||
|         "field_key", |  | ||||||
|         "label", |  | ||||||
|         "type", |  | ||||||
|         "placeholder", |  | ||||||
|     ] |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class PromptCreateView( | class PromptCreateView( | ||||||
|     SuccessMessageMixin, |     SuccessMessageMixin, | ||||||
|     LoginRequiredMixin, |     LoginRequiredMixin, | ||||||
| @ -53,7 +27,7 @@ class PromptCreateView( | |||||||
|     permission_required = "authentik_stages_prompt.add_prompt" |     permission_required = "authentik_stages_prompt.add_prompt" | ||||||
|  |  | ||||||
|     template_name = "generic/create.html" |     template_name = "generic/create.html" | ||||||
|     success_url = reverse_lazy("authentik_admin:stage-prompts") |     success_url = "/" | ||||||
|     success_message = _("Successfully created Prompt") |     success_message = _("Successfully created Prompt") | ||||||
|  |  | ||||||
|  |  | ||||||
| @ -70,7 +44,7 @@ class PromptUpdateView( | |||||||
|     permission_required = "authentik_stages_prompt.change_prompt" |     permission_required = "authentik_stages_prompt.change_prompt" | ||||||
|  |  | ||||||
|     template_name = "generic/update.html" |     template_name = "generic/update.html" | ||||||
|     success_url = reverse_lazy("authentik_admin:stage-prompts") |     success_url = "/" | ||||||
|     success_message = _("Successfully updated Prompt") |     success_message = _("Successfully updated Prompt") | ||||||
|  |  | ||||||
|  |  | ||||||
| @ -81,5 +55,5 @@ class PromptDeleteView(LoginRequiredMixin, PermissionRequiredMixin, DeleteMessag | |||||||
|     permission_required = "authentik_stages_prompt.delete_prompt" |     permission_required = "authentik_stages_prompt.delete_prompt" | ||||||
|  |  | ||||||
|     template_name = "generic/delete.html" |     template_name = "generic/delete.html" | ||||||
|     success_url = reverse_lazy("authentik_admin:stage-prompts") |     success_url = "/" | ||||||
|     success_message = _("Successfully deleted Prompt") |     success_message = _("Successfully deleted Prompt") | ||||||
|  | |||||||
| @ -136,8 +136,8 @@ router.register("stages/captcha", CaptchaStageViewSet) | |||||||
| router.register("stages/consent", ConsentStageViewSet) | router.register("stages/consent", ConsentStageViewSet) | ||||||
| router.register("stages/email", EmailStageViewSet) | router.register("stages/email", EmailStageViewSet) | ||||||
| router.register("stages/identification", IdentificationStageViewSet) | router.register("stages/identification", IdentificationStageViewSet) | ||||||
| router.register("stages/invitation", InvitationStageViewSet) |  | ||||||
| router.register("stages/invitation/invitations", InvitationViewSet) | router.register("stages/invitation/invitations", InvitationViewSet) | ||||||
|  | router.register("stages/invitation/stages", InvitationStageViewSet) | ||||||
| router.register("stages/password", PasswordStageViewSet) | router.register("stages/password", PasswordStageViewSet) | ||||||
| router.register("stages/prompt/prompts", PromptViewSet) | router.register("stages/prompt/prompts", PromptViewSet) | ||||||
| router.register("stages/prompt/stages", PromptStageViewSet) | router.register("stages/prompt/stages", PromptStageViewSet) | ||||||
|  | |||||||
| @ -23,6 +23,7 @@ def get_attrs(obj: SerializerModel) -> dict[str, Any]: | |||||||
|         "verbose_name_plural", |         "verbose_name_plural", | ||||||
|         "object_type", |         "object_type", | ||||||
|         "flow_set", |         "flow_set", | ||||||
|  |         "promptstage_set", | ||||||
|     ) |     ) | ||||||
|     for to_remove_name in to_remove: |     for to_remove_name in to_remove: | ||||||
|         if to_remove_name in data: |         if to_remove_name in data: | ||||||
|  | |||||||
| @ -34,7 +34,9 @@ class InvitationSerializer(ModelSerializer): | |||||||
|             "pk", |             "pk", | ||||||
|             "expires", |             "expires", | ||||||
|             "fixed_data", |             "fixed_data", | ||||||
|  |             "created_by", | ||||||
|         ] |         ] | ||||||
|  |         depth = 2 | ||||||
|  |  | ||||||
|  |  | ||||||
| class InvitationViewSet(ModelViewSet): | class InvitationViewSet(ModelViewSet): | ||||||
| @ -42,6 +44,9 @@ class InvitationViewSet(ModelViewSet): | |||||||
|  |  | ||||||
|     queryset = Invitation.objects.all() |     queryset = Invitation.objects.all() | ||||||
|     serializer_class = InvitationSerializer |     serializer_class = InvitationSerializer | ||||||
|  |     order = ["-expires"] | ||||||
|  |     search_fields = ["created_by__username", "expires"] | ||||||
|  |     filterset_fields = ["created_by__username", "expires"] | ||||||
|  |  | ||||||
|     def perform_create(self, serializer: InvitationSerializer): |     def perform_create(self, serializer: InvitationSerializer): | ||||||
|         serializer.instance.created_by = self.request.user |         serializer.instance.created_by = self.request.user | ||||||
|  | |||||||
| @ -31,6 +31,8 @@ class PromptStageViewSet(ModelViewSet): | |||||||
| class PromptSerializer(ModelSerializer): | class PromptSerializer(ModelSerializer): | ||||||
|     """Prompt Serializer""" |     """Prompt Serializer""" | ||||||
|  |  | ||||||
|  |     promptstage_set = StageSerializer(many=True, required=False) | ||||||
|  |  | ||||||
|     class Meta: |     class Meta: | ||||||
|  |  | ||||||
|         model = Prompt |         model = Prompt | ||||||
| @ -42,11 +44,13 @@ class PromptSerializer(ModelSerializer): | |||||||
|             "required", |             "required", | ||||||
|             "placeholder", |             "placeholder", | ||||||
|             "order", |             "order", | ||||||
|  |             "promptstage_set", | ||||||
|         ] |         ] | ||||||
|  |  | ||||||
|  |  | ||||||
| class PromptViewSet(ModelViewSet): | class PromptViewSet(ModelViewSet): | ||||||
|     """Prompt Viewset""" |     """Prompt Viewset""" | ||||||
|  |  | ||||||
|     queryset = Prompt.objects.all() |     queryset = Prompt.objects.all().prefetch_related("promptstage_set") | ||||||
|     serializer_class = PromptSerializer |     serializer_class = PromptSerializer | ||||||
|  |     filterset_fields = ["field_key", "label", "type", "placeholder"] | ||||||
|  | |||||||
							
								
								
									
										454
									
								
								swagger.yaml
									
									
									
									
									
								
							
							
						
						
									
										454
									
								
								swagger.yaml
									
									
									
									
									
								
							| @ -6830,78 +6830,21 @@ paths: | |||||||
|         required: true |         required: true | ||||||
|         type: string |         type: string | ||||||
|         format: uuid |         format: uuid | ||||||
|   /stages/invitation/: |  | ||||||
|     get: |  | ||||||
|       operationId: stages_invitation_list |  | ||||||
|       description: InvitationStage Viewset |  | ||||||
|       parameters: |  | ||||||
|         - name: ordering |  | ||||||
|           in: query |  | ||||||
|           description: Which field to use when ordering the results. |  | ||||||
|           required: false |  | ||||||
|           type: string |  | ||||||
|         - name: search |  | ||||||
|           in: query |  | ||||||
|           description: A search term. |  | ||||||
|           required: false |  | ||||||
|           type: string |  | ||||||
|         - name: page |  | ||||||
|           in: query |  | ||||||
|           description: A page number within the paginated result set. |  | ||||||
|           required: false |  | ||||||
|           type: integer |  | ||||||
|         - name: page_size |  | ||||||
|           in: query |  | ||||||
|           description: Number of results to return per page. |  | ||||||
|           required: false |  | ||||||
|           type: integer |  | ||||||
|       responses: |  | ||||||
|         '200': |  | ||||||
|           description: '' |  | ||||||
|           schema: |  | ||||||
|             required: |  | ||||||
|               - count |  | ||||||
|               - results |  | ||||||
|             type: object |  | ||||||
|             properties: |  | ||||||
|               count: |  | ||||||
|                 type: integer |  | ||||||
|               next: |  | ||||||
|                 type: string |  | ||||||
|                 format: uri |  | ||||||
|                 x-nullable: true |  | ||||||
|               previous: |  | ||||||
|                 type: string |  | ||||||
|                 format: uri |  | ||||||
|                 x-nullable: true |  | ||||||
|               results: |  | ||||||
|                 type: array |  | ||||||
|                 items: |  | ||||||
|                   $ref: '#/definitions/InvitationStage' |  | ||||||
|       tags: |  | ||||||
|         - stages |  | ||||||
|     post: |  | ||||||
|       operationId: stages_invitation_create |  | ||||||
|       description: InvitationStage Viewset |  | ||||||
|       parameters: |  | ||||||
|         - name: data |  | ||||||
|           in: body |  | ||||||
|           required: true |  | ||||||
|           schema: |  | ||||||
|             $ref: '#/definitions/InvitationStage' |  | ||||||
|       responses: |  | ||||||
|         '201': |  | ||||||
|           description: '' |  | ||||||
|           schema: |  | ||||||
|             $ref: '#/definitions/InvitationStage' |  | ||||||
|       tags: |  | ||||||
|         - stages |  | ||||||
|     parameters: [] |  | ||||||
|   /stages/invitation/invitations/: |   /stages/invitation/invitations/: | ||||||
|     get: |     get: | ||||||
|       operationId: stages_invitation_invitations_list |       operationId: stages_invitation_invitations_list | ||||||
|       description: Invitation Viewset |       description: Invitation Viewset | ||||||
|       parameters: |       parameters: | ||||||
|  |         - name: created_by__username | ||||||
|  |           in: query | ||||||
|  |           description: '' | ||||||
|  |           required: false | ||||||
|  |           type: string | ||||||
|  |         - name: expires | ||||||
|  |           in: query | ||||||
|  |           description: '' | ||||||
|  |           required: false | ||||||
|  |           type: string | ||||||
|         - name: ordering |         - name: ordering | ||||||
|           in: query |           in: query | ||||||
|           description: Which field to use when ordering the results. |           description: Which field to use when ordering the results. | ||||||
| @ -7024,9 +6967,76 @@ paths: | |||||||
|         required: true |         required: true | ||||||
|         type: string |         type: string | ||||||
|         format: uuid |         format: uuid | ||||||
|   /stages/invitation/{stage_uuid}/: |   /stages/invitation/stages/: | ||||||
|     get: |     get: | ||||||
|       operationId: stages_invitation_read |       operationId: stages_invitation_stages_list | ||||||
|  |       description: InvitationStage Viewset | ||||||
|  |       parameters: | ||||||
|  |         - name: ordering | ||||||
|  |           in: query | ||||||
|  |           description: Which field to use when ordering the results. | ||||||
|  |           required: false | ||||||
|  |           type: string | ||||||
|  |         - name: search | ||||||
|  |           in: query | ||||||
|  |           description: A search term. | ||||||
|  |           required: false | ||||||
|  |           type: string | ||||||
|  |         - name: page | ||||||
|  |           in: query | ||||||
|  |           description: A page number within the paginated result set. | ||||||
|  |           required: false | ||||||
|  |           type: integer | ||||||
|  |         - name: page_size | ||||||
|  |           in: query | ||||||
|  |           description: Number of results to return per page. | ||||||
|  |           required: false | ||||||
|  |           type: integer | ||||||
|  |       responses: | ||||||
|  |         '200': | ||||||
|  |           description: '' | ||||||
|  |           schema: | ||||||
|  |             required: | ||||||
|  |               - count | ||||||
|  |               - results | ||||||
|  |             type: object | ||||||
|  |             properties: | ||||||
|  |               count: | ||||||
|  |                 type: integer | ||||||
|  |               next: | ||||||
|  |                 type: string | ||||||
|  |                 format: uri | ||||||
|  |                 x-nullable: true | ||||||
|  |               previous: | ||||||
|  |                 type: string | ||||||
|  |                 format: uri | ||||||
|  |                 x-nullable: true | ||||||
|  |               results: | ||||||
|  |                 type: array | ||||||
|  |                 items: | ||||||
|  |                   $ref: '#/definitions/InvitationStage' | ||||||
|  |       tags: | ||||||
|  |         - stages | ||||||
|  |     post: | ||||||
|  |       operationId: stages_invitation_stages_create | ||||||
|  |       description: InvitationStage Viewset | ||||||
|  |       parameters: | ||||||
|  |         - name: data | ||||||
|  |           in: body | ||||||
|  |           required: true | ||||||
|  |           schema: | ||||||
|  |             $ref: '#/definitions/InvitationStage' | ||||||
|  |       responses: | ||||||
|  |         '201': | ||||||
|  |           description: '' | ||||||
|  |           schema: | ||||||
|  |             $ref: '#/definitions/InvitationStage' | ||||||
|  |       tags: | ||||||
|  |         - stages | ||||||
|  |     parameters: [] | ||||||
|  |   /stages/invitation/stages/{stage_uuid}/: | ||||||
|  |     get: | ||||||
|  |       operationId: stages_invitation_stages_read | ||||||
|       description: InvitationStage Viewset |       description: InvitationStage Viewset | ||||||
|       parameters: [] |       parameters: [] | ||||||
|       responses: |       responses: | ||||||
| @ -7037,7 +7047,7 @@ paths: | |||||||
|       tags: |       tags: | ||||||
|         - stages |         - stages | ||||||
|     put: |     put: | ||||||
|       operationId: stages_invitation_update |       operationId: stages_invitation_stages_update | ||||||
|       description: InvitationStage Viewset |       description: InvitationStage Viewset | ||||||
|       parameters: |       parameters: | ||||||
|         - name: data |         - name: data | ||||||
| @ -7053,7 +7063,7 @@ paths: | |||||||
|       tags: |       tags: | ||||||
|         - stages |         - stages | ||||||
|     patch: |     patch: | ||||||
|       operationId: stages_invitation_partial_update |       operationId: stages_invitation_stages_partial_update | ||||||
|       description: InvitationStage Viewset |       description: InvitationStage Viewset | ||||||
|       parameters: |       parameters: | ||||||
|         - name: data |         - name: data | ||||||
| @ -7069,7 +7079,7 @@ paths: | |||||||
|       tags: |       tags: | ||||||
|         - stages |         - stages | ||||||
|     delete: |     delete: | ||||||
|       operationId: stages_invitation_delete |       operationId: stages_invitation_stages_delete | ||||||
|       description: InvitationStage Viewset |       description: InvitationStage Viewset | ||||||
|       parameters: [] |       parameters: [] | ||||||
|       responses: |       responses: | ||||||
| @ -7216,6 +7226,26 @@ paths: | |||||||
|       operationId: stages_prompt_prompts_list |       operationId: stages_prompt_prompts_list | ||||||
|       description: Prompt Viewset |       description: Prompt Viewset | ||||||
|       parameters: |       parameters: | ||||||
|  |         - name: field_key | ||||||
|  |           in: query | ||||||
|  |           description: '' | ||||||
|  |           required: false | ||||||
|  |           type: string | ||||||
|  |         - name: label | ||||||
|  |           in: query | ||||||
|  |           description: '' | ||||||
|  |           required: false | ||||||
|  |           type: string | ||||||
|  |         - name: type | ||||||
|  |           in: query | ||||||
|  |           description: '' | ||||||
|  |           required: false | ||||||
|  |           type: string | ||||||
|  |         - name: placeholder | ||||||
|  |           in: query | ||||||
|  |           description: '' | ||||||
|  |           required: false | ||||||
|  |           type: string | ||||||
|         - name: ordering |         - name: ordering | ||||||
|           in: query |           in: query | ||||||
|           description: Which field to use when ordering the results. |           description: Which field to use when ordering the results. | ||||||
| @ -11335,6 +11365,263 @@ definitions: | |||||||
|         type: string |         type: string | ||||||
|         format: uuid |         format: uuid | ||||||
|         x-nullable: true |         x-nullable: true | ||||||
|  |   Invitation: | ||||||
|  |     description: Invitation Serializer | ||||||
|  |     type: object | ||||||
|  |     properties: | ||||||
|  |       pk: | ||||||
|  |         title: Invite uuid | ||||||
|  |         type: string | ||||||
|  |         format: uuid | ||||||
|  |         readOnly: true | ||||||
|  |       expires: | ||||||
|  |         title: Expires | ||||||
|  |         type: string | ||||||
|  |         format: date-time | ||||||
|  |         x-nullable: true | ||||||
|  |       fixed_data: | ||||||
|  |         title: Fixed data | ||||||
|  |         description: Optional fixed data to enforce on user enrollment. | ||||||
|  |         type: object | ||||||
|  |       created_by: | ||||||
|  |         description: Custom User model to allow easier adding o f user-based settings | ||||||
|  |         required: | ||||||
|  |           - password | ||||||
|  |           - username | ||||||
|  |           - name | ||||||
|  |         type: object | ||||||
|  |         properties: | ||||||
|  |           id: | ||||||
|  |             title: ID | ||||||
|  |             type: integer | ||||||
|  |             readOnly: true | ||||||
|  |           password: | ||||||
|  |             title: Password | ||||||
|  |             type: string | ||||||
|  |             maxLength: 128 | ||||||
|  |             minLength: 1 | ||||||
|  |           last_login: | ||||||
|  |             title: Last login | ||||||
|  |             type: string | ||||||
|  |             format: date-time | ||||||
|  |             x-nullable: true | ||||||
|  |           username: | ||||||
|  |             title: Username | ||||||
|  |             description: Required. 150 characters or fewer. Letters, digits and @/./+/-/_ | ||||||
|  |               only. | ||||||
|  |             type: string | ||||||
|  |             pattern: ^[\w.@+-]+$ | ||||||
|  |             maxLength: 150 | ||||||
|  |             minLength: 1 | ||||||
|  |           first_name: | ||||||
|  |             title: First name | ||||||
|  |             type: string | ||||||
|  |             maxLength: 150 | ||||||
|  |           last_name: | ||||||
|  |             title: Last name | ||||||
|  |             type: string | ||||||
|  |             maxLength: 150 | ||||||
|  |           email: | ||||||
|  |             title: Email address | ||||||
|  |             type: string | ||||||
|  |             format: email | ||||||
|  |             maxLength: 254 | ||||||
|  |           is_active: | ||||||
|  |             title: Active | ||||||
|  |             description: Designates whether this user should be treated as active. | ||||||
|  |               Unselect this instead of deleting accounts. | ||||||
|  |             type: boolean | ||||||
|  |           date_joined: | ||||||
|  |             title: Date joined | ||||||
|  |             type: string | ||||||
|  |             format: date-time | ||||||
|  |           uuid: | ||||||
|  |             title: Uuid | ||||||
|  |             type: string | ||||||
|  |             format: uuid | ||||||
|  |             readOnly: true | ||||||
|  |           name: | ||||||
|  |             title: Name | ||||||
|  |             description: User's display name. | ||||||
|  |             type: string | ||||||
|  |             minLength: 1 | ||||||
|  |           password_change_date: | ||||||
|  |             title: Password change date | ||||||
|  |             type: string | ||||||
|  |             format: date-time | ||||||
|  |             readOnly: true | ||||||
|  |           attributes: | ||||||
|  |             title: Attributes | ||||||
|  |             type: object | ||||||
|  |           groups: | ||||||
|  |             description: '' | ||||||
|  |             type: array | ||||||
|  |             items: | ||||||
|  |               description: Groups are a generic way of categorizing users to apply | ||||||
|  |                 permissions, or some other label, to those users. A user can belong | ||||||
|  |                 to any number of groups. A user in a group automatically has all the | ||||||
|  |                 permissions granted to that group. For example, if the group 'Site | ||||||
|  |                 editors' has the permission can_edit_home_page, any user in that group | ||||||
|  |                 will have that permission. Beyond permissions, groups are a convenient | ||||||
|  |                 way to categorize users to apply some label, or extended functionality, | ||||||
|  |                 to them. For example, you could create a group 'Special users', and | ||||||
|  |                 you could write code that would do special things to those users -- | ||||||
|  |                 such as giving them access to a members-only portion of your site, | ||||||
|  |                 or sending them members-only email messages. | ||||||
|  |               required: | ||||||
|  |                 - name | ||||||
|  |               type: object | ||||||
|  |               properties: | ||||||
|  |                 id: | ||||||
|  |                   title: ID | ||||||
|  |                   type: integer | ||||||
|  |                   readOnly: true | ||||||
|  |                 name: | ||||||
|  |                   title: Name | ||||||
|  |                   type: string | ||||||
|  |                   maxLength: 150 | ||||||
|  |                   minLength: 1 | ||||||
|  |                 permissions: | ||||||
|  |                   type: array | ||||||
|  |                   items: | ||||||
|  |                     type: integer | ||||||
|  |                   uniqueItems: true | ||||||
|  |             readOnly: true | ||||||
|  |           user_permissions: | ||||||
|  |             description: '' | ||||||
|  |             type: array | ||||||
|  |             items: | ||||||
|  |               description: "The permissions system provides a way to assign permissions\ | ||||||
|  |                 \ to specific users and groups of users. The permission system is\ | ||||||
|  |                 \ used by the Django admin site, but may also be useful in your own\ | ||||||
|  |                 \ code. The Django admin site uses permissions as follows: - The \"\ | ||||||
|  |                 add\" permission limits the user's ability to view the \"add\" form\ | ||||||
|  |                 \ and add an object. - The \"change\" permission limits a user's ability\ | ||||||
|  |                 \ to view the change list, view the \"change\" form and change an\ | ||||||
|  |                 \ object. - The \"delete\" permission limits the ability to delete\ | ||||||
|  |                 \ an object. - The \"view\" permission limits the ability to view\ | ||||||
|  |                 \ an object. Permissions are set globally per type of object, not\ | ||||||
|  |                 \ per specific object instance. It is possible to say \"Mary may change\ | ||||||
|  |                 \ news stories,\" but it's not currently possible to say \"Mary may\ | ||||||
|  |                 \ change news stories, but only the ones she created herself\" or\ | ||||||
|  |                 \ \"Mary may only change news stories that have a certain status or\ | ||||||
|  |                 \ publication date.\" The permissions listed above are automatically\ | ||||||
|  |                 \ created for each model." | ||||||
|  |               required: | ||||||
|  |                 - name | ||||||
|  |                 - codename | ||||||
|  |                 - content_type | ||||||
|  |               type: object | ||||||
|  |               properties: | ||||||
|  |                 id: | ||||||
|  |                   title: ID | ||||||
|  |                   type: integer | ||||||
|  |                   readOnly: true | ||||||
|  |                 name: | ||||||
|  |                   title: Name | ||||||
|  |                   type: string | ||||||
|  |                   maxLength: 255 | ||||||
|  |                   minLength: 1 | ||||||
|  |                 codename: | ||||||
|  |                   title: Codename | ||||||
|  |                   type: string | ||||||
|  |                   maxLength: 100 | ||||||
|  |                   minLength: 1 | ||||||
|  |                 content_type: | ||||||
|  |                   title: Content type | ||||||
|  |                   type: integer | ||||||
|  |             readOnly: true | ||||||
|  |           sources: | ||||||
|  |             description: '' | ||||||
|  |             type: array | ||||||
|  |             items: | ||||||
|  |               description: Base Authentication source, i.e. an OAuth Provider, SAML | ||||||
|  |                 Remote or LDAP Server | ||||||
|  |               required: | ||||||
|  |                 - name | ||||||
|  |                 - slug | ||||||
|  |               type: object | ||||||
|  |               properties: | ||||||
|  |                 pbm_uuid: | ||||||
|  |                   title: Pbm uuid | ||||||
|  |                   type: string | ||||||
|  |                   format: uuid | ||||||
|  |                   readOnly: true | ||||||
|  |                 name: | ||||||
|  |                   title: Name | ||||||
|  |                   description: Source's display Name. | ||||||
|  |                   type: string | ||||||
|  |                   minLength: 1 | ||||||
|  |                 slug: | ||||||
|  |                   title: Slug | ||||||
|  |                   description: Internal source name, used in URLs. | ||||||
|  |                   type: string | ||||||
|  |                   format: slug | ||||||
|  |                   pattern: ^[-a-zA-Z0-9_]+$ | ||||||
|  |                   maxLength: 50 | ||||||
|  |                   minLength: 1 | ||||||
|  |                 enabled: | ||||||
|  |                   title: Enabled | ||||||
|  |                   type: boolean | ||||||
|  |                 authentication_flow: | ||||||
|  |                   title: Authentication flow | ||||||
|  |                   description: Flow to use when authenticating existing users. | ||||||
|  |                   type: string | ||||||
|  |                   format: uuid | ||||||
|  |                   x-nullable: true | ||||||
|  |                 enrollment_flow: | ||||||
|  |                   title: Enrollment flow | ||||||
|  |                   description: Flow to use when enrolling new users. | ||||||
|  |                   type: string | ||||||
|  |                   format: uuid | ||||||
|  |                   x-nullable: true | ||||||
|  |                 policies: | ||||||
|  |                   type: array | ||||||
|  |                   items: | ||||||
|  |                     type: string | ||||||
|  |                     format: uuid | ||||||
|  |                   readOnly: true | ||||||
|  |                   uniqueItems: true | ||||||
|  |                 property_mappings: | ||||||
|  |                   type: array | ||||||
|  |                   items: | ||||||
|  |                     type: string | ||||||
|  |                     format: uuid | ||||||
|  |                   uniqueItems: true | ||||||
|  |             readOnly: true | ||||||
|  |           ak_groups: | ||||||
|  |             description: '' | ||||||
|  |             type: array | ||||||
|  |             items: | ||||||
|  |               description: Custom Group model which supports a basic hierarchy | ||||||
|  |               required: | ||||||
|  |                 - name | ||||||
|  |                 - parent | ||||||
|  |               type: object | ||||||
|  |               properties: | ||||||
|  |                 group_uuid: | ||||||
|  |                   title: Group uuid | ||||||
|  |                   type: string | ||||||
|  |                   format: uuid | ||||||
|  |                   readOnly: true | ||||||
|  |                 name: | ||||||
|  |                   title: Name | ||||||
|  |                   type: string | ||||||
|  |                   maxLength: 80 | ||||||
|  |                   minLength: 1 | ||||||
|  |                 is_superuser: | ||||||
|  |                   title: Is superuser | ||||||
|  |                   description: Users added to this group will be superusers. | ||||||
|  |                   type: boolean | ||||||
|  |                 attributes: | ||||||
|  |                   title: Attributes | ||||||
|  |                   type: object | ||||||
|  |                 parent: | ||||||
|  |                   title: Parent | ||||||
|  |                   type: string | ||||||
|  |                   format: uuid | ||||||
|  |             readOnly: true | ||||||
|  |         readOnly: true | ||||||
|   InvitationStage: |   InvitationStage: | ||||||
|     description: InvitationStage Serializer |     description: InvitationStage Serializer | ||||||
|     required: |     required: | ||||||
| @ -11373,24 +11660,6 @@ definitions: | |||||||
|           no Invitation is given. By default this Stage will cancel the Flow when |           no Invitation is given. By default this Stage will cancel the Flow when | ||||||
|           no invitation is given. |           no invitation is given. | ||||||
|         type: boolean |         type: boolean | ||||||
|   Invitation: |  | ||||||
|     description: Invitation Serializer |  | ||||||
|     type: object |  | ||||||
|     properties: |  | ||||||
|       pk: |  | ||||||
|         title: Invite uuid |  | ||||||
|         type: string |  | ||||||
|         format: uuid |  | ||||||
|         readOnly: true |  | ||||||
|       expires: |  | ||||||
|         title: Expires |  | ||||||
|         type: string |  | ||||||
|         format: date-time |  | ||||||
|         x-nullable: true |  | ||||||
|       fixed_data: |  | ||||||
|         title: Fixed data |  | ||||||
|         description: Optional fixed data to enforce on user enrollment. |  | ||||||
|         type: object |  | ||||||
|   PasswordStage: |   PasswordStage: | ||||||
|     description: PasswordStage Serializer |     description: PasswordStage Serializer | ||||||
|     required: |     required: | ||||||
| @ -11496,6 +11765,11 @@ definitions: | |||||||
|         type: integer |         type: integer | ||||||
|         maximum: 2147483647 |         maximum: 2147483647 | ||||||
|         minimum: -2147483648 |         minimum: -2147483648 | ||||||
|  |       promptstage_set: | ||||||
|  |         description: '' | ||||||
|  |         type: array | ||||||
|  |         items: | ||||||
|  |           $ref: '#/definitions/Stage' | ||||||
|   PromptStage: |   PromptStage: | ||||||
|     description: PromptStage Serializer |     description: PromptStage Serializer | ||||||
|     required: |     required: | ||||||
|  | |||||||
							
								
								
									
										27
									
								
								web/src/api/Invitations.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								web/src/api/Invitations.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | |||||||
|  | import { DefaultClient, QueryArguments, AKResponse } from "./Client"; | ||||||
|  | import { EventContext } from "./Events"; | ||||||
|  | import { User } from "./Users"; | ||||||
|  |  | ||||||
|  | export class Invitation { | ||||||
|  |  | ||||||
|  |     pk: string; | ||||||
|  |     expires: number; | ||||||
|  |     fixed_date: EventContext; | ||||||
|  |     created_by: User; | ||||||
|  |  | ||||||
|  |     constructor() { | ||||||
|  |         throw Error(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     static get(pk: string): Promise<Invitation> { | ||||||
|  |         return DefaultClient.fetch<Invitation>(["stages", "invitation", "invitations", pk]); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     static list(filter?: QueryArguments): Promise<AKResponse<Invitation>> { | ||||||
|  |         return DefaultClient.fetch<AKResponse<Invitation>>(["stages", "invitation", "invitations"], filter); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     static adminUrl(rest: string): string { | ||||||
|  |         return `/administration/stages/invitations/${rest}`; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										30
									
								
								web/src/api/Prompts.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								web/src/api/Prompts.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | |||||||
|  | import { DefaultClient, QueryArguments, AKResponse } from "./Client"; | ||||||
|  | import { Stage } from "./Flows"; | ||||||
|  |  | ||||||
|  | export class Prompt { | ||||||
|  |  | ||||||
|  |     pk: string; | ||||||
|  |     field_key: string; | ||||||
|  |     label: string; | ||||||
|  |     type: string; | ||||||
|  |     required: boolean; | ||||||
|  |     placeholder: string; | ||||||
|  |     order: number; | ||||||
|  |     promptstage_set: Stage[]; | ||||||
|  |  | ||||||
|  |     constructor() { | ||||||
|  |         throw Error(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     static get(pk: string): Promise<Prompt> { | ||||||
|  |         return DefaultClient.fetch<Prompt>(["stages", "prompt", "prompts", pk]); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     static list(filter?: QueryArguments): Promise<AKResponse<Prompt>> { | ||||||
|  |         return DefaultClient.fetch<AKResponse<Prompt>>(["stages", "prompt", "prompts"], filter); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     static adminUrl(rest: string): string { | ||||||
|  |         return `/administration/stages/prompts/${rest}`; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -29,7 +29,7 @@ export class SidebarItem { | |||||||
|         this.condition = async () => true; |         this.condition = async () => true; | ||||||
|         this.activeMatchers = []; |         this.activeMatchers = []; | ||||||
|         if (this.path) { |         if (this.path) { | ||||||
|             this.activeMatchers.push(new RegExp(`^${this.path}`)); |             this.activeMatchers.push(new RegExp(`^${this.path}$`)); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
| @ -41,8 +41,8 @@ export const SIDEBAR_ITEMS: SidebarItem[] = [ | |||||||
|     new SidebarItem("Flows").children( |     new SidebarItem("Flows").children( | ||||||
|         new SidebarItem("Flows", "/flow/flows").activeWhen(`^/flow/flows/(?<slug>${SLUG_REGEX})$`), |         new SidebarItem("Flows", "/flow/flows").activeWhen(`^/flow/flows/(?<slug>${SLUG_REGEX})$`), | ||||||
|         new SidebarItem("Stages", "/flow/stages"), |         new SidebarItem("Stages", "/flow/stages"), | ||||||
|         new SidebarItem("Prompts", "/administration/stages_prompts/"), |         new SidebarItem("Prompts", "/flow/stages/prompts"), | ||||||
|         new SidebarItem("Invitations", "/administration/stages/invitations/"), |         new SidebarItem("Invitations", "/flow/stages/invitations"), | ||||||
|     ).when((): Promise<boolean> => { |     ).when((): Promise<boolean> => { | ||||||
|         return User.me().then(u => u.is_superuser); |         return User.me().then(u => u.is_superuser); | ||||||
|     }), |     }), | ||||||
|  | |||||||
							
								
								
									
										72
									
								
								web/src/pages/stages/InvitationListPage.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								web/src/pages/stages/InvitationListPage.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,72 @@ | |||||||
|  | import { gettext } from "django"; | ||||||
|  | import { customElement, html, property, TemplateResult } from "lit-element"; | ||||||
|  | import { AKResponse } from "../../api/Client"; | ||||||
|  | import { TablePage } from "../../elements/table/TablePage"; | ||||||
|  |  | ||||||
|  | import "../../elements/buttons/ModalButton"; | ||||||
|  | import "../../elements/buttons/SpinnerButton"; | ||||||
|  | import { TableColumn } from "../../elements/table/Table"; | ||||||
|  | import { Invitation } from "../../api/Invitations"; | ||||||
|  |  | ||||||
|  | @customElement("ak-stage-invitation-list") | ||||||
|  | export class InvitationListPage extends TablePage<Invitation> { | ||||||
|  |     searchEnabled(): boolean { | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |     pageTitle(): string { | ||||||
|  |         return gettext("Invitations"); | ||||||
|  |     } | ||||||
|  |     pageDescription(): string { | ||||||
|  |         return gettext("Create Invitation Links to enroll Users, and optionally force specific attributes of their account."); | ||||||
|  |     } | ||||||
|  |     pageIcon(): string { | ||||||
|  |         return gettext("pf-icon pf-icon-migration"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @property() | ||||||
|  |     order = "expires"; | ||||||
|  |  | ||||||
|  |     apiEndpoint(page: number): Promise<AKResponse<Invitation>> { | ||||||
|  |         return Invitation.list({ | ||||||
|  |             ordering: this.order, | ||||||
|  |             page: page, | ||||||
|  |             search: this.search || "", | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     columns(): TableColumn[] { | ||||||
|  |         return [ | ||||||
|  |             new TableColumn("ID", "pk"), | ||||||
|  |             new TableColumn("Created by", "created_by"), | ||||||
|  |             new TableColumn("Expiry"), | ||||||
|  |             new TableColumn(""), | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     row(item: Invitation): TemplateResult[] { | ||||||
|  |         return [ | ||||||
|  |             html`${item.pk}`, | ||||||
|  |             html`${item.created_by.username}`, | ||||||
|  |             html`${new Date(item.expires * 1000).toLocaleString()}`, | ||||||
|  |             html` | ||||||
|  |             <ak-modal-button href="${Invitation.adminUrl(`${item.pk}/delete/`)}"> | ||||||
|  |                 <ak-spinner-button slot="trigger" class="pf-m-danger"> | ||||||
|  |                     ${gettext("Delete")} | ||||||
|  |                 </ak-spinner-button> | ||||||
|  |                 <div slot="modal"></div> | ||||||
|  |             </ak-modal-button>`, | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     renderToolbar(): TemplateResult { | ||||||
|  |         return html` | ||||||
|  |         <ak-modal-button href=${Invitation.adminUrl("create/")}> | ||||||
|  |             <ak-spinner-button slot="trigger" class="pf-m-primary"> | ||||||
|  |                 ${gettext("Create")} | ||||||
|  |             </ak-spinner-button> | ||||||
|  |             <div slot="modal"></div> | ||||||
|  |         </ak-modal-button> | ||||||
|  |         ${super.renderToolbar()} | ||||||
|  |         `; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										84
									
								
								web/src/pages/stages/PromptListPage.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								web/src/pages/stages/PromptListPage.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,84 @@ | |||||||
|  | import { gettext } from "django"; | ||||||
|  | import { customElement, html, property, TemplateResult } from "lit-element"; | ||||||
|  | import { AKResponse } from "../../api/Client"; | ||||||
|  | import { TablePage } from "../../elements/table/TablePage"; | ||||||
|  |  | ||||||
|  | import "../../elements/buttons/ModalButton"; | ||||||
|  | import "../../elements/buttons/SpinnerButton"; | ||||||
|  | import { TableColumn } from "../../elements/table/Table"; | ||||||
|  | import { Prompt } from "../../api/Prompts"; | ||||||
|  |  | ||||||
|  | @customElement("ak-stage-prompt-list") | ||||||
|  | export class PromptListPage extends TablePage<Prompt> { | ||||||
|  |     searchEnabled(): boolean { | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |     pageTitle(): string { | ||||||
|  |         return gettext("Prompts"); | ||||||
|  |     } | ||||||
|  |     pageDescription(): string { | ||||||
|  |         return gettext("Single Prompts that can be used for Prompt Stages."); | ||||||
|  |     } | ||||||
|  |     pageIcon(): string { | ||||||
|  |         return gettext("pf-icon pf-icon-plugged"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @property() | ||||||
|  |     order = "order"; | ||||||
|  |  | ||||||
|  |     apiEndpoint(page: number): Promise<AKResponse<Prompt>> { | ||||||
|  |         return Prompt.list({ | ||||||
|  |             ordering: this.order, | ||||||
|  |             page: page, | ||||||
|  |             search: this.search || "", | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     columns(): TableColumn[] { | ||||||
|  |         return [ | ||||||
|  |             new TableColumn("Field", "field_key"), | ||||||
|  |             new TableColumn("Label", "label"), | ||||||
|  |             new TableColumn("Type", "type"), | ||||||
|  |             new TableColumn("Order", "order"), | ||||||
|  |             new TableColumn("Stages"), | ||||||
|  |             new TableColumn(""), | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     row(item: Prompt): TemplateResult[] { | ||||||
|  |         return [ | ||||||
|  |             html`${item.field_key}`, | ||||||
|  |             html`${item.label}`, | ||||||
|  |             html`${item.type}`, | ||||||
|  |             html`${item.order}`, | ||||||
|  |             html`${item.promptstage_set.map((stage) => { | ||||||
|  |                 return html`<li>${stage.name}</li>`; | ||||||
|  |             })}`, | ||||||
|  |             html` | ||||||
|  |             <ak-modal-button href="${Prompt.adminUrl(`${item.pk}/update/`)}"> | ||||||
|  |                 <ak-spinner-button slot="trigger" class="pf-m-secondary"> | ||||||
|  |                     ${gettext("Edit")} | ||||||
|  |                 </ak-spinner-button> | ||||||
|  |                 <div slot="modal"></div> | ||||||
|  |             </ak-modal-button> | ||||||
|  |             <ak-modal-button href="${Prompt.adminUrl(`${item.pk}/delete/`)}"> | ||||||
|  |                 <ak-spinner-button slot="trigger" class="pf-m-danger"> | ||||||
|  |                     ${gettext("Delete")} | ||||||
|  |                 </ak-spinner-button> | ||||||
|  |                 <div slot="modal"></div> | ||||||
|  |             </ak-modal-button>`, | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     renderToolbar(): TemplateResult { | ||||||
|  |         return html` | ||||||
|  |         <ak-modal-button href=${Prompt.adminUrl("create/")}> | ||||||
|  |             <ak-spinner-button slot="trigger" class="pf-m-primary"> | ||||||
|  |                 ${gettext("Create")} | ||||||
|  |             </ak-spinner-button> | ||||||
|  |             <div slot="modal"></div> | ||||||
|  |         </ak-modal-button> | ||||||
|  |         ${super.renderToolbar()} | ||||||
|  |         `; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -22,6 +22,8 @@ import "./pages/providers/ProviderViewPage"; | |||||||
| import "./pages/sources/SourcesListPage"; | import "./pages/sources/SourcesListPage"; | ||||||
| import "./pages/sources/SourceViewPage"; | import "./pages/sources/SourceViewPage"; | ||||||
| import "./pages/stages/StageListPage"; | import "./pages/stages/StageListPage"; | ||||||
|  | import "./pages/stages/InvitationListPage"; | ||||||
|  | import "./pages/stages/PromptListPage"; | ||||||
| import "./pages/system-tasks/SystemTaskListPage"; | import "./pages/system-tasks/SystemTaskListPage"; | ||||||
| import "./pages/tokens/TokenListPage"; | import "./pages/tokens/TokenListPage"; | ||||||
| import "./pages/users/UserListPage"; | import "./pages/users/UserListPage"; | ||||||
| @ -49,6 +51,8 @@ export const ROUTES: Route[] = [ | |||||||
|     new Route(new RegExp("^/identity/groups$"), html`<ak-group-list></ak-group-list>`), |     new Route(new RegExp("^/identity/groups$"), html`<ak-group-list></ak-group-list>`), | ||||||
|     new Route(new RegExp("^/identity/users$"), html`<ak-user-list></ak-user-list>`), |     new Route(new RegExp("^/identity/users$"), html`<ak-user-list></ak-user-list>`), | ||||||
|     new Route(new RegExp("^/core/tokens$"), html`<ak-token-list></ak-token-list>`), |     new Route(new RegExp("^/core/tokens$"), html`<ak-token-list></ak-token-list>`), | ||||||
|  |     new Route(new RegExp("^/flow/stages/invitations$"), html`<ak-stage-invitation-list></ak-stage-invitation-list>`), | ||||||
|  |     new Route(new RegExp("^/flow/stages/prompts$"), html`<ak-stage-prompt-list></ak-stage-prompt-list>`), | ||||||
|     new Route(new RegExp("^/flow/stages$"), html`<ak-stage-list></ak-stage-list>`), |     new Route(new RegExp("^/flow/stages$"), html`<ak-stage-list></ak-stage-list>`), | ||||||
|     new Route(new RegExp("^/flow/flows$"), html`<ak-flow-list></ak-flow-list>`), |     new Route(new RegExp("^/flow/flows$"), html`<ak-flow-list></ak-flow-list>`), | ||||||
|     new Route(new RegExp(`^/flow/flows/(?<slug>${SLUG_REGEX})$`)).then((args) => { |     new Route(new RegExp(`^/flow/flows/(?<slug>${SLUG_REGEX})$`)).then((args) => { | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Jens Langhammer
					Jens Langhammer