django-unfold 0.67.0__py3-none-any.whl → 0.69.0__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.
- {django_unfold-0.67.0.dist-info → django_unfold-0.69.0.dist-info}/METADATA +33 -41
- {django_unfold-0.67.0.dist-info → django_unfold-0.69.0.dist-info}/RECORD +54 -47
- unfold/admin.py +46 -15
- unfold/components.py +2 -2
- unfold/contrib/filters/admin/choice_filters.py +13 -1
- unfold/contrib/filters/admin/mixins.py +3 -3
- unfold/contrib/filters/admin/numeric_filters.py +6 -6
- unfold/contrib/forms/widgets.py +5 -5
- unfold/contrib/inlines/admin.py +3 -3
- unfold/contrib/inlines/forms.py +5 -4
- unfold/dataclasses.py +13 -13
- unfold/datasets.py +90 -0
- unfold/decorators.py +19 -19
- unfold/fields.py +3 -5
- unfold/forms.py +41 -22
- unfold/mixins/__init__.py +2 -1
- unfold/mixins/action_model_admin.py +11 -10
- unfold/mixins/base_model_admin.py +6 -6
- unfold/mixins/dataset_model_admin.py +62 -0
- unfold/settings.py +1 -0
- unfold/sites.py +19 -18
- unfold/static/admin/js/actions.js +246 -0
- unfold/static/unfold/css/styles.css +2 -2
- unfold/static/unfold/fonts/material-symbols/Material-Symbols-Outlined.woff2 +0 -0
- unfold/static/unfold/js/app.js +3 -1
- unfold/styles.css +21 -16
- unfold/templates/admin/actions.html +2 -2
- unfold/templates/admin/change_form.html +10 -2
- unfold/templates/admin/change_list.html +1 -1
- unfold/templates/admin/change_list_results.html +10 -62
- unfold/templates/admin/dataset_actions.html +50 -0
- unfold/templates/admin/edit_inline/stacked.html +2 -8
- unfold/templates/admin/edit_inline/tabular.html +1 -7
- unfold/templates/admin/includes/fieldset.html +1 -3
- unfold/templates/admin/search_form.html +6 -4
- unfold/templates/registration/password_change_done.html +3 -4
- unfold/templates/registration/password_change_form.html +10 -6
- unfold/templates/unfold/helpers/change_list_actions.html +1 -1
- unfold/templates/unfold/helpers/change_list_headers.html +65 -0
- unfold/templates/unfold/helpers/dataset.html +31 -0
- unfold/templates/unfold/helpers/edit_inline/tabular_field.html +1 -1
- unfold/templates/unfold/helpers/empty_results.html +6 -4
- unfold/templates/unfold/helpers/field_readonly_value_file.html +1 -1
- unfold/templates/unfold/helpers/fieldsets_tabs.html +9 -11
- unfold/templates/unfold/helpers/inline_heading.html +11 -0
- unfold/templates/unfold/helpers/tab_items.html +9 -1
- unfold/templatetags/unfold.py +64 -82
- unfold/templatetags/unfold_list.py +76 -8
- unfold/typing.py +5 -6
- unfold/utils.py +9 -9
- unfold/views.py +15 -1
- unfold/widgets.py +31 -31
- {django_unfold-0.67.0.dist-info → django_unfold-0.69.0.dist-info}/WHEEL +0 -0
- {django_unfold-0.67.0.dist-info → django_unfold-0.69.0.dist-info}/licenses/LICENSE.md +0 -0
|
Binary file
|
unfold/static/unfold/js/app.js
CHANGED
|
@@ -17,7 +17,9 @@ const sortRecords = (e) => {
|
|
|
17
17
|
const orderingField = e.from.dataset.orderingField;
|
|
18
18
|
|
|
19
19
|
const weightInputs = Array.from(
|
|
20
|
-
e.from.querySelectorAll(
|
|
20
|
+
e.from.querySelectorAll(
|
|
21
|
+
`.has_original input[name$=-${orderingField}], td.field-${orderingField} input[name$=-${orderingField}]`
|
|
22
|
+
)
|
|
21
23
|
);
|
|
22
24
|
|
|
23
25
|
weightInputs.forEach((input, index) => {
|
unfold/styles.css
CHANGED
|
@@ -420,6 +420,10 @@ td .inline-deletelink {
|
|
|
420
420
|
@apply py-1;
|
|
421
421
|
}
|
|
422
422
|
|
|
423
|
+
.select2-container .select2-results__option--highlighted[aria-selected] {
|
|
424
|
+
@apply !bg-base-100 dark:!bg-base-800;
|
|
425
|
+
}
|
|
426
|
+
|
|
423
427
|
.select2-container.select2-container--open .select2-dropdown {
|
|
424
428
|
@apply bg-white border border-base-200 rounded-default shadow-xs dark:border-base-700 dark:bg-base-900;
|
|
425
429
|
}
|
|
@@ -505,13 +509,17 @@ fieldset details[open] > summary:after {
|
|
|
505
509
|
/*******************************************************
|
|
506
510
|
Calendar
|
|
507
511
|
*******************************************************/
|
|
512
|
+
.calendarbox .calendar {
|
|
513
|
+
@apply min-h-[320px];
|
|
514
|
+
}
|
|
515
|
+
|
|
508
516
|
.calendarbox,
|
|
509
517
|
.clockbox {
|
|
510
|
-
@apply bg-white border border-base-200 rounded-default shadow-xs
|
|
518
|
+
@apply bg-white border border-base-200 rounded-default shadow-xs w-80 z-50 dark:bg-base-800 dark:border-base-700 fixed! left-1/2! top-1/2! -translate-x-1/2 -translate-y-1/2;
|
|
511
519
|
}
|
|
512
520
|
|
|
513
521
|
.calendar caption {
|
|
514
|
-
@apply font-
|
|
522
|
+
@apply font-semibold mb-3 py-3 text-important;
|
|
515
523
|
}
|
|
516
524
|
|
|
517
525
|
.calendar table {
|
|
@@ -519,7 +527,7 @@ fieldset details[open] > summary:after {
|
|
|
519
527
|
}
|
|
520
528
|
|
|
521
529
|
.calendar table th {
|
|
522
|
-
@apply font-
|
|
530
|
+
@apply font-semibold text-center text-important text-xs;
|
|
523
531
|
}
|
|
524
532
|
|
|
525
533
|
.calendar table td {
|
|
@@ -527,7 +535,7 @@ fieldset details[open] > summary:after {
|
|
|
527
535
|
}
|
|
528
536
|
|
|
529
537
|
.calendar table td a {
|
|
530
|
-
@apply block flex h-8 items-center justify-center rounded-full
|
|
538
|
+
@apply block flex h-8 items-center justify-center rounded-full w-8 dark:text-base-300;
|
|
531
539
|
}
|
|
532
540
|
|
|
533
541
|
.calendar table td a:hover {
|
|
@@ -543,7 +551,7 @@ fieldset details[open] > summary:after {
|
|
|
543
551
|
}
|
|
544
552
|
|
|
545
553
|
.calendar-shortcuts a {
|
|
546
|
-
@apply border border-base-200
|
|
554
|
+
@apply border border-base-200 font-medium leading-none mx-1 px-2 py-2 rounded-default shadow-xs text-center text-base-500 text-xs w-1/3 dark:border-base-700 dark:text-base-300 ;
|
|
547
555
|
}
|
|
548
556
|
|
|
549
557
|
.calendar-cancel {
|
|
@@ -554,28 +562,25 @@ fieldset details[open] > summary:after {
|
|
|
554
562
|
@apply absolute block ml-2 mt-2 left-0 text-[0px] top-0;
|
|
555
563
|
}
|
|
556
564
|
|
|
557
|
-
.calendarnav-next
|
|
558
|
-
.calendarnav-previous
|
|
559
|
-
@apply border border-base-200 flex h-7 items-center justify-center material-symbols-outlined rounded-full
|
|
565
|
+
.calendarnav-next,
|
|
566
|
+
.calendarnav-previous {
|
|
567
|
+
@apply after:border after:border-base-200 after:flex after:h-7 after:items-center after:justify-center after:material-symbols-outlined after:rounded-full after:transition-all after:w-7 dark:after:bg-base-800 dark:after:border-base-700;
|
|
568
|
+
}
|
|
560
569
|
|
|
570
|
+
.calendarnav-previous:after {
|
|
561
571
|
content: "navigate_before";
|
|
562
572
|
display: flex;
|
|
563
573
|
}
|
|
564
574
|
|
|
565
|
-
.calendarnav-next:
|
|
566
|
-
|
|
567
|
-
|
|
575
|
+
.calendarnav-next:after {
|
|
576
|
+
content: "navigate_next";
|
|
577
|
+
display: flex;
|
|
568
578
|
}
|
|
569
579
|
|
|
570
580
|
.calendarnav-next {
|
|
571
581
|
@apply absolute block mr-2 mt-2 right-0 text-[0px] top-0;
|
|
572
582
|
}
|
|
573
583
|
|
|
574
|
-
.calendarnav-next:after {
|
|
575
|
-
content: "navigate_next";
|
|
576
|
-
display: flex;
|
|
577
|
-
}
|
|
578
|
-
|
|
579
584
|
/*******************************************************
|
|
580
585
|
Timepicker
|
|
581
586
|
*******************************************************/
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{% load i18n %}
|
|
2
2
|
|
|
3
|
-
<div id="changelist-actions" class="actions flex flex-col gap-3 text-white sm:flex-row sm:items-center lg:items-center {% if not cl.model_admin.list_fullwidth %}mx-auto{% endif %}"
|
|
3
|
+
<div id="changelist-actions" class="actions flex flex-col gap-3 text-white sm:flex-row sm:items-center lg:items-center {% if not cl.model_admin.list_fullwidth %}mx-auto{% endif %}" x-bind:style="'width: ' + changeListWidth + 'px'">
|
|
4
4
|
{% block actions %}
|
|
5
|
-
<div class="group primary flex flex-row gap-2 lg:flex-row" x-data="{action: ''}">
|
|
5
|
+
<div class="group primary flex flex-row gap-2 lg:flex-row" x-data="{action: '', selectAcross: 0}">
|
|
6
6
|
{% block actions-form %}
|
|
7
7
|
{% for field in action_form %}
|
|
8
8
|
{% if field.label %}
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
{% include adminform.model_admin.change_form_outer_before_template %}
|
|
35
35
|
{% endif %}
|
|
36
36
|
|
|
37
|
-
<form {% if adminform.model_admin.conditional_fields %}x-data='{{ adminform|changeform_data }}'{% endif %} {% if has_file_field %}enctype="multipart/form-data" {% endif %}{% if form_url %}action="{{ form_url }}"{%
|
|
37
|
+
<form {% if adminform.model_admin.conditional_fields %}x-data='{{ adminform|changeform_data }}'{% endif %} {% if has_file_field %}enctype="multipart/form-data" {% endif %}{% if form_url %}action="{{ form_url }}"{% endif %} x-bind:action="activeTab && activeTab !== 'general' ? window.location.pathname + window.location.search + '#' + activeTab : window.location.pathname + window.location.search" method="post" id="{{ opts.model_name }}_form" {% if adminform.model_admin.warn_unsaved_form %}class="warn-unsaved-form"{% endif %} novalidate>
|
|
38
38
|
{% csrf_token %}
|
|
39
39
|
|
|
40
40
|
{% if adminform.model_admin.change_form_before_template %}
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
|
|
44
44
|
{% block form_top %}{% endblock %}
|
|
45
45
|
|
|
46
|
-
<div class="flex flex-col gap-
|
|
46
|
+
<div class="flex flex-col gap-6">
|
|
47
47
|
{% if is_popup %}
|
|
48
48
|
<input type="hidden" name="{{ is_popup_var }}" value="1">
|
|
49
49
|
{% endif %}
|
|
@@ -99,6 +99,14 @@
|
|
|
99
99
|
{% endif %}
|
|
100
100
|
</form>
|
|
101
101
|
|
|
102
|
+
{% if datasets %}
|
|
103
|
+
<div class="flex flex-col">
|
|
104
|
+
{% for dataset in datasets %}
|
|
105
|
+
{{ dataset.contents }}
|
|
106
|
+
{% endfor %}
|
|
107
|
+
</div>
|
|
108
|
+
{% endif %}
|
|
109
|
+
|
|
102
110
|
{% if adminform.model_admin.change_form_outer_after_template %}
|
|
103
111
|
{% include adminform.model_admin.change_form_outer_after_template %}
|
|
104
112
|
{% endif %}
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
{% endif %}
|
|
46
46
|
|
|
47
47
|
<div class="flex -mx-4 module{% if cl.has_filters %} filtered{% endif %}" id="changelist" x-data="{ changeListWidth: 0 }">
|
|
48
|
-
<div class="changelist-form-container flex flex-row grow gap-6 min-w-0 px-4">
|
|
48
|
+
<div class="result-list-wrapper changelist-form-container flex flex-row grow gap-6 min-w-0 px-4">
|
|
49
49
|
<div class="grow min-w-0" x-resize="changeListWidth = $width">
|
|
50
50
|
{% block date_hierarchy %}
|
|
51
51
|
{% if cl.date_hierarchy %}
|
|
@@ -8,69 +8,11 @@
|
|
|
8
8
|
|
|
9
9
|
{% if results %}
|
|
10
10
|
<div class="{% if cl.search_fields or cl.has_filters %}lg:rounded-b-default{% else %}lg:rounded-default{% endif %} -mx-1 px-1 overflow-x-auto lg:border lg:border-base-200 lg:mx-0 lg:px-0 lg:shadow-xs lg:dark:border-base-800 lg:bg-white lg:dark:bg-base-900 {% if cl.model_admin.list_horizontal_scrollbar_top %}simplebar-horizontal-scrollbar-top{% endif %}" data-simplebar data-simplebar-auto-hide="false">
|
|
11
|
-
<table id="result_list" class="block border-base-200 border-spacing-none border-separate w-full lg:table">
|
|
12
|
-
|
|
13
|
-
<tr>
|
|
14
|
-
{% if cl.model_admin.list_sections|length > 0 %}
|
|
15
|
-
<th></th>
|
|
16
|
-
{% endif %}
|
|
17
|
-
|
|
18
|
-
{% for header in result_headers %}
|
|
19
|
-
<th class="align-middle font-semibold py-2 text-left text-font-important-light dark:text-font-important-dark whitespace-nowrap {{ header.class_attrib }} {% if "action-toggle" in header.text and forloop.counter == 1 %}lg:px-3 lg:w-10{% else %}hidden px-3 lg:table-cell{% endif %}" scope="col">
|
|
20
|
-
<div class="flex items-center">
|
|
21
|
-
<div class="text">
|
|
22
|
-
{% if header.sortable %}
|
|
23
|
-
<a href="{{ header.url_primary }}">
|
|
24
|
-
{{ header.text|capfirst }}
|
|
25
|
-
</a>
|
|
26
|
-
{% else %}
|
|
27
|
-
{% if "action-toggle" in header.text and forloop.counter == 1 %}
|
|
28
|
-
<label class="flex flex-row items-center gap-2">
|
|
29
|
-
{{ header.text|capfirst }}
|
|
30
|
-
|
|
31
|
-
<span class="block font-normal lg:hidden">
|
|
32
|
-
{% trans "Select all rows"%}
|
|
33
|
-
</span>
|
|
34
|
-
</label>
|
|
35
|
-
{% else %}
|
|
36
|
-
<span>
|
|
37
|
-
{{ header.text|capfirst }}
|
|
38
|
-
</span>
|
|
39
|
-
{% endif %}
|
|
40
|
-
{% endif %}
|
|
41
|
-
</div>
|
|
42
|
-
|
|
43
|
-
{% if header.sortable %}
|
|
44
|
-
{% if header.sort_priority > 0 %}
|
|
45
|
-
<div class="sortoptions flex items-center ml-2">
|
|
46
|
-
<a href="{{ header.url_toggle }}" class="flex items-center leading-none text-base-400 hover:text-base-500 dark:text-base-500 dark:hover:text-base-400 toggle {% if header.ascending %}ascending{% else %}descending{% endif %}" title="{% translate "Toggle sorting" %}">
|
|
47
|
-
{% if header.ascending %}
|
|
48
|
-
<span class="block material-symbols-outlined">arrow_circle_down</span>
|
|
49
|
-
{% else %}
|
|
50
|
-
<span class="block material-symbols-outlined">arrow_circle_up</span>
|
|
51
|
-
{% endif %}
|
|
52
|
-
</a>
|
|
53
|
-
|
|
54
|
-
<a class="sortremove flex items-center leading-none ml-1 text-base-400 dark:text-base-500 transition-all hover:text-red-700 dark:hover:text-red-500" href="{{ header.url_remove }}" title="{% translate "Remove from sorting" %}">
|
|
55
|
-
<span class="block material-symbols-outlined">cancel</span>
|
|
56
|
-
</a>
|
|
57
|
-
</div>
|
|
58
|
-
|
|
59
|
-
{% if num_sorted_fields > 1 %}
|
|
60
|
-
<span class="sortpriority font-medium ml-2 text-xs" title="{% blocktranslate with priority_number=header.sort_priority %}Sorting priority: {{ priority_number }}{% endblocktranslate %}">
|
|
61
|
-
{{ header.sort_priority }}
|
|
62
|
-
</span>
|
|
63
|
-
{% endif %}
|
|
64
|
-
{% endif %}
|
|
65
|
-
{% endif %}
|
|
66
|
-
</div>
|
|
67
|
-
</th>
|
|
68
|
-
{% endfor %}
|
|
69
|
-
</tr>
|
|
70
|
-
</thead>
|
|
11
|
+
<table id="result_list" class="result-list block border-base-200 border-spacing-none border-separate w-full lg:table" {% if cl.model_admin.ordering_field %}x-sort.ghost x-on:end="sortRecords"{% endif %} data-ordering-field="{{ cl.model_admin.ordering_field }}">
|
|
12
|
+
{% include 'unfold/helpers/change_list_headers.html' %}
|
|
71
13
|
|
|
72
14
|
{% for result in results %}
|
|
73
|
-
<tbody class="block relative lg:table-row-group lg:hover:shadow-raised lg:dark:hover:shadow-raised-dark lg:hover:z-20 {% cycle '' 'bg-base-50 dark:bg-white/[.02]' %}" x-data="{rowOpen: false}">
|
|
15
|
+
<tbody class="block relative lg:table-row-group lg:hover:shadow-raised lg:dark:hover:shadow-raised-dark lg:hover:z-20 {% cycle '' 'bg-base-50 dark:bg-white/[.02]' %}" x-data="{rowOpen: false}" {% if cl.model_admin.ordering_field %}x-sort:item{% endif %}>
|
|
74
16
|
{% if result.form and result.form.non_field_errors %}
|
|
75
17
|
<tr>
|
|
76
18
|
<td class="text-left" colspan="{{ result|length }}">
|
|
@@ -80,6 +22,12 @@
|
|
|
80
22
|
{% endif %}
|
|
81
23
|
|
|
82
24
|
<tr class="block border border-base-200 mb-3 relative rounded-default shadow-xs lg:table-row lg:border-none lg:mb-0 lg:rounded-none lg:shadow-none dark:border-base-800">
|
|
25
|
+
{% if cl.model_admin.ordering_field %}
|
|
26
|
+
<td class="align-middle cursor-move flex border-b border-base-200 font-normal px-2.5 py-2 relative text-left before:font-semibold before:text-font-important-light before:block before:capitalize before:content-[attr(data-label)] before:mr-auto lg:before:hidden lg:border-b-0 lg:border-t lg:pl-3 lg:pr-0 lg:py-3 lg:table-cell dark:border-base-800 dark:lg:border-base-800 dark:before:text-font-important-dark lg:w-px" x-sort:handle>
|
|
27
|
+
<span class="material-symbols-outlined align-middle cursor-move">drag_indicator</span>
|
|
28
|
+
</td>
|
|
29
|
+
{% endif %}
|
|
30
|
+
|
|
83
31
|
{% if cl.model_admin.list_sections|length > 0 %}
|
|
84
32
|
<td class="align-middle cursor-pointer flex border-b border-base-200 font-normal px-2.5 py-2 relative text-left before:font-semibold before:text-font-important-light before:block before:capitalize before:content-[attr(data-label)] before:mr-auto lg:before:hidden lg:border-b-0 lg:border-t lg:pl-3 lg:pr-0 lg:py-3 lg:table-cell dark:border-base-800 dark:lg:border-base-800 dark:before:text-font-important-dark lg:w-px"
|
|
85
33
|
data-label="{% trans "Expand row" %}"
|
|
@@ -100,7 +48,7 @@
|
|
|
100
48
|
|
|
101
49
|
{% if cl.model_admin.list_sections|length > 0 %}
|
|
102
50
|
<tr class="block mb-3 relative z-30 lg:table-row" x-show="rowOpen">
|
|
103
|
-
<td colspan="
|
|
51
|
+
<td colspan="100%" class="border bg-base-200/10 block border-base-200 relative rounded-default p-3 lg:shadow-inner lg:border-0 lg:border-t lg:rounded-none lg:table-cell dark:border-base-800">
|
|
104
52
|
<div class="absolute bg-primary-600 h-full hidden left-0 top-0 w-0.5 lg:block"></div>
|
|
105
53
|
|
|
106
54
|
<div class="grid gap-3 {{ cl.model_admin.list_sections_classes }}">
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{% load i18n %}
|
|
2
|
+
|
|
3
|
+
<div class="actions flex flex-col gap-3 order-last lg:order-none lg:flex-row lg:items-center">
|
|
4
|
+
{% if actions_selection_counter %}
|
|
5
|
+
<div class="bg-base-100 flex flex-row h-9.5 items-center px-3 rounded-md shadow-sm truncate dark:bg-white/[.04] lg:bg-transparent dark:lg:!bg-transparent lg:px-0 lg:shadow-none">
|
|
6
|
+
<span class="action-counter text-sm" data-actions-icnt="{{ cl.result_list|length }}">
|
|
7
|
+
{{ selection_note }}
|
|
8
|
+
</span>
|
|
9
|
+
|
|
10
|
+
{% if cl.result_count != cl.result_list|length %}
|
|
11
|
+
<span class="all hidden">
|
|
12
|
+
{{ selection_note_all }}
|
|
13
|
+
</span>
|
|
14
|
+
|
|
15
|
+
{% if not cl.model_admin.list_disable_select_all %}
|
|
16
|
+
<span class="question ml-2 hidden text-primary-600 dark:text-primary-500">
|
|
17
|
+
<a href="#" title="{% translate "Click here to select the objects across all pages" %}">
|
|
18
|
+
{% blocktranslate with cl.result_count as total_count %}Select all {{ total_count }} {{ module_name }}{% endblocktranslate %}
|
|
19
|
+
</a>
|
|
20
|
+
</span>
|
|
21
|
+
|
|
22
|
+
<span class="clear hidden text-red-600">
|
|
23
|
+
<a href="#">
|
|
24
|
+
{% translate "Clear selection" %}
|
|
25
|
+
</a>
|
|
26
|
+
</span>
|
|
27
|
+
{% endif %}
|
|
28
|
+
{% endif %}
|
|
29
|
+
</div>
|
|
30
|
+
{% endif %}
|
|
31
|
+
|
|
32
|
+
<div class="flex flex-col gap-2 lg:flex-row">
|
|
33
|
+
{% for field in action_form %}
|
|
34
|
+
{% if field.label %}
|
|
35
|
+
<label>
|
|
36
|
+
{{ field.label }}
|
|
37
|
+
{% endif %}
|
|
38
|
+
|
|
39
|
+
{{ field }}
|
|
40
|
+
|
|
41
|
+
{% if field.label %}
|
|
42
|
+
</label>
|
|
43
|
+
{% endif %}
|
|
44
|
+
{% endfor %}
|
|
45
|
+
|
|
46
|
+
<button type="submit" form="dataset-{{ id }}" x-show="action" class="bg-primary-600 cursor-pointer flex font-medium items-center justify-center px-3 py-2 rounded-md text-sm text-white whitespace-nowrap" title="{% translate "Run the selected action" %}" name="index" value="{{ action_index|default:0 }}">
|
|
47
|
+
{% trans "Run" %}
|
|
48
|
+
</button>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
@@ -4,13 +4,7 @@
|
|
|
4
4
|
<fieldset class="module relative {{ inline_admin_formset.classes }}" aria-labelledby="{{ inline_admin_formset.formset.prefix }}-heading">
|
|
5
5
|
{% if inline_admin_formset.is_collapsible %}<details><summary>{% endif %}
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
{% if inline_admin_formset.formset.max_num == 1 %}
|
|
9
|
-
{{ inline_admin_formset.opts.verbose_name|capfirst }}
|
|
10
|
-
{% else %}
|
|
11
|
-
{{ inline_admin_formset.opts.verbose_name_plural|capfirst }}
|
|
12
|
-
{% endif %}
|
|
13
|
-
</h2>
|
|
7
|
+
{% include "unfold/helpers/inline_heading.html" %}
|
|
14
8
|
|
|
15
9
|
{% if inline_admin_formset.is_collapsible %}</summary>{% endif %}
|
|
16
10
|
|
|
@@ -34,7 +28,7 @@
|
|
|
34
28
|
|
|
35
29
|
{% if inline_admin_formset.opts.ordering_field %}
|
|
36
30
|
{% if inline_admin_form.original %}
|
|
37
|
-
<span class="material-symbols-outlined cursor-
|
|
31
|
+
<span class="material-symbols-outlined cursor-move" x-sort:handle>drag_indicator</span>
|
|
38
32
|
{% else %}
|
|
39
33
|
<span class="-mr-2" x-sort:handle></span>
|
|
40
34
|
{% endif %}
|
|
@@ -7,13 +7,7 @@
|
|
|
7
7
|
<fieldset class="module relative {{ inline_admin_formset.classes }} min-w-0" aria-labelledby="{{ inline_admin_formset.formset.prefix }}-heading">
|
|
8
8
|
{% if inline_admin_formset.is_collapsible %}<details><summary>{% endif %}
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
{% if inline_admin_formset.formset.max_num == 1 %}
|
|
12
|
-
{{ inline_admin_formset.opts.verbose_name|capfirst }}
|
|
13
|
-
{% else %}
|
|
14
|
-
{{ inline_admin_formset.opts.verbose_name_plural|capfirst }}
|
|
15
|
-
{% endif %}
|
|
16
|
-
</h2>
|
|
10
|
+
{% include "unfold/helpers/inline_heading.html" %}
|
|
17
11
|
|
|
18
12
|
{% if inline_admin_formset.is_collapsible %}</summary>{% endif %}
|
|
19
13
|
|
|
@@ -9,9 +9,7 @@
|
|
|
9
9
|
{{ fieldset.name }}
|
|
10
10
|
</h2>
|
|
11
11
|
{% else %}
|
|
12
|
-
|
|
13
|
-
{{ fieldset.name }}
|
|
14
|
-
</h2>
|
|
12
|
+
{% include "unfold/helpers/inline_heading.html" with title=fieldset.name clickable=fieldset.is_collapsible %}
|
|
15
13
|
{% endif %}
|
|
16
14
|
{% endif %}
|
|
17
15
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
{% if cl.search_fields %}
|
|
4
4
|
<div id="toolbar">
|
|
5
|
-
<form id="changelist-search" method="get" role="search"
|
|
5
|
+
<form {% if not cl.is_dataset %}id="changelist-search" x-data="searchForm()"{% endif %} method="get" role="search">
|
|
6
6
|
<div class="bg-white border border-base-200 flex flex-row items-center px-3 rounded-default relative shadow-xs w-full focus-within:outline-2 focus-within:-outline-offset-2 focus-within:outline-primary-600 lg:w-96 dark:bg-base-900 dark:border-base-700">
|
|
7
7
|
<button type="submit" class="flex items-center focus:outline-hidden" id="searchbar-submit">
|
|
8
8
|
<span class="material-symbols-outlined md-18 text-base-400 dark:text-base-500">search</span>
|
|
@@ -10,14 +10,16 @@
|
|
|
10
10
|
|
|
11
11
|
<input type="text"
|
|
12
12
|
x-ref="searchInput"
|
|
13
|
-
x-on:keydown.window="applyShortcut($event)"
|
|
13
|
+
{% if not cl.is_dataset %}x-on:keydown.window="applyShortcut($event)"{% endif %}
|
|
14
14
|
class="grow font-medium min-w-0 overflow-hidden p-2 placeholder-font-subtle-light truncate focus:outline-hidden dark:bg-base-900 dark:placeholder-font-subtle-dark dark:text-font-default-dark"
|
|
15
15
|
name="{{ search_var }}"
|
|
16
16
|
value="{{ cl.query }}"
|
|
17
|
-
id="searchbar"
|
|
17
|
+
{% if not cl.is_dataset %}id="searchbar"{% endif %}
|
|
18
18
|
placeholder="{% if cl.search_help_text %}{{ cl.search_help_text }}{% else %}{% trans "Type to search" %}{% endif %}" />
|
|
19
19
|
|
|
20
|
-
{%
|
|
20
|
+
{% if not cl.is_dataset %}
|
|
21
|
+
{% include "unfold/helpers/shortcut.html" with shortcut="/" %}
|
|
22
|
+
{% endif %}
|
|
21
23
|
</div>
|
|
22
24
|
|
|
23
25
|
{% for pair in cl.filter_params.items %}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
{% extends "admin/base_site.html" %}
|
|
2
2
|
{% load admin_urls i18n static %}
|
|
3
3
|
|
|
4
|
-
{% block extrastyle %}{{ block.super }}
|
|
4
|
+
{% block extrastyle %}{{ block.super }}{% endblock %}
|
|
5
5
|
|
|
6
6
|
{% block content %}
|
|
7
7
|
<div id="content-main">
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
</p>
|
|
8
|
+
{% translate 'Your password was changed.' as message %}
|
|
9
|
+
{% include "unfold/helpers/messages/success.html" with message=message %}
|
|
11
10
|
</div>
|
|
12
11
|
{% endblock %}
|
|
@@ -19,15 +19,19 @@
|
|
|
19
19
|
|
|
20
20
|
{% include "unfold/helpers/messages/info.html" with message=message %}
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
<fieldset class="fieldset group border border-base-200 mb-6 rounded-default shadow-xs p-3 dark:border-base-800 *:last:mb-0">
|
|
23
|
+
{% include "unfold/helpers/field.html" with field=form.old_password %}
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
{% include "unfold/helpers/field.html" with field=form.new_password1 %}
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
{% include "unfold/helpers/field.html" with field=form.new_password2 %}
|
|
28
|
+
</fieldset>
|
|
27
29
|
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
<div class="flex justify-end">
|
|
31
|
+
<button type="submit" class="bg-primary-600 border border-transparent font-medium px-3 py-2 rounded-default text-sm text-white">
|
|
32
|
+
{% translate 'Change password' %}
|
|
33
|
+
</button>
|
|
34
|
+
</div>
|
|
31
35
|
</div>
|
|
32
36
|
</form>
|
|
33
37
|
</div>
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
{% if actions_on_top %}
|
|
4
4
|
{% if cl.search_fields or action_form or cl.has_filters %}
|
|
5
5
|
<div class="bottom-0 left-0 right-0 hidden bg-primary-600 group-has-[input.action-select:checked]:flex fixed gap-3 lg:h-[64px] items-center p-3 z-50 lg:flex-row dark:bg-primary-500">
|
|
6
|
-
<div id="changelist-actions-wrapper" class="grow" {% if not is_popup %}x-bind:class="{'xl:ml-0': !sidebarDesktopOpen, 'xl:ml-72': sidebarDesktopOpen}"{% endif %}>
|
|
6
|
+
<div id="changelist-actions-wrapper" class="grow group changelist-actions" {% if not is_popup %}x-bind:class="{'xl:ml-0': !sidebarDesktopOpen, 'xl:ml-72': sidebarDesktopOpen}"{% endif %}>
|
|
7
7
|
{% if action_form %}
|
|
8
8
|
{% admin_actions %}
|
|
9
9
|
{% endif %}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{% load i18n %}
|
|
2
|
+
|
|
3
|
+
<thead>
|
|
4
|
+
<tr>
|
|
5
|
+
{% if cl.model_admin.ordering_field %}
|
|
6
|
+
<th></th>
|
|
7
|
+
{% endif %}
|
|
8
|
+
|
|
9
|
+
{% if cl.model_admin.list_sections|length > 0 %}
|
|
10
|
+
<th></th>
|
|
11
|
+
{% endif %}
|
|
12
|
+
|
|
13
|
+
{% for header in result_headers %}
|
|
14
|
+
<th class="align-middle font-semibold py-2 text-left text-font-important-light dark:text-font-important-dark whitespace-nowrap {{ header.class_attrib }} {% if "action-toggle" in header.text and forloop.counter == 1 %}lg:px-3 lg:w-10{% else %}hidden px-3 lg:table-cell{% endif %}" scope="col">
|
|
15
|
+
<div class="flex items-center">
|
|
16
|
+
<div class="text">
|
|
17
|
+
{% if header.sortable %}
|
|
18
|
+
<a href="{{ header.url_primary }}">
|
|
19
|
+
{{ header.text|capfirst }}
|
|
20
|
+
</a>
|
|
21
|
+
{% else %}
|
|
22
|
+
{% if "action-toggle" in header.text and forloop.counter == 1 %}
|
|
23
|
+
<label class="flex flex-row items-center gap-2">
|
|
24
|
+
{{ header.text|capfirst }}
|
|
25
|
+
|
|
26
|
+
<span class="block font-normal lg:hidden">
|
|
27
|
+
{% trans "Select all rows"%}
|
|
28
|
+
</span>
|
|
29
|
+
</label>
|
|
30
|
+
{% else %}
|
|
31
|
+
<span>
|
|
32
|
+
{{ header.text|capfirst }}
|
|
33
|
+
</span>
|
|
34
|
+
{% endif %}
|
|
35
|
+
{% endif %}
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
{% if header.sortable %}
|
|
39
|
+
{% if header.sort_priority > 0 %}
|
|
40
|
+
<div class="sortoptions flex items-center ml-2">
|
|
41
|
+
<a href="{{ header.url_toggle }}" class="flex items-center leading-none text-base-400 hover:text-base-500 dark:text-base-500 dark:hover:text-base-400 toggle {% if header.ascending %}ascending{% else %}descending{% endif %}" title="{% translate "Toggle sorting" %}">
|
|
42
|
+
{% if header.ascending %}
|
|
43
|
+
<span class="block material-symbols-outlined">arrow_circle_down</span>
|
|
44
|
+
{% else %}
|
|
45
|
+
<span class="block material-symbols-outlined">arrow_circle_up</span>
|
|
46
|
+
{% endif %}
|
|
47
|
+
</a>
|
|
48
|
+
|
|
49
|
+
<a class="sortremove flex items-center leading-none ml-1 text-base-400 dark:text-base-500 transition-all hover:text-red-700 dark:hover:text-red-500" href="{{ header.url_remove }}" title="{% translate "Remove from sorting" %}">
|
|
50
|
+
<span class="block material-symbols-outlined">cancel</span>
|
|
51
|
+
</a>
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
{% if num_sorted_fields > 1 %}
|
|
55
|
+
<span class="sortpriority font-medium ml-2 text-xs" title="{% blocktranslate with priority_number=header.sort_priority %}Sorting priority: {{ priority_number }}{% endblocktranslate %}">
|
|
56
|
+
{{ header.sort_priority }}
|
|
57
|
+
</span>
|
|
58
|
+
{% endif %}
|
|
59
|
+
{% endif %}
|
|
60
|
+
{% endif %}
|
|
61
|
+
</div>
|
|
62
|
+
</th>
|
|
63
|
+
{% endfor %}
|
|
64
|
+
</tr>
|
|
65
|
+
</thead>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{% load admin_list unfold_list %}
|
|
2
|
+
|
|
3
|
+
<div class="result-list-wrapper {% if not tab %}mt-6{% endif %}" x-data="{action: '', selectAcross: '0'}" {% if tab %}x-show="activeTab == 'dataset-{{ dataset.model_name }}'"{% else %}x-show="activeTab == 'general'"{% endif %}>
|
|
4
|
+
{% if not tab %}
|
|
5
|
+
{% include "unfold/helpers/inline_heading.html" with title=dataset.model_verbose_name %}
|
|
6
|
+
{% endif %}
|
|
7
|
+
|
|
8
|
+
{% if cl.search_fields %}
|
|
9
|
+
<div class="flex flex-col gap-4 justify-between mb-4 sm:flex-row empty:hidden lg:border lg:border-base-200 lg:dark:border-base-800 lg:-mb-8 lg:p-3 lg:pb-11 lg:rounded-t-default">
|
|
10
|
+
{% unfold_search_form cl %}
|
|
11
|
+
|
|
12
|
+
{% unfold_admin_actions %}
|
|
13
|
+
</div>
|
|
14
|
+
{% endif %}
|
|
15
|
+
|
|
16
|
+
<form id="dataset-{{ id }}" class="group" method="post"{% if cl.formset and cl.formset.is_multipart %} enctype="multipart/form-data"{% endif %} novalidate>
|
|
17
|
+
{% csrf_token %}
|
|
18
|
+
|
|
19
|
+
<input type="hidden" name="dataset" value="{{ id }}">
|
|
20
|
+
<input type="hidden" name="action" x-model="action">
|
|
21
|
+
<input type="hidden" name="select_across" x-model="selectAcross">
|
|
22
|
+
|
|
23
|
+
{% if cl.formset %}
|
|
24
|
+
{{ cl.formset.management_form }}
|
|
25
|
+
{% endif %}
|
|
26
|
+
|
|
27
|
+
{% unfold_result_list cl %}
|
|
28
|
+
</form>
|
|
29
|
+
|
|
30
|
+
{% pagination cl %}
|
|
31
|
+
</div>
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
{% if forloop.parentloop.counter == 1 and forloop.counter == 1 %}
|
|
3
3
|
{% if inline_admin_formset.opts.ordering_field %}
|
|
4
4
|
{% if inline_admin_form.original %}
|
|
5
|
-
<span class="material-symbols-outlined cursor-
|
|
5
|
+
<span class="material-symbols-outlined cursor-move" x-sort:handle>drag_indicator</span>
|
|
6
6
|
{% else %}
|
|
7
7
|
<span class="-mr-3" x-sort:handle></span>
|
|
8
8
|
{% endif %}
|
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
{% url cl.opts|admin_urlname:"add" as add_url %}
|
|
4
4
|
{% blocktranslate with name=cl.opts.verbose_name asvar title %}Add {{ name }}{% endblocktranslate %}
|
|
5
5
|
|
|
6
|
-
<div class="bg-white border border-base-200 flex flex-col items-center px-8
|
|
7
|
-
|
|
8
|
-
<
|
|
9
|
-
|
|
6
|
+
<div class="bg-white border border-base-200 flex flex-col items-center px-8 shadow-xs dark:bg-base-900 dark:border-base-800 {% if cl.search_fields %}rounded-b-default{% else %}rounded-default{% endif %} {% if cl.is_dataset %}py-16{% else %}py-24{% endif %}">
|
|
7
|
+
{% if not cl.is_dataset %}
|
|
8
|
+
<div class="border border-base-300 border-dashed flex h-24 items-center justify-center mb-8 rounded-full w-24 dark:border-base-700">
|
|
9
|
+
<span class="material-symbols-outlined text-base-500 text-5xl! dark:text-base-400">inbox</span>
|
|
10
|
+
</div>
|
|
11
|
+
{% endif %}
|
|
10
12
|
|
|
11
13
|
<h2 class="font-semibold mb-1 text-xl text-font-important-light tracking-tight dark:text-font-important-dark">
|
|
12
14
|
{% trans "No results found" %}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
{% with url=field.url %}
|
|
4
4
|
{% if not url %}
|
|
5
|
-
<span class="flex items-center"
|
|
5
|
+
<span class="flex items-center">-</span>
|
|
6
6
|
{% elif field.is_image %}
|
|
7
7
|
<a href="{{ url }}" target="_blank" class="block max-w-48">
|
|
8
8
|
<img src="{{ url }}" alt="{% trans 'Image preview' %}" class="block rounded-default" />
|
|
@@ -2,23 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
{% with tabs=adminform|tabs %}
|
|
4
4
|
{% if tabs %}
|
|
5
|
-
<div x-data="{openTab: null}" x-show="activeTab == 'general'">
|
|
6
|
-
<
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
<a
|
|
10
|
-
x-on:click="openTab = '{{ forloop.counter0 }}-{{ fieldset.name|slugify }}'"
|
|
11
|
-
x-bind:class="openTab == '{{ forloop.counter0 }}-{{ fieldset.name|slugify }}'{% if forloop.first %} || openTab == null{% endif %} ? 'bg-white text-font-important-light shadow-xs dark:bg-base-900 dark:text-font-important-dark' : ''">
|
|
5
|
+
<div class="{% fieldset_rows_classes %}" x-data="{openTab: null}" x-show="activeTab == 'general'">
|
|
6
|
+
<div class="{% if adminform.model_admin.compressed_fields %}border-b border-base-200 border-dashed dark:border-base-800{% endif %}">
|
|
7
|
+
<nav class="bg-base-100 cursor-pointer flex flex-col font-medium gap-1 m-2 p-1 rounded-default text-important dark:border-base-700 md:inline-flex md:flex-row md:w-auto dark:bg-white/[.04] *:flex-inline *:flex-row *:items-center *:px-2.5 *:py-[5px] *:rounded-default *:transition-colors *:hover:bg-base-700/[.04] *:dark:hover:bg-white/[.04] [&>.active]:bg-white [&>.active]:shadow-xs [&>.active]:hover:bg-white [&>.active]:dark:bg-base-900 [&>.active]:dark:hover:bg-base-900">
|
|
8
|
+
{% for fieldset in tabs %}
|
|
9
|
+
<a x-on:click="openTab = '{{ forloop.counter0 }}-{{ fieldset.name|slugify }}'" x-bind:class="openTab == '{{ forloop.counter0 }}-{{ fieldset.name|slugify }}'{% if forloop.first %} || openTab == null{% endif %} ? 'active' : ''">
|
|
12
10
|
{{ fieldset.name }}
|
|
13
11
|
</a>
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
</
|
|
12
|
+
{% endfor %}
|
|
13
|
+
</nav>
|
|
14
|
+
</div>
|
|
17
15
|
|
|
18
16
|
{% for fieldset in tabs %}
|
|
19
17
|
<div class="tab-wrapper{% if fieldset.name %} fieldset-{{ fieldset.name|slugify }} fieldset-{{ forloop.counter0 }}-{{ fieldset.name|slugify }}{% endif %}"
|
|
20
18
|
x-show="openTab == '{{ forloop.counter0 }}-{{ fieldset.name|slugify }}'{% if forloop.first %} || openTab == null{% endif %}">
|
|
21
|
-
{% include 'admin/includes/fieldset.html' %}
|
|
19
|
+
{% include 'admin/includes/fieldset.html' with stacked=1 %}
|
|
22
20
|
</div>
|
|
23
21
|
{% endfor %}
|
|
24
22
|
</div>
|