accrete 0.0.99__py3-none-any.whl → 0.0.109__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- accrete/contrib/ui/__init__.py +6 -27
- accrete/contrib/ui/context.py +26 -294
- accrete/contrib/ui/filter.py +309 -280
- accrete/contrib/ui/middleware.py +44 -0
- accrete/contrib/ui/models.py +3 -0
- accrete/contrib/ui/static/bulma/README.md +4 -2
- accrete/contrib/ui/static/bulma/bulma.css +21551 -0
- accrete/contrib/ui/static/bulma/bulma.css.map +1 -0
- accrete/contrib/ui/static/bulma/bulma.scss +1 -1
- accrete/contrib/ui/static/bulma/css/bulma.css +1988 -2874
- accrete/contrib/ui/static/bulma/css/bulma.css.map +1 -1
- accrete/contrib/ui/static/bulma/css/bulma.min.css +2 -2
- accrete/contrib/ui/static/bulma/css/versions/bulma-no-dark-mode.css +19648 -0
- accrete/contrib/ui/static/bulma/css/versions/bulma-no-dark-mode.css.map +1 -0
- accrete/contrib/ui/static/bulma/css/versions/bulma-no-dark-mode.min.css +2 -2
- accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers-prefixed.css +11136 -0
- accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers-prefixed.css.map +1 -0
- accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers-prefixed.min.css +2 -2
- accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers.css +11136 -0
- accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers.css.map +1 -0
- accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers.min.css +2 -2
- accrete/contrib/ui/static/bulma/css/versions/bulma-prefixed.min.css +21550 -2
- accrete/contrib/ui/static/bulma/css/versions/bulma-prefixed.min.css.map +1 -1
- accrete/contrib/ui/static/bulma/css/versions/bulma-prefixed.min.min.css +3 -0
- accrete/contrib/ui/static/bulma/package.json +12 -11
- accrete/contrib/ui/static/bulma/sass/base/animations.css +15 -0
- accrete/contrib/ui/static/bulma/sass/base/animations.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/base/generic.css +196 -0
- accrete/contrib/ui/static/bulma/sass/base/generic.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/base/minireset.css +82 -0
- accrete/contrib/ui/static/bulma/sass/base/minireset.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/base/skeleton.css +113 -0
- accrete/contrib/ui/static/bulma/sass/base/skeleton.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/base/skeleton.scss +0 -12
- accrete/contrib/ui/static/bulma/sass/components/breadcrumb.css +108 -0
- accrete/contrib/ui/static/bulma/sass/components/breadcrumb.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/components/card.css +130 -0
- accrete/contrib/ui/static/bulma/sass/components/card.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/components/dropdown.css +119 -0
- accrete/contrib/ui/static/bulma/sass/components/dropdown.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/components/menu.css +119 -0
- accrete/contrib/ui/static/bulma/sass/components/menu.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/components/message.css +191 -0
- accrete/contrib/ui/static/bulma/sass/components/message.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/components/modal.css +194 -0
- accrete/contrib/ui/static/bulma/sass/components/modal.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/components/navbar.css +768 -0
- accrete/contrib/ui/static/bulma/sass/components/navbar.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/components/navbar.scss +41 -30
- accrete/contrib/ui/static/bulma/sass/components/pagination.css +302 -0
- accrete/contrib/ui/static/bulma/sass/components/pagination.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/components/panel.css +224 -0
- accrete/contrib/ui/static/bulma/sass/components/panel.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/components/panel.scss +2 -2
- accrete/contrib/ui/static/bulma/sass/components/tabs.css +192 -0
- accrete/contrib/ui/static/bulma/sass/components/tabs.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/elements/block.css +17 -0
- accrete/contrib/ui/static/bulma/sass/elements/block.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/elements/box.css +43 -0
- accrete/contrib/ui/static/bulma/sass/elements/box.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/elements/button.css +685 -0
- accrete/contrib/ui/static/bulma/sass/elements/button.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/elements/button.scss +9 -2
- accrete/contrib/ui/static/bulma/sass/elements/content.css +208 -0
- accrete/contrib/ui/static/bulma/sass/elements/content.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/elements/content.scss +8 -2
- accrete/contrib/ui/static/bulma/sass/elements/delete.css +60 -0
- accrete/contrib/ui/static/bulma/sass/elements/delete.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/elements/icon.css +51 -0
- accrete/contrib/ui/static/bulma/sass/elements/icon.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/elements/image.css +253 -0
- accrete/contrib/ui/static/bulma/sass/elements/image.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/elements/loader.css +14 -0
- accrete/contrib/ui/static/bulma/sass/elements/loader.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/elements/notification.css +213 -0
- accrete/contrib/ui/static/bulma/sass/elements/notification.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/elements/progress.css +119 -0
- accrete/contrib/ui/static/bulma/sass/elements/progress.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/elements/table.css +294 -0
- accrete/contrib/ui/static/bulma/sass/elements/table.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/elements/tag.css +252 -0
- accrete/contrib/ui/static/bulma/sass/elements/tag.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/elements/title.css +131 -0
- accrete/contrib/ui/static/bulma/sass/elements/title.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/form/checkbox-radio.css +72 -0
- accrete/contrib/ui/static/bulma/sass/form/checkbox-radio.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/form/checkbox-radio.scss +7 -3
- accrete/contrib/ui/static/bulma/sass/form/file.css +374 -0
- accrete/contrib/ui/static/bulma/sass/form/file.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/form/input-textarea.css +284 -0
- accrete/contrib/ui/static/bulma/sass/form/input-textarea.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/form/input-textarea.scss +0 -10
- accrete/contrib/ui/static/bulma/sass/form/select.css +347 -0
- accrete/contrib/ui/static/bulma/sass/form/select.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/form/select.scss +1 -0
- accrete/contrib/ui/static/bulma/sass/form/shared.css +48 -0
- accrete/contrib/ui/static/bulma/sass/form/shared.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/form/shared.scss +5 -1
- accrete/contrib/ui/static/bulma/sass/form/tools.css +356 -0
- accrete/contrib/ui/static/bulma/sass/form/tools.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/form/tools.scss +23 -12
- accrete/contrib/ui/static/bulma/sass/grid/columns-v2.css +1635 -0
- accrete/contrib/ui/static/bulma/sass/grid/columns-v2.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/grid/columns.css +1652 -0
- accrete/contrib/ui/static/bulma/sass/grid/columns.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/grid/columns.scss +109 -25
- accrete/contrib/ui/static/bulma/sass/grid/grid.css +3011 -0
- accrete/contrib/ui/static/bulma/sass/grid/grid.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/grid/grid.scss +3 -3
- accrete/contrib/ui/static/bulma/sass/helpers/aspect-ratio.css +61 -0
- accrete/contrib/ui/static/bulma/sass/helpers/aspect-ratio.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/helpers/border.css +17 -0
- accrete/contrib/ui/static/bulma/sass/helpers/border.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/helpers/color.css +5582 -0
- accrete/contrib/ui/static/bulma/sass/helpers/color.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/helpers/color.scss +166 -186
- accrete/contrib/ui/static/bulma/sass/helpers/flexbox.css +217 -0
- accrete/contrib/ui/static/bulma/sass/helpers/flexbox.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/helpers/float.css +37 -0
- accrete/contrib/ui/static/bulma/sass/helpers/float.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/helpers/gap.css +209 -0
- accrete/contrib/ui/static/bulma/sass/helpers/gap.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/helpers/other.css +34 -0
- accrete/contrib/ui/static/bulma/sass/helpers/other.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/helpers/overflow.css +65 -0
- accrete/contrib/ui/static/bulma/sass/helpers/overflow.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/helpers/position.css +45 -0
- accrete/contrib/ui/static/bulma/sass/helpers/position.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/helpers/spacing.css +489 -0
- accrete/contrib/ui/static/bulma/sass/helpers/spacing.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/helpers/typography.css +423 -0
- accrete/contrib/ui/static/bulma/sass/helpers/typography.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/helpers/visibility.css +485 -0
- accrete/contrib/ui/static/bulma/sass/helpers/visibility.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/layout/container.scss +16 -8
- accrete/contrib/ui/static/bulma/sass/layout/footer.css +9 -0
- accrete/contrib/ui/static/bulma/sass/layout/footer.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/layout/hero.css +534 -0
- accrete/contrib/ui/static/bulma/sass/layout/hero.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/layout/level.css +102 -0
- accrete/contrib/ui/static/bulma/sass/layout/level.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/layout/media.css +90 -0
- accrete/contrib/ui/static/bulma/sass/layout/media.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/layout/section.css +23 -0
- accrete/contrib/ui/static/bulma/sass/layout/section.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/layout/section.scss +4 -0
- accrete/contrib/ui/static/bulma/sass/themes/dark.css +3 -0
- accrete/contrib/ui/static/bulma/sass/themes/dark.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/themes/light.css +3 -0
- accrete/contrib/ui/static/bulma/sass/themes/light.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/themes/light.scss +1 -0
- accrete/contrib/ui/static/bulma/sass/themes/setup.css +3 -0
- accrete/contrib/ui/static/bulma/sass/themes/setup.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/utilities/controls.css +13 -0
- accrete/contrib/ui/static/bulma/sass/utilities/controls.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/utilities/css-variables.css +3 -0
- accrete/contrib/ui/static/bulma/sass/utilities/css-variables.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/utilities/css-variables.scss +3 -2
- accrete/contrib/ui/static/bulma/sass/utilities/derived-variables.css +3 -0
- accrete/contrib/ui/static/bulma/sass/utilities/derived-variables.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/utilities/extends.css +13 -0
- accrete/contrib/ui/static/bulma/sass/utilities/extends.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/utilities/functions.scss +2 -2
- accrete/contrib/ui/static/bulma/sass/utilities/initial-variables.css +3 -0
- accrete/contrib/ui/static/bulma/sass/utilities/initial-variables.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/utilities/initial-variables.scss +4 -4
- accrete/contrib/ui/static/bulma/sass/utilities/mixins.css +3 -0
- accrete/contrib/ui/static/bulma/sass/utilities/mixins.css.map +1 -0
- accrete/contrib/ui/static/bulma/sass/utilities/mixins.scss +1 -1
- accrete/contrib/ui/static/bulma/versions/bulma-no-dark-mode.css +19648 -0
- accrete/contrib/ui/static/bulma/versions/bulma-no-dark-mode.css.map +1 -0
- accrete/contrib/ui/static/bulma/versions/bulma-no-dark-mode.scss +2 -1
- accrete/contrib/ui/static/bulma/versions/bulma-no-helpers-prefixed.css +11136 -0
- accrete/contrib/ui/static/bulma/versions/bulma-no-helpers-prefixed.css.map +1 -0
- accrete/contrib/ui/static/bulma/versions/bulma-no-helpers-prefixed.scss +1 -1
- accrete/contrib/ui/static/bulma/versions/bulma-no-helpers.css +11136 -0
- accrete/contrib/ui/static/bulma/versions/bulma-no-helpers.css.map +1 -0
- accrete/contrib/ui/static/bulma/versions/bulma-no-helpers.scss +1 -1
- accrete/contrib/ui/static/bulma/versions/bulma-prefixed.css +21551 -0
- accrete/contrib/ui/static/bulma/versions/bulma-prefixed.css.map +1 -0
- accrete/contrib/ui/static/bulma/versions/bulma-prefixed.scss +1 -1
- accrete/contrib/ui/static/css/accrete.css +20757 -19996
- accrete/contrib/ui/static/css/accrete.css.map +1 -1
- accrete/contrib/ui/static/css/accrete.scss +185 -461
- accrete/contrib/ui/static/js/filter.js +98 -679
- accrete/contrib/ui/static/js/htmx.min.js +1 -1
- accrete/contrib/ui/templates/django/forms/widgets/date.html +5 -0
- accrete/contrib/ui/templates/django/forms/widgets/input.html +1 -1
- accrete/contrib/ui/templates/django/forms/widgets/select.html +7 -5
- accrete/contrib/ui/templates/ui/content_right.html +7 -0
- accrete/contrib/ui/templates/ui/filter/filter.html +27 -0
- accrete/contrib/ui/templates/ui/filter/query_input.html +31 -0
- accrete/contrib/ui/templates/ui/filter/query_operator.html +11 -0
- accrete/contrib/ui/templates/ui/filter/query_params.html +106 -0
- accrete/contrib/ui/templates/ui/filter/query_tags.html +26 -0
- accrete/contrib/ui/templates/ui/layout.html +175 -232
- accrete/contrib/ui/templates/ui/list.html +39 -28
- accrete/contrib/ui/templates/ui/list_update.html +3 -0
- accrete/contrib/ui/templates/ui/message.html +13 -0
- accrete/contrib/ui/templates/ui/{partials/modal.html → modal.html} +9 -5
- accrete/contrib/ui/templates/ui/oob.html +3 -0
- accrete/contrib/ui/templates/ui/table.html +67 -71
- accrete/contrib/ui/templates/ui/table_row_update.html +14 -0
- accrete/contrib/ui/templates/ui/widgets/model_search_select.html +42 -0
- accrete/contrib/ui/templates/ui/widgets/model_search_select_multi.html +78 -0
- accrete/contrib/ui/templates/ui/widgets/model_search_select_options.html +3 -0
- accrete/contrib/ui/templatetags/{accrete_ui.py → ui.py} +69 -57
- accrete/contrib/ui/urls.py +3 -1
- accrete/contrib/ui/views.py +33 -3
- accrete/contrib/ui/widgets/__init__.py +1 -0
- accrete/contrib/ui/widgets/search_select.py +106 -0
- accrete/contrib/user/forms.py +1 -1
- accrete/contrib/user/templates/user/change_email.html +22 -27
- accrete/contrib/user/templates/user/change_password.html +24 -36
- accrete/contrib/user/templates/user/login.html +72 -23
- accrete/contrib/user/templates/user/user_form.html +50 -52
- accrete/contrib/user/urls.py +2 -3
- accrete/contrib/user/views.py +39 -46
- accrete/forms.py +0 -2
- accrete/managers.py +4 -4
- accrete/middleware.py +43 -68
- accrete/models.py +7 -1
- accrete/storage.py +4 -1
- accrete/tenant.py +11 -5
- accrete/utils/__init__.py +2 -0
- accrete/utils/models.py +9 -1
- accrete/utils/views.py +36 -20
- accrete/views.py +9 -5
- {accrete-0.0.99.dist-info → accrete-0.0.109.dist-info}/METADATA +2 -2
- accrete-0.0.109.dist-info/RECORD +369 -0
- {accrete-0.0.99.dist-info → accrete-0.0.109.dist-info}/WHEEL +1 -1
- accrete/contrib/ui/elements.py +0 -93
- accrete/contrib/ui/static/bulma/css/versions/bulma-no-dark-mode.min.css.map +0 -1
- accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers-prefixed.min.css.map +0 -1
- accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers.min.css.map +0 -1
- accrete/contrib/ui/static/bulma/sass/grid/columns-v2.scss +0 -957
- accrete/contrib/ui/static/js/ui.js +0 -30
- accrete/contrib/ui/templates/ui/dashboard.html +0 -7
- accrete/contrib/ui/templates/ui/detail.html +0 -19
- accrete/contrib/ui/templates/ui/form.html +0 -21
- accrete/contrib/ui/templates/ui/partials/filter.html +0 -143
- accrete/contrib/ui/templates/ui/partials/form_errors.html +0 -34
- accrete/contrib/ui/templates/ui/partials/header.html +0 -123
- accrete/contrib/ui/templates/ui/partials/modal_form.html +0 -45
- accrete/contrib/ui/templates/ui/partials/onchange_form.html +0 -1
- accrete/contrib/ui/templates/ui/partials/pagination_detail.html +0 -23
- accrete/contrib/ui/templates/ui/partials/pagination_list.html +0 -28
- accrete/contrib/ui/templates/ui/partials/table_field.html +0 -16
- accrete/contrib/ui/templates/ui/partials/table_field_float.html +0 -1
- accrete/contrib/ui/templates/ui/partials/table_field_monetary.html +0 -4
- accrete/contrib/ui/templates/ui/partials/table_field_string.html +0 -1
- accrete/contrib/user/templates/user/user_detail.html +0 -43
- accrete-0.0.99.dist-info/RECORD +0 -231
- {accrete-0.0.99.dist-info → accrete-0.0.109.dist-info}/licenses/LICENSE +0 -0
@@ -1,29 +1,24 @@
|
|
1
|
-
{% extends 'ui/
|
1
|
+
{% extends 'ui/modal.html' %}
|
2
|
+
{% load i18n %}
|
2
3
|
|
3
|
-
{% block
|
4
|
-
<form id="form"
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
</
|
15
|
-
</
|
16
|
-
</
|
17
|
-
<div class="columns">
|
18
|
-
<div class="column is-6">
|
19
|
-
<label class="label has-field is-required">
|
20
|
-
{{ form.password.label_tag }}
|
21
|
-
<span class="has-text-danger is-size-7">{{ form.password.errors }}</span>
|
22
|
-
<div class="field">
|
23
|
-
<p class="control is-fullwidth">{{ form.password }}</p>
|
24
|
-
</div>
|
25
|
-
</label>
|
26
|
-
</div>
|
27
|
-
</div>
|
28
|
-
</form>
|
4
|
+
{% block modal_content %}
|
5
|
+
<form id="{{ modal_id }}-form" hx-post="{% url 'user:change_email' %}">
|
6
|
+
{% csrf_token %}
|
7
|
+
<label class="label has-field is-required">
|
8
|
+
{{ form.email.label }}
|
9
|
+
{{ form.email }}
|
10
|
+
<span class="has-text-danger is-size-7">{{ form.email.errors }}</span>
|
11
|
+
</label>
|
12
|
+
<label class="label has-field is-required">
|
13
|
+
{{ form.password.label }}
|
14
|
+
{{ form.password }}
|
15
|
+
<span class="has-text-danger is-size-7">{{ form.password.errors }}</span>
|
16
|
+
</label>
|
17
|
+
</form>
|
29
18
|
{% endblock %}
|
19
|
+
|
20
|
+
{% block modal_buttons %}
|
21
|
+
<button type="submit" form="{{ modal_id }}-form" class="button is-success">{% translate 'Save' %}</button>
|
22
|
+
{{ block.super }}
|
23
|
+
{% endblock %}
|
24
|
+
|
@@ -1,40 +1,28 @@
|
|
1
|
-
{% extends 'ui/
|
1
|
+
{% extends 'ui/modal.html' %}
|
2
|
+
{% load i18n %}
|
2
3
|
|
3
|
-
{% block
|
4
|
-
<form id="form"
|
4
|
+
{% block modal_content %}
|
5
|
+
<form id="{{ modal_id }}-form" hx-post="{% url 'user:change_password' %}">
|
5
6
|
{% csrf_token %}
|
6
|
-
<
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
<span class="has-text-danger is-size-7">{{ form.new_password.errors }}</span>
|
22
|
-
<div class="field">
|
23
|
-
<p class="control is-fullwidth">{{ form.new_password }}</p>
|
24
|
-
</div>
|
25
|
-
</label>
|
26
|
-
</div>
|
27
|
-
</div>
|
28
|
-
<div class="columns">
|
29
|
-
<div class="column is-6">
|
30
|
-
<label class="label has-field is-required">
|
31
|
-
{{ form.new_password_confirm.label_tag }}
|
32
|
-
<span class="has-text-danger is-size-7">{{ form.new_password_confirm.errors }}</span>
|
33
|
-
<div class="field">
|
34
|
-
<p class="control is-fullwidth">{{ form.new_password_confirm }}</p>
|
35
|
-
</div>
|
36
|
-
</label>
|
37
|
-
</div>
|
38
|
-
</div>
|
7
|
+
<label class="label">
|
8
|
+
{{ form.old_password.label }}
|
9
|
+
{{ form.old_password }}
|
10
|
+
<span class="has-text-danger is-size-7">{{ form.old_password.errors }}</span>
|
11
|
+
</label>
|
12
|
+
<label class="label has-field is-required">
|
13
|
+
{{ form.new_password.label }}
|
14
|
+
{{ form.new_password }}
|
15
|
+
<span class="has-text-danger is-size-7">{{ form.new_password.errors }}</span>
|
16
|
+
</label>
|
17
|
+
<label class="label has-field is-required">
|
18
|
+
{{ form.new_password_confirm.label }}
|
19
|
+
{{ form.new_password_confirm }}
|
20
|
+
<span class="has-text-danger is-size-7">{{ form.new_password_confirm.errors }}</span>
|
21
|
+
</label>
|
39
22
|
</form>
|
40
23
|
{% endblock %}
|
24
|
+
|
25
|
+
{% block modal_buttons %}
|
26
|
+
<button type="submit" form="{{ modal_id }}-form" class="button is-success">{% translate 'Save' %}</button>
|
27
|
+
{{ block.super }}
|
28
|
+
{% endblock %}
|
@@ -2,33 +2,82 @@
|
|
2
2
|
{% load static %}
|
3
3
|
{% load i18n %}
|
4
4
|
|
5
|
-
{% block title %}Login
|
5
|
+
{% block title %}Login{% endblock %}
|
6
6
|
|
7
7
|
{% block body %}
|
8
|
-
<section class="hero is-
|
9
|
-
|
10
|
-
<div class="
|
11
|
-
<
|
12
|
-
<div class="
|
13
|
-
<
|
14
|
-
|
15
|
-
<span class="
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
<span
|
20
|
-
</
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
<
|
25
|
-
|
8
|
+
<section class="hero is-success is-fullheight">
|
9
|
+
<!-- Hero head: will stick at the top -->
|
10
|
+
<div class="hero-head">
|
11
|
+
<header class="navbar">
|
12
|
+
<div class="container">
|
13
|
+
<div class="navbar-brand">
|
14
|
+
<p class="title navbar-item">HRP</p>
|
15
|
+
<span class="navbar-burger" data-target="navbarMenuHeroC">
|
16
|
+
<span></span>
|
17
|
+
<span></span>
|
18
|
+
<span></span>
|
19
|
+
<span></span>
|
20
|
+
</span>
|
21
|
+
</div>
|
22
|
+
{# <div id="navbarMenuHeroC" class="navbar-menu">#}
|
23
|
+
{# <div class="navbar-end">#}
|
24
|
+
{# <a class="navbar-item is-active"> Home </a>#}
|
25
|
+
{# <a class="navbar-item"> Examples </a>#}
|
26
|
+
{# <a class="navbar-item"> Documentation </a>#}
|
27
|
+
{# <span class="navbar-item">#}
|
28
|
+
{# <a class="button is-success is-inverted">#}
|
29
|
+
{# <span class="icon">#}
|
30
|
+
{# <i class="fab fa-github"></i>#}
|
31
|
+
{# </span>#}
|
32
|
+
{# <span>Download</span>#}
|
33
|
+
{# </a>#}
|
34
|
+
{# </span>#}
|
35
|
+
{# </div>#}
|
36
|
+
{# </div>#}
|
37
|
+
</div>
|
38
|
+
</header>
|
39
|
+
</div>
|
26
40
|
|
27
|
-
|
28
|
-
|
41
|
+
<!-- Hero content: will be in the middle -->
|
42
|
+
<div class="hero-body">
|
43
|
+
<div class="container">
|
44
|
+
<div class="columns">
|
45
|
+
<div class="column box is-8-tablet is-offset-2-tablet is-6-desktop is-offset-3-desktop is-4-fullhd is-offset-4-fullhd p-3" data-theme="light">
|
46
|
+
<form method="POST" action="" hx-boost="false">
|
47
|
+
{% csrf_token %}
|
48
|
+
<span class="has-text-danger is-size-7">{{ form.non_field_errors }}</span>
|
49
|
+
<label class="label">
|
50
|
+
<span class="has-text-black">{{ form.username.label_tag }}</span>
|
51
|
+
{{ form.username }}
|
52
|
+
<span class="has-text-danger is-size-7">{{ form.username.errors }}</span>
|
53
|
+
</label>
|
54
|
+
<label class="label">
|
55
|
+
<span class="has-text-black">{{ form.password.label_tag }}</span>
|
56
|
+
{{ form.password }}
|
57
|
+
<span class="has-text-danger is-size-7">{{ form.password.errors }}</span>
|
58
|
+
</label>
|
59
|
+
<input type="submit" class="button is-fullwidth is-success is-medium"
|
60
|
+
value="{% translate 'Login' %}">
|
61
|
+
</form>
|
62
|
+
</div>
|
29
63
|
</div>
|
30
64
|
</div>
|
31
65
|
</div>
|
32
|
-
|
33
|
-
|
66
|
+
|
67
|
+
<!-- Hero footer: will stick at the bottom -->
|
68
|
+
<div class="hero-foot">
|
69
|
+
<nav class="tabs is-boxed is-fullwidth">
|
70
|
+
<div class="container">
|
71
|
+
<ul>
|
72
|
+
{# <li class="is-active"><a>Overview</a></li>#}
|
73
|
+
{# <li><a>Modifiers</a></li>#}
|
74
|
+
{# <li><a>Grid</a></li>#}
|
75
|
+
{# <li><a>Elements</a></li>#}
|
76
|
+
{# <li><a>Components</a></li>#}
|
77
|
+
{# <li><a>Layout</a></li>#}
|
78
|
+
</ul>
|
79
|
+
</div>
|
80
|
+
</nav>
|
81
|
+
</div>
|
82
|
+
</section>
|
34
83
|
{% endblock %}
|
@@ -1,56 +1,54 @@
|
|
1
|
-
{% extends 'ui/
|
1
|
+
{% extends 'ui/layout.html' %}
|
2
2
|
{% load i18n %}
|
3
3
|
|
4
|
-
{% block
|
5
|
-
|
6
|
-
{%
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
<p class="control is-expanded">{{ form.username }}</p>
|
14
|
-
</div>
|
15
|
-
</label>
|
16
|
-
</div>
|
17
|
-
</div>
|
18
|
-
|
19
|
-
<div class="columns">
|
20
|
-
<div class="column is-6">
|
21
|
-
<label class="label has-field">
|
22
|
-
{{ form.first_name.label }}
|
23
|
-
<span class="has-text-danger is-size-7">{{ form.first_name.errors }}</span>
|
24
|
-
<div class="field">
|
25
|
-
<p class="control is-fullwidth is-expanded">{{ form.first_name }}</p>
|
26
|
-
</div>
|
27
|
-
|
28
|
-
</label>
|
29
|
-
</div>
|
30
|
-
</div>
|
31
|
-
|
32
|
-
<div class="columns">
|
33
|
-
<div class="column is-6">
|
34
|
-
<label class="label has-field">
|
35
|
-
{{ form.last_name.label }}
|
36
|
-
<span class="has-text-danger is-size-7">{{ form.last_name.errors }}</span>
|
37
|
-
<div class="field">
|
38
|
-
<p class="control is-fullwidth is-expanded">{{ form.last_name }}</p>
|
39
|
-
</div>
|
40
|
-
</label>
|
41
|
-
</div>
|
42
|
-
</div>
|
4
|
+
{% block header_left %}
|
5
|
+
{{ block.super }}
|
6
|
+
<button class="button p-2 my-1 mr-1 is-light" hx-get="{% url 'user:change_password' %}" hx-target="body" hx-swap="beforeend">
|
7
|
+
<span>{% translate 'Change Password' %}</span>
|
8
|
+
</button>
|
9
|
+
<button class="button p-2 my-1 mr-1 is-light" hx-get="{% url 'user:change_email' %}" hx-target="body" hx-swap="beforeend">
|
10
|
+
<span>{% translate 'Change E-Mail' %}</span>
|
11
|
+
</button>
|
12
|
+
{% endblock %}
|
43
13
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
<
|
51
|
-
|
52
|
-
|
14
|
+
{% block content_left %}
|
15
|
+
<form id="user-form" hx-post="{% url 'user:detail' %}" hx-trigger="change changed" hx-select="#user-form" hx-swap="outerHTML" hx-select-oob="#navbar-user-name">
|
16
|
+
{% csrf_token %}
|
17
|
+
<div class="columns m-0">
|
18
|
+
<div class="column is-6">
|
19
|
+
{% if form.save_error or form.non_field_errors %}
|
20
|
+
<div class="notification is-danger is-light">
|
21
|
+
{{ form.save_error|default_if_none:'' }}
|
22
|
+
{{ form.non_field_errors|default_if_none:'' }}
|
23
|
+
</div>
|
24
|
+
{% endif %}
|
25
|
+
<label class="label">
|
26
|
+
{{ form.username.label }}
|
27
|
+
{{ form.username }}
|
28
|
+
<span class="has-text-danger is-size-7">{{ form.username.errors }}</span>
|
29
|
+
</label>
|
30
|
+
<label class="label">
|
31
|
+
{{ form.first_name.label }}
|
32
|
+
{{ form.first_name }}
|
33
|
+
<span class="has-text-danger is-size-7">{{ form.first_name.errors }}</span>
|
34
|
+
</label>
|
35
|
+
<label class="label">
|
36
|
+
{{ form.last_name.label }}
|
37
|
+
{{ form.last_name }}
|
38
|
+
<span class="has-text-danger is-size-7">{{ form.last_name.errors }}</span>
|
39
|
+
</label>
|
40
|
+
<label class="label">
|
41
|
+
{{ form.language_code.label }}
|
42
|
+
{{ form.language_code }}
|
43
|
+
<span class="has-text-danger is-size-7">{{ form.language_code.errors }}</span>
|
44
|
+
</label>
|
45
|
+
<label class="label">
|
46
|
+
{% translate 'E-Mail' %}
|
47
|
+
<div class="field has-addons">
|
48
|
+
<p class="control input has-text-weight-normal">{{ user.email }}</p>
|
49
|
+
</div>
|
50
|
+
</label>
|
51
|
+
</div>
|
53
52
|
</div>
|
54
|
-
</
|
55
|
-
|
56
|
-
{% endblock %}
|
53
|
+
</form>
|
54
|
+
{% endblock %}
|
accrete/contrib/user/urls.py
CHANGED
@@ -7,7 +7,6 @@ urlpatterns = [
|
|
7
7
|
path('login/', views.LoginView.as_view(), name='login'),
|
8
8
|
path('logout/', views.LogoutView.as_view(), name='logout'),
|
9
9
|
path('detail/', views.user_detail, name='detail'),
|
10
|
-
path('
|
11
|
-
path('
|
12
|
-
path('edit/email', views.user_change_email, name='edit_email')
|
10
|
+
path('password/', views.user_change_password, name='change_password'),
|
11
|
+
path('email/', views.user_change_email, name='change_email')
|
13
12
|
]
|
accrete/contrib/user/views.py
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
from django.contrib.auth.forms import AuthenticationForm
|
2
2
|
from django.contrib.auth import views, update_session_auth_hash
|
3
3
|
from django.contrib.auth.decorators import login_required
|
4
|
-
from django.
|
5
|
-
from django.shortcuts import redirect, render, reverse, resolve_url
|
4
|
+
from django.shortcuts import redirect, render, resolve_url
|
6
5
|
from django.utils.translation import gettext_lazy as _
|
7
6
|
from django.conf import settings
|
8
7
|
|
@@ -36,21 +35,6 @@ class LogoutView(views.LogoutView):
|
|
36
35
|
|
37
36
|
@login_required()
|
38
37
|
def user_detail(request):
|
39
|
-
ctx = ui.DetailContext(
|
40
|
-
title=_('Preferences'),
|
41
|
-
object=request.user,
|
42
|
-
breadcrumbs=[],
|
43
|
-
actions=[
|
44
|
-
ui.ClientAction(_('Edit'), url=reverse('user:edit')),
|
45
|
-
ui.ClientAction(_('Change E-Mail'), url=reverse('user:edit_email')),
|
46
|
-
ui.ClientAction(_('Change Password'), url=reverse('user:edit_password'))
|
47
|
-
]
|
48
|
-
).dict()
|
49
|
-
return render(request, 'user/user_detail.html', ctx)
|
50
|
-
|
51
|
-
|
52
|
-
@login_required()
|
53
|
-
def user_edit(request):
|
54
38
|
form = UserForm(
|
55
39
|
initial={'language_code': request.user.language_code},
|
56
40
|
instance=request.user
|
@@ -58,12 +42,13 @@ def user_edit(request):
|
|
58
42
|
if request.method == 'POST':
|
59
43
|
form = save_form(UserForm(request.POST, instance=request.user))
|
60
44
|
if form.is_saved:
|
61
|
-
return redirect('user:detail')
|
62
|
-
ctx = ui.
|
63
|
-
title=_('Preferences'),
|
64
|
-
|
65
|
-
|
66
|
-
|
45
|
+
return redirect(resolve_url('user:detail') + f'?{request.GET.urlencode()}')
|
46
|
+
ctx = ui.Context(
|
47
|
+
title=_('User Preferences'),
|
48
|
+
extra=dict(
|
49
|
+
user=request.user,
|
50
|
+
form=form
|
51
|
+
)
|
67
52
|
).dict()
|
68
53
|
return render(request, 'user/user_form.html', ctx)
|
69
54
|
|
@@ -71,42 +56,50 @@ def user_edit(request):
|
|
71
56
|
@login_required()
|
72
57
|
def user_change_password(request):
|
73
58
|
form = ChangePasswordForm(instance=request.user)
|
59
|
+
ctx = ui.ModalContext(
|
60
|
+
title=_('Change Password'),
|
61
|
+
modal_id='change-password',
|
62
|
+
blocking=True,
|
63
|
+
extra=dict(
|
64
|
+
form=form,
|
65
|
+
user=request.user
|
66
|
+
)
|
67
|
+
).dict()
|
74
68
|
if request.method == 'POST':
|
75
69
|
form = save_form(ChangePasswordForm(request.POST, instance=request.user))
|
76
70
|
if form.is_saved:
|
77
71
|
update_session_auth_hash(request, form.instance)
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
fail_silently=True
|
72
|
+
return redirect(
|
73
|
+
resolve_url('user:detail')
|
74
|
+
+ f'?{request.GET.urlencode()}'
|
82
75
|
)
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
actions=ui.form_actions(reverse('user:detail'))
|
89
|
-
).dict()
|
76
|
+
ctx.update(form=form)
|
77
|
+
res = render(request, 'user/change_password.html', ctx)
|
78
|
+
res.headers['HX-Retarget'] = f'#{ctx["modal_id"]}'
|
79
|
+
res.headers['HX-Reswap'] = 'outerHTML'
|
80
|
+
return res
|
90
81
|
return render(request, 'user/change_password.html', ctx)
|
91
82
|
|
92
83
|
|
93
84
|
@login_required()
|
94
85
|
def user_change_email(request):
|
95
86
|
form = ChangeEmailForm(instance=request.user)
|
87
|
+
ctx = ui.ModalContext(
|
88
|
+
title=_('Change E-Mail'),
|
89
|
+
modal_id='change-email',
|
90
|
+
blocking=True,
|
91
|
+
extra=dict(
|
92
|
+
form=form,
|
93
|
+
user=request.user
|
94
|
+
)
|
95
|
+
).dict()
|
96
96
|
if request.method == 'POST':
|
97
97
|
form = save_form(ChangeEmailForm(request.POST, instance=request.user))
|
98
98
|
if form.is_saved:
|
99
|
-
messages.add_message(
|
100
|
-
request, messages.SUCCESS,
|
101
|
-
str(_('Your email address has been changed.')),
|
102
|
-
fail_silently=True
|
103
|
-
)
|
104
99
|
return redirect('user:detail')
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
actions=ui.form_actions(reverse('user:detail'))
|
111
|
-
).dict()
|
100
|
+
ctx.update(form=form)
|
101
|
+
res = render(request, 'user/change_email.html', ctx)
|
102
|
+
res.headers['HX-Retarget'] = f'#{ctx["modal_id"]}'
|
103
|
+
res.headers['HX-Reswap'] = 'outerHTML'
|
104
|
+
return res
|
112
105
|
return render(request, 'user/change_email.html', ctx)
|
accrete/forms.py
CHANGED
accrete/managers.py
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
from django.db import models
|
2
2
|
from accrete.tenant import get_tenant
|
3
|
-
from accrete.annotation import AnnotationManagerMixin
|
4
3
|
|
5
4
|
|
6
|
-
class TenantManager(models.Manager
|
5
|
+
class TenantManager(models.Manager):
|
7
6
|
|
8
7
|
def get_queryset(self):
|
9
8
|
queryset = super().get_queryset()
|
10
|
-
|
9
|
+
tenant = get_tenant()
|
10
|
+
if tenant:
|
11
11
|
queryset = queryset.filter(tenant=tenant)
|
12
|
-
return queryset
|
12
|
+
return queryset
|
13
13
|
|
14
14
|
def bulk_create(
|
15
15
|
self,
|
accrete/middleware.py
CHANGED
@@ -1,94 +1,69 @@
|
|
1
|
+
import logging
|
2
|
+
|
1
3
|
from django.utils.deprecation import MiddlewareMixin
|
2
|
-
from
|
3
|
-
|
4
|
-
from
|
4
|
+
from accrete.tenant import set_tenant, set_member, get_tenant
|
5
|
+
|
6
|
+
from .models import Tenant, Member
|
5
7
|
|
6
|
-
|
8
|
+
_logger = logging.getLogger(__name__)
|
7
9
|
|
8
10
|
|
9
11
|
class TenantMiddleware(MiddlewareMixin):
|
10
12
|
@staticmethod
|
11
13
|
def get_tenant_id_from_request(request):
|
12
|
-
|
13
|
-
tenant_id
|
14
|
-
|
15
|
-
|
16
|
-
elif tenant_id := request.GET.get('tenant_id'):
|
17
|
-
tenant_id = tenant_id
|
18
|
-
elif tenant := request.COOKIES.get('tenant_id'):
|
19
|
-
tenant_id = tenant
|
20
|
-
else:
|
21
|
-
tenant_id = None
|
22
|
-
|
14
|
+
tenant_id = (
|
15
|
+
request.GET.get('tenant_id')
|
16
|
+
or request.META.get('HTTP_X_TENANT_ID')
|
17
|
+
)
|
23
18
|
try:
|
24
19
|
tenant_id = int(tenant_id)
|
25
|
-
|
20
|
+
assert tenant_id > 0
|
21
|
+
except (ValueError, TypeError, AssertionError):
|
26
22
|
tenant_id = None
|
27
|
-
|
28
23
|
return tenant_id
|
29
24
|
|
30
25
|
def process_request(self, request):
|
31
26
|
request.tenant = None
|
32
27
|
request.member = None
|
28
|
+
set_member(False)
|
33
29
|
if request.path.startswith('/admin'):
|
30
|
+
return
|
31
|
+
if not request.user.is_authenticated:
|
34
32
|
set_member(None)
|
35
33
|
return
|
34
|
+
tenant_id = self.get_tenant_id_from_request(request)
|
35
|
+
tenant = Tenant.objects.none()
|
36
|
+
memberships = Member.objects.filter(
|
37
|
+
user=request.user, is_active=True, tenant__is_active=True
|
38
|
+
).prefetch_related('tenant', 'user').order_by('pk')
|
39
|
+
if tenant_id:
|
40
|
+
tenant = Tenant.objects.get(pk=tenant_id)
|
41
|
+
memberships = memberships.filter(tenant=tenant)
|
42
|
+
if memberships.count() == 1:
|
43
|
+
request.member = memberships.first()
|
44
|
+
request.tenant = request.member.tenant
|
45
|
+
set_member(request.member)
|
46
|
+
self.update_post_data(request)
|
47
|
+
return
|
48
|
+
if memberships.count() > 1:
|
49
|
+
set_member(None)
|
50
|
+
return
|
51
|
+
if request.user.is_staff and tenant:
|
52
|
+
set_member(None)
|
53
|
+
set_tenant(tenant)
|
54
|
+
request.tenant = tenant
|
55
|
+
return
|
56
|
+
set_member(None)
|
57
|
+
return
|
36
58
|
|
37
|
-
|
38
|
-
|
39
|
-
memberships = request.user.memberships.filter(
|
40
|
-
is_active=True,
|
41
|
-
tenant__is_active=True
|
42
|
-
)
|
43
|
-
|
44
|
-
if request.user.is_staff:
|
45
|
-
tenant_id = self.get_tenant_id_from_request(request)
|
46
|
-
if not tenant_id:
|
47
|
-
tenant_id = memberships and memberships.first().tenant.pk
|
48
|
-
request.tenant = tenant_id and Tenant.objects.filter(pk=tenant_id).first()
|
49
|
-
request.member = request.tenant.members.filter(user=request.user).first()
|
50
|
-
|
51
|
-
elif memberships and len(memberships) == 1:
|
52
|
-
request.member = memberships.first()
|
53
|
-
request.tenant = request.member.tenant
|
54
|
-
elif memberships and len(memberships) > 1:
|
55
|
-
tenant_id = self.get_tenant_id_from_request(request)
|
56
|
-
if not tenant_id:
|
57
|
-
tenant_id = memberships.first().tenant.pk
|
58
|
-
request.member = memberships.filter(tenant_id=tenant_id).first()
|
59
|
-
request.tenant = request.member.tenant
|
60
|
-
|
61
|
-
set_member(request.member)
|
62
|
-
if request.user.is_staff:
|
63
|
-
set_tenant(request.tenant)
|
64
|
-
|
59
|
+
@staticmethod
|
60
|
+
def update_post_data(request):
|
65
61
|
if request.POST and not request.POST.get('tenant') and request.tenant:
|
66
62
|
request.POST = request.POST.copy()
|
67
63
|
request.POST['tenant'] = request.tenant.pk
|
68
64
|
|
69
65
|
@staticmethod
|
70
66
|
def process_response(request, response):
|
71
|
-
|
72
|
-
|
73
|
-
'tenant_id',
|
74
|
-
request.tenant.pk,
|
75
|
-
samesite=settings.SESSION_COOKIE_SAMESITE,
|
76
|
-
max_age=31536000
|
77
|
-
)
|
78
|
-
return response
|
79
|
-
|
80
|
-
|
81
|
-
class HtmxRedirectMiddleware(MiddlewareMixin):
|
82
|
-
|
83
|
-
@staticmethod
|
84
|
-
def process_response(request, response):
|
85
|
-
is_htmx = request.headers.get('HX-Request', 'false') == 'true'
|
86
|
-
if not is_htmx:
|
87
|
-
return response
|
88
|
-
is_redirect = isinstance(response, HttpResponseRedirect)
|
89
|
-
is_permanent_redirect = isinstance(response, HttpResponsePermanentRedirect)
|
90
|
-
if is_redirect or is_permanent_redirect:
|
91
|
-
response.status_code = 200
|
92
|
-
header = 'HX-Location' if is_redirect else 'HX-Redirect'
|
93
|
-
response[header] = response['Location']
|
67
|
+
tenant = get_tenant()
|
68
|
+
response['X-TENANT-ID'] = tenant and tenant.id or 0
|
94
69
|
return response
|