web: migrate remaining list views to web
This commit is contained in:
parent
9d4c22c706
commit
854d94056e
|
@ -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:
|
||||||
|
|
|
@ -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}`;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -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()}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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