core: load user detail form in an inner SiteShell so update doesn't reload entire page

This commit is contained in:
Jens Langhammer 2020-12-13 00:11:08 +01:00
parent 7e8702a71e
commit 96f0d582f0
6 changed files with 50 additions and 26 deletions

View File

@ -0,0 +1,26 @@
{% load i18n %}
<div class="pf-c-card">
<div class="pf-c-card__header pf-c-title pf-m-md">
{% trans 'Update details' %}
</div>
<div class="pf-c-card__body">
<form action="" method="post" class="pf-c-form pf-m-horizontal">
{% include 'partials/form_horizontal.html' with form=form %}
{% block beneath_form %}
{% endblock %}
<div class="pf-c-form__group pf-m-action">
<div class="pf-c-form__horizontal-group">
<div class="pf-c-form__actions">
<input class="pf-c-button pf-m-primary" type="submit" value="{% trans 'Update' %}" />
{% if unenrollment_enabled %}
<a class="pf-c-button pf-m-danger"
href="{% url 'authentik_flows:default-unenrollment' %}?back={{ request.get_full_path }}">{%
trans "Delete account" %}</a>
{% endif %}
</div>
</div>
</div>
</form>
</div>
</div>

View File

@ -15,29 +15,9 @@
<section class="pf-c-page__main-section"> <section class="pf-c-page__main-section">
<div class="pf-u-display-flex pf-u-justify-content-center"> <div class="pf-u-display-flex pf-u-justify-content-center">
<div class="pf-u-w-75"> <div class="pf-u-w-75">
<div class="pf-c-card"> <ak-site-shell url="{% url 'authentik_core:user-details' %}">
<div class="pf-c-card__header pf-c-title pf-m-md"> <div slot="body"></div>
{% trans 'Update details' %} </ak-site-shell>
</div>
<div class="pf-c-card__body">
<form action="" method="post" class="pf-c-form pf-m-horizontal">
{% include 'partials/form_horizontal.html' with form=form %}
{% block beneath_form %}
{% endblock %}
<div class="pf-c-form__group pf-m-action">
<div class="pf-c-form__horizontal-group">
<div class="pf-c-form__actions">
<input class="pf-c-button pf-m-primary" type="submit" value="{% trans 'Update' %}" />
{% if unenrollment_enabled %}
<a class="pf-c-button pf-m-danger"
href="{% url 'authentik_flows:default-unenrollment' %}?back={{ request.get_full_path }}">{% trans "Delete account" %}</a>
{% endif %}
</div>
</div>
</div>
</form>
</div>
</div>
</div> </div>
</div> </div>
</section> </section>

View File

@ -28,3 +28,9 @@ class TestUserViews(TestCase):
self.assertEqual( self.assertEqual(
self.client.get(reverse("authentik_core:user-settings")).status_code, 200 self.client.get(reverse("authentik_core:user-settings")).status_code, 200
) )
def test_user_details(self):
"""Test UserDetailsView"""
self.assertEqual(
self.client.get(reverse("authentik_core:user-details")).status_code, 200
)

View File

@ -7,6 +7,7 @@ urlpatterns = [
path("", shell.ShellView.as_view(), name="shell"), path("", shell.ShellView.as_view(), name="shell"),
# User views # User views
path("-/user/", user.UserSettingsView.as_view(), name="user-settings"), path("-/user/", user.UserSettingsView.as_view(), name="user-settings"),
path("-/user/details/", user.UserDetailsView.as_view(), name="user-details"),
path("-/user/tokens/", user.TokenListView.as_view(), name="user-tokens"), path("-/user/tokens/", user.TokenListView.as_view(), name="user-tokens"),
path( path(
"-/user/tokens/create/", "-/user/tokens/create/",

View File

@ -11,6 +11,7 @@ from django.http.response import HttpResponse
from django.urls import reverse_lazy 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 ListView, UpdateView
from django.views.generic.base import TemplateView
from guardian.mixins import PermissionListMixin, PermissionRequiredMixin from guardian.mixins import PermissionListMixin, PermissionRequiredMixin
from guardian.shortcuts import get_objects_for_user from guardian.shortcuts import get_objects_for_user
@ -26,14 +27,20 @@ from authentik.flows.models import Flow, FlowDesignation
from authentik.lib.views import CreateAssignPermView from authentik.lib.views import CreateAssignPermView
class UserSettingsView(SuccessMessageMixin, LoginRequiredMixin, UpdateView): class UserSettingsView(TemplateView):
"""Update User settings""" """Multiple SiteShells for user details and all stages"""
template_name = "user/settings.html" template_name = "user/settings.html"
class UserDetailsView(SuccessMessageMixin, LoginRequiredMixin, UpdateView):
"""Update User details"""
template_name = "user/details.html"
form_class = UserDetailForm form_class = UserDetailForm
success_message = _("Successfully updated user.") success_message = _("Successfully updated user.")
success_url = reverse_lazy("authentik_core:user-settings") success_url = reverse_lazy("authentik_core:user-details")
def get_object(self): def get_object(self):
return self.request.user return self.request.user

View File

@ -63,6 +63,9 @@ export class SiteShell extends LitElement {
if (!this._url) { if (!this._url) {
return; return;
} }
if (this.loading) {
return;
}
this.loading = true; this.loading = true;
fetch(this._url) fetch(this._url)
.then((r) => { .then((r) => {
@ -75,6 +78,7 @@ export class SiteShell extends LitElement {
level_tag: "error", level_tag: "error",
message: gettext(`Request failed: ${r.statusText}`), message: gettext(`Request failed: ${r.statusText}`),
}); });
this.loading = false;
throw new SentryIgnoredError("Request failed"); throw new SentryIgnoredError("Request failed");
}) })
.then((r) => r.text()) .then((r) => r.text())