django-unfold 0.41.0__py3-none-any.whl → 0.43.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.
Files changed (63) hide show
  1. {django_unfold-0.41.0.dist-info → django_unfold-0.43.0.dist-info}/METADATA +1 -1
  2. {django_unfold-0.41.0.dist-info → django_unfold-0.43.0.dist-info}/RECORD +63 -55
  3. unfold/admin.py +8 -1
  4. unfold/components.py +47 -0
  5. unfold/contrib/filters/admin.py +23 -33
  6. unfold/contrib/guardian/templates/admin/guardian/model/obj_perms_manage.html +1 -1
  7. unfold/contrib/guardian/templates/admin/guardian/model/obj_perms_manage_group.html +1 -1
  8. unfold/contrib/guardian/templates/admin/guardian/model/obj_perms_manage_user.html +1 -1
  9. unfold/contrib/import_export/templates/admin/import_export/export.html +1 -1
  10. unfold/contrib/import_export/templates/admin/import_export/import.html +1 -1
  11. unfold/contrib/import_export/templates/admin/import_export/import_validation.html +26 -21
  12. unfold/contrib/import_export/templates/admin/import_export/resource_fields_list.html +5 -3
  13. unfold/contrib/simple_history/templates/simple_history/object_history_form.html +1 -1
  14. unfold/contrib/simple_history/templates/simple_history/submit_line.html +1 -1
  15. unfold/settings.py +1 -0
  16. unfold/sites.py +25 -5
  17. unfold/static/unfold/css/styles.css +1 -1
  18. unfold/static/unfold/js/app.js +21 -15
  19. unfold/styles.css +14 -1
  20. unfold/templates/admin/base.html +3 -3
  21. unfold/templates/admin/change_form.html +9 -1
  22. unfold/templates/admin/change_list.html +1 -1
  23. unfold/templates/admin/date_hierarchy.html +5 -5
  24. unfold/templates/admin/delete_confirmation.html +1 -1
  25. unfold/templates/admin/delete_selected_confirmation.html +1 -1
  26. unfold/templates/admin/edit_inline/stacked.html +8 -2
  27. unfold/templates/admin/edit_inline/tabular.html +8 -2
  28. unfold/templates/admin/nav_sidebar.html +1 -10
  29. unfold/templates/admin/object_history.html +1 -1
  30. unfold/templates/admin/submit_line.html +2 -2
  31. unfold/templates/unfold/change_list_filter.html +5 -13
  32. unfold/templates/unfold/components/card.html +1 -1
  33. unfold/templates/unfold/components/chart/cohort.html +59 -0
  34. unfold/templates/unfold/components/navigation.html +1 -1
  35. unfold/templates/unfold/components/tracker.html +5 -0
  36. unfold/templates/unfold/helpers/account_links.html +1 -1
  37. unfold/templates/unfold/helpers/actions_row.html +9 -7
  38. unfold/templates/unfold/helpers/field_readonly.html +1 -1
  39. unfold/templates/unfold/helpers/form_label.html +1 -1
  40. unfold/templates/unfold/helpers/header.html +1 -1
  41. unfold/templates/unfold/helpers/label.html +1 -1
  42. unfold/templates/unfold/helpers/language_switch.html +27 -0
  43. unfold/templates/unfold/helpers/messages/debug.html +3 -0
  44. unfold/templates/unfold/helpers/messages/error.html +5 -3
  45. unfold/templates/unfold/helpers/messages/info.html +2 -2
  46. unfold/templates/unfold/helpers/messages/success.html +3 -0
  47. unfold/templates/unfold/helpers/messages/warning.html +3 -0
  48. unfold/templates/unfold/helpers/messages.html +13 -14
  49. unfold/templates/unfold/helpers/tab_list.html +3 -3
  50. unfold/templates/unfold/helpers/theme_switch.html +1 -1
  51. unfold/templates/unfold/helpers/userlinks.html +4 -0
  52. unfold/templates/unfold/helpers/welcomemsg.html +9 -1
  53. unfold/templates/unfold/layouts/base_simple.html +1 -1
  54. unfold/templates/unfold/layouts/skeleton.html +1 -1
  55. unfold/templates/unfold/templatetags/preserve_changelist_filters.html +3 -0
  56. unfold/templates/unfold/widgets/clearable_file_input.html +1 -1
  57. unfold/templates/unfold/widgets/clearable_file_input_small.html +1 -1
  58. unfold/templates/unfold/widgets/split_datetime_vertical.html +1 -1
  59. unfold/templatetags/unfold.py +55 -9
  60. unfold/utils.py +17 -0
  61. unfold/widgets.py +6 -2
  62. {django_unfold-0.41.0.dist-info → django_unfold-0.43.0.dist-info}/LICENSE.md +0 -0
  63. {django_unfold-0.41.0.dist-info → django_unfold-0.43.0.dist-info}/WHEEL +0 -0
@@ -135,27 +135,33 @@ const dateTimeShortcutsOverlay = () => {
135
135
  * File upload path
136
136
  *************************************************************/
137
137
  const fileInputUpdatePath = () => {
138
- const observer = new MutationObserver((mutations) => {
139
- for (const mutation of mutations) {
140
- if (mutation.type === "childList") {
141
- for (const input of document.querySelectorAll("input[type=file]")) {
142
- input.addEventListener("change", (e) => {
143
- const parts = e.target.value.split("\\");
144
- const placeholder =
145
- input.parentNode.parentNode.parentNode.querySelector(
146
- "input[type=text]"
147
- );
148
- placeholder.setAttribute("value", parts[parts.length - 1]);
149
- });
150
- }
138
+ const checkInputChanged = () => {
139
+ for (const input of document.querySelectorAll("input[type=file]")) {
140
+ if (input.hasChangeListener) {
141
+ continue;
151
142
  }
143
+
144
+ input.addEventListener("change", (e) => {
145
+ const parts = e.target.value.split("\\");
146
+ const placeholder =
147
+ input.parentNode.parentNode.parentNode.querySelector(
148
+ "input[type=text]"
149
+ );
150
+ placeholder.setAttribute("value", parts[parts.length - 1]);
151
+ });
152
+
153
+ input.hasChangeListener = true;
152
154
  }
153
- });
155
+ };
154
156
 
155
- observer.observe(document.body, {
157
+ new MutationObserver(() => {
158
+ checkInputChanged();
159
+ }).observe(document.body, {
156
160
  childList: true,
157
161
  subtree: true,
158
162
  });
163
+
164
+ checkInputChanged();
159
165
  };
160
166
 
161
167
  /*************************************************************
unfold/styles.css CHANGED
@@ -443,7 +443,7 @@ h3 span:nth-child(3) {
443
443
  }
444
444
 
445
445
  /*******************************************************
446
- Collapsed
446
+ Fieldset collapsible
447
447
  *******************************************************/
448
448
  fieldset.collapsed > div {
449
449
  display: none;
@@ -462,6 +462,19 @@ fieldset.collapsed .collapse-toggle {
462
462
  @apply inline;
463
463
  }
464
464
 
465
+ fieldset details > summary {
466
+ @apply list-none
467
+ }
468
+
469
+ fieldset details > summary:after {
470
+ @apply material-symbols-outlined absolute right-3 top-3.5;
471
+ content: "expand_more";
472
+ }
473
+
474
+ fieldset details[open] > summary:after {
475
+ @apply rotate-180;
476
+ }
477
+
465
478
  /*******************************************************
466
479
  Calendar
467
480
  *******************************************************/
@@ -16,7 +16,7 @@
16
16
  {% if not is_popup %}
17
17
  {% spaceless %}
18
18
  {% block breadcrumbs %}
19
- <div class="px-4 lg:px-12">
19
+ <div class="px-4 lg:px-8">
20
20
  <div class="container mb-12 mx-auto -my-3">
21
21
  <ul class="flex flex-wrap">
22
22
  {% url 'admin:index' as link %}
@@ -31,14 +31,14 @@
31
31
  {% endif %}
32
32
 
33
33
  {% block messages %}
34
- <div class="px-4 lg:px-12">
34
+ <div class="px-4 lg:px-8">
35
35
  <div class="{% if not cl.model_admin.list_fullwidth %}container{% endif %} mx-auto">
36
36
  {% include "unfold/helpers/messages.html" %}
37
37
  </div>
38
38
  </div>
39
39
  {% endblock messages %}
40
40
 
41
- <div class="px-4 pb-12 lg:px-12">
41
+ <div class="px-4 pb-8 lg:px-8">
42
42
  <div id="content" class="{% if not cl.model_admin.list_fullwidth %}container{% endif %} mx-auto {% block coltype %}colM{% endblock %}">
43
43
  {% if cl %}
44
44
  {% tab_list "changelist" cl.opts %}
@@ -11,7 +11,7 @@
11
11
 
12
12
  {% if not is_popup %}
13
13
  {% block breadcrumbs %}
14
- <div class="px-4 lg:px-12">
14
+ <div class="px-4 lg:px-8">
15
15
  <div class="container mb-6 mx-auto -my-3 lg:mb-12">
16
16
  <ul class="flex flex-wrap">
17
17
  {% url 'admin:index' as link %}
@@ -61,6 +61,10 @@
61
61
  <div id="content-main">
62
62
  {% block form_before %}{% endblock %}
63
63
 
64
+ {% if adminform.model_admin.change_form_outer_before_template %}
65
+ {% include adminform.model_admin.change_form_outer_before_template %}
66
+ {% endif %}
67
+
64
68
  <form {% if has_file_field %}enctype="multipart/form-data" {% endif %}{% if form_url %}action="{{ form_url }}" {% endif %}method="post" id="{{ opts.model_name }}_form" {% if adminform.model_admin.warn_unsaved_form %}class="warn-unsaved-form"{% endif %} novalidate>
65
69
  {% csrf_token %}
66
70
 
@@ -116,6 +120,10 @@
116
120
  </div>
117
121
  </form>
118
122
 
123
+ {% if adminform.model_admin.change_form_outer_after_template %}
124
+ {% include adminform.model_admin.change_form_outer_after_template %}
125
+ {% endif %}
126
+
119
127
  {% block form_after %}{% endblock %}
120
128
  </div>
121
129
  {% endblock %}
@@ -24,7 +24,7 @@
24
24
 
25
25
  {% if not is_popup %}
26
26
  {% block breadcrumbs %}
27
- <div class="px-4 lg:px-12">
27
+ <div class="px-4 lg:px-8">
28
28
  <div class="{% if not cl.model_admin.list_fullwidth %}container{% endif %} mb-6 mx-auto -my-3 lg:mb-12">
29
29
  <ul class="flex flex-wrap">
30
30
  {% url 'admin:index' as link %}
@@ -1,12 +1,12 @@
1
1
  {% if show %}
2
- <div class="xfull mb-4">
3
- <ul class="toplinks flex -mx-2 text-gray-500 text-sm">
2
+ <div class="mb-4">
3
+ <ul class="toplinks flex -mx-2 text-sm">
4
4
  {% block date-hierarchy-toplinks %}
5
5
  {% block date-hierarchy-back %}
6
6
  {% if back %}
7
7
  <li class="date-back px-2">
8
- <a href="{{ back.link }}" class="flex items-center hover:text-primary-600">
9
- <span class="material-symbols-outlined md-16 mr-2 text-gray-400">arrow_back</span> {{ back.title }}
8
+ <a href="{{ back.link }}" class="flex group items-center hover:text-primary-600 dark:hover:text-primary-500">
9
+ <span class="material-symbols-outlined md-16 mr-2 text-gray-400 group-hover:text-primary-600 dark:group-hover:text-primary-500">arrow_back</span> {{ back.title }}
10
10
  </a>
11
11
  </li>
12
12
  {% endif %}
@@ -16,7 +16,7 @@
16
16
  {% for choice in choices %}
17
17
  <li class="px-2">
18
18
  {% if choice.link %}
19
- <a href="{{ choice.link }}" class="hover:text-primary-600">
19
+ <a href="{{ choice.link }}" class="hover:text-primary-600 dark:hover:text-primary-500">
20
20
  {% endif %}
21
21
 
22
22
  {{ choice.title }}
@@ -10,7 +10,7 @@
10
10
  {% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} delete-confirmation{% endblock %}
11
11
 
12
12
  {% block breadcrumbs %}
13
- <div class="px-4 lg:px-12">
13
+ <div class="px-4 lg:px-8">
14
14
  <div class="container mb-6 mx-auto -my-3 lg:mb-12">
15
15
  <ul class="flex flex-wrap">
16
16
  {% url 'admin:index' as link %}
@@ -10,7 +10,7 @@
10
10
  {% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} delete-confirmation delete-selected-confirmation{% endblock %}
11
11
 
12
12
  {% block breadcrumbs %}
13
- <div class="px-4 lg:px-12">
13
+ <div class="px-4 lg:px-8">
14
14
  <div class="container mb-6 mx-auto -my-3 lg:mb-12">
15
15
  <ul class="flex flex-wrap">
16
16
  {% url 'admin:index' as link %}
@@ -1,8 +1,10 @@
1
1
  {% load admin_urls i18n unfold %}
2
2
 
3
3
  <div class="js-inline-admin-formset inline-group" id="{{ inline_admin_formset.formset.prefix }}-group" data-inline-type="stacked" data-inline-formset="{{ inline_admin_formset.inline_formset_data }}" {% if inline_admin_formset.opts.tab %}x-show="activeTab == '{{ inline_admin_formset.opts.verbose_name|slugify }}'"{% else %}x-show="activeTab == 'general'"{% endif %}>
4
- <fieldset class="module {{ inline_admin_formset.classes }}">
5
- <h2 class="bg-gray-100 border border-transparent font-semibold mb-6 px-4 py-3 rounded-md text-font-important-light text-sm lg:-mx-4 dark:bg-white/[.02] dark:border dark:border-gray-800 dark:text-font-important-dark {% if inline_admin_formset.opts.tab %}hidden{% endif %}">
4
+ <fieldset class="module relative {{ inline_admin_formset.classes }}" aria-labelledby="{{ inline_admin_formset.formset.prefix }}-heading">
5
+ {% if inline_admin_formset.is_collapsible %}<details><summary>{% endif %}
6
+
7
+ <h2 id="{{ inline_admin_formset.formset.prefix }}-heading" class="inline-heading bg-gray-100 border border-transparent font-semibold mb-6 px-4 py-3 rounded-md text-font-important-light text-sm lg:-mx-4 dark:bg-white/[.02] dark:border dark:border-gray-800 dark:text-font-important-dark {% if inline_admin_formset.opts.tab %}hidden{% endif %} {% if inline_admin_formset.is_collapsible %} cursor-pointer{% endif %}">
6
8
  {% if inline_admin_formset.formset.max_num == 1 %}
7
9
  {{ inline_admin_formset.opts.verbose_name|capfirst }}
8
10
  {% else %}
@@ -10,6 +12,8 @@
10
12
  {% endif %}
11
13
  </h2>
12
14
 
15
+ {% if inline_admin_formset.is_collapsible %}</summary>{% endif %}
16
+
13
17
  {{ inline_admin_formset.formset.management_form }}
14
18
  {% include "unfold/helpers/messages/error.html" with errors=inline_admin_formset.formset.non_form_errors %}
15
19
 
@@ -92,5 +96,7 @@
92
96
  </div>
93
97
  {% endfor %}
94
98
  </div>
99
+
100
+ {% if inline_admin_formset.is_collapsible %}</details>{% endif %}
95
101
  </fieldset>
96
102
  </div>
@@ -4,8 +4,10 @@
4
4
  <div class="tabular inline-related {% if forloop.last %}last-related{% endif %}">
5
5
  {{ inline_admin_formset.formset.management_form }}
6
6
 
7
- <fieldset class="module {{ inline_admin_formset.classes }} min-w-0">
8
- <h2 class="bg-gray-100 border border-transparent font-semibold mb-6 px-4 py-3 rounded-md text-font-important-light text-sm lg:-mx-4 dark:bg-white/[.02] dark:border dark:border-gray-800 dark:text-font-important-dark {% if inline_admin_formset.opts.tab %}hidden{% endif %}">
7
+ <fieldset class="module relative {{ inline_admin_formset.classes }} min-w-0" aria-labelledby="{{ inline_admin_formset.formset.prefix }}-heading">
8
+ {% if inline_admin_formset.is_collapsible %}<details><summary>{% endif %}
9
+
10
+ <h2 id="{{ inline_admin_formset.formset.prefix }}-heading" class="bg-gray-100 border border-transparent font-semibold mb-6 px-4 py-3 rounded-md text-font-important-light text-sm lg:-mx-4 dark:bg-white/[.02] dark:border dark:border-gray-800 dark:text-font-important-dark {% if inline_admin_formset.opts.tab %}hidden{% endif %} {% if inline_admin_formset.is_collapsible %} cursor-pointer{% endif %}">
9
11
  {% if inline_admin_formset.formset.max_num == 1 %}
10
12
  {{ inline_admin_formset.opts.verbose_name|capfirst }}
11
13
  {% else %}
@@ -13,6 +15,8 @@
13
15
  {% endif %}
14
16
  </h2>
15
17
 
18
+ {% if inline_admin_formset.is_collapsible %}</summary>{% endif %}
19
+
16
20
  {{ inline_admin_formset.formset.non_form_errors }}
17
21
 
18
22
  <div class="border border-gray-200 mb-6 overflow-x-auto rounded-md shadow-sm dark:border-gray-800" data-simplebar data-simplebar-auto-hide="false">
@@ -173,6 +177,8 @@
173
177
  {% endfor %}
174
178
  </table>
175
179
  </div>
180
+
181
+ {% if inline_admin_formset.is_collapsible %}</details>{% endif %}
176
182
  </fieldset>
177
183
  </div>
178
184
  </div>
@@ -1,22 +1,13 @@
1
1
  {% load i18n %}
2
2
 
3
3
  <div class="relative z-50">
4
- <div @click="sidebarDesktopOpen = !sidebarDesktopOpen"
5
- hx-get="{% url "admin:toggle_sidebar" %}"
6
- hx-swap="none"
7
- class="bg-white border cursor-pointer fixed h-6 hidden items-center justify-center rounded-full text-gray-500 top-5 -translate-x-1/2 w-6 z-50 xl:flex dark:bg-gray-800 dark:border-gray-700 dark:text-gray-200"
8
- :class="{'ml-6 rotate-180': !sidebarDesktopOpen, 'ml-72': sidebarDesktopOpen}">
9
- <span class="material-symbols-outlined md-16">
10
- first_page
11
- </span>
12
- </div>
13
-
14
4
  <div @click="sidebarMobileOpen = !sidebarMobileOpen"
15
5
  class="fixed bottom-0 bg-gray-700 cursor-pointer flex items-center left-0 mb-2 ml-2 justify-center px-2 py-1 rounded-full shadow-sm text-xs text-white uppercase z-50 xl:hidden"
16
6
  :class="{'ml-72 -translate-x-1/2': sidebarMobileOpen}">
17
7
  {% trans "Menu" %}
18
8
  </div>
19
9
 
10
+
20
11
  <div :class="{'xl:block': sidebarDesktopOpen, 'xl:hidden': !sidebarDesktopOpen, 'max-xl:fixed': sidebarMobileOpen, 'hidden': !sidebarMobileOpen }">
21
12
  {% include "unfold/helpers/navigation.html" %}
22
13
  </div>
@@ -2,7 +2,7 @@
2
2
  {% load i18n admin_urls %}
3
3
 
4
4
  {% block breadcrumbs %}
5
- <div class="px-4 lg:px-12">
5
+ <div class="px-4 lg:px-8">
6
6
  <div class="container mb-12 mx-auto -my-3">
7
7
  <ul class="flex flex-wrap">
8
8
  {% url 'admin:index' as link %}
@@ -1,8 +1,8 @@
1
1
  {% load i18n admin_urls %}
2
2
 
3
- <div {% if not is_popup %}id="submit-row"{% endif %} class="relative z-20 {% if not is_popup %} mt-8{% endif %}">
3
+ <div {% if not is_popup %}id="submit-row"{% endif %} class="relative mt-16 z-20">
4
4
  <div class="{% if not is_popup %}lg:bottom-0 lg:fixed lg:left-0 lg:right-0{% endif %}" {% if not is_popup %}x-bind:class="{'xl:left-0': !sidebarDesktopOpen, 'xl:left-72': sidebarDesktopOpen}"{% endif %}>
5
- <div class="bg-white dark:bg-gray-900 {% if not is_popup %}lg:border-t lg:py-4 relative scrollable-top lg:px-12 dark:border-gray-800{% endif %}">
5
+ <div class="bg-white dark:bg-gray-900 {% if not is_popup %}lg:border-t lg:py-4 relative scrollable-top lg:px-8 dark:border-gray-800{% endif %}">
6
6
  <div class="container flex flex-col-reverse gap-3 items-center mx-auto lg:flex-row-reverse">
7
7
  {% block submit-row %}
8
8
  {% if show_save %}
@@ -1,4 +1,4 @@
1
- {% load i18n admin_list %}
1
+ {% load i18n admin_list unfold %}
2
2
 
3
3
  <div id="changelist-filter" class="backdrop-blur-sm bg-opacity-80 bg-gray-900 flex inset-0 z-50 fixed {% if not cl.model_admin.list_filter_sheet %}2xl:bg-transparent 2xl:relative 2xl:!block 2xl:z-10{% endif %}" x-show="filterOpen">
4
4
  <label for="show-filters" id="changelist-filter-close" class="flex-grow {% if not cl.model_admin.list_filter_sheet %}2xl:hidden{% endif %}" x-on:click="filterOpen = false"></label>
@@ -38,13 +38,7 @@
38
38
  <div class="px-4{% if cl.model_admin.list_filter_submit %} {% endif %}">
39
39
  {% if cl.model_admin.list_filter_submit %}
40
40
  <form id="filter-form" method="get">
41
- {% if request.GET.q %}
42
- <input type="hidden" name="q" value="{{ request.GET.q }}">
43
- {% endif %}
44
-
45
- {% if request.GET.o %}
46
- <input type="hidden" name="o" value="{{ request.GET.o }}">
47
- {% endif %}
41
+ {% preserve_filters %}
48
42
  {% endif %}
49
43
 
50
44
  {% for spec in cl.filter_specs %}
@@ -52,11 +46,9 @@
52
46
  {% endfor %}
53
47
 
54
48
  {% if cl.model_admin.list_filter_submit %}
55
- <div class="bottom-4 absolute left-4 right-4 {% if not cl.model_admin.list_filter_sheet %}2xl:left-0 2xl:right-0 2xl:relative 2xl:mt-8{% endif %}">
56
- <button type="submit" class="bg-primary-600 block border border-transparent font-medium px-3 py-2 rounded-md self-end text-sm text-white w-full">
57
- {% trans "Apply Filters" %}
58
- </button>
59
- </div>
49
+ <button type="submit" class="bg-primary-600 block border border-transparent font-medium mb-4 mt-8 px-3 py-2 rounded-md self-end text-sm text-white w-full">
50
+ {% trans "Apply Filters" %}
51
+ </button>
60
52
  </form>
61
53
  {% endif %}
62
54
  </div>
@@ -1,6 +1,6 @@
1
1
  <div class="border flex flex-col flex-grow overflow-hidden p-6 relative rounded-md shadow-sm dark:border-gray-800 {% if class %} {{ class }}{% endif %}">
2
2
  {% if title %}
3
- <h2 class="border-b font-semibold mb-6 -mt-2 -mx-6 pb-4 px-6 text-font-important-light dark:text-font-important-dark dark:border-gray-800">
3
+ <h2 class="bg-gray-50 border-b font-semibold mb-6 -mt-6 -mx-6 py-4 px-6 text-font-important-light dark:text-font-important-dark dark:border-gray-800 dark:bg-white/[.02]">
4
4
  {{ title }}
5
5
  </h2>
6
6
  {% endif %}
@@ -0,0 +1,59 @@
1
+ <div class="overflow-auto w-full" data-simplebar>
2
+ <table class="w-full">
3
+ <thead>
4
+ <tr>
5
+ <th></th>
6
+
7
+ {% for header in data.headers %}
8
+ <th class="font-normal px-3 pb-2.5 text-left ">
9
+ <div class="font-semibold text-font-important-light truncate dark:text-font-important-dark">
10
+ {{ header.title }}
11
+ </div>
12
+
13
+ {% if header.subtitle %}
14
+ <div class="mt-0.5 text-xs truncate">
15
+ {{ header.subtitle }}
16
+ </div>
17
+ {% endif %}
18
+ </th>
19
+ {% endfor %}
20
+ </tr>
21
+ </thead>
22
+
23
+ <tbody>
24
+ {% for row in data.rows %}
25
+ <tr class="h-full">
26
+ <td>
27
+ <div class="pr-3 py-2.5">
28
+ <div class="font-semibold text-font-important-light dark:text-font-important-dark">
29
+ {{ row.header.title }}
30
+ </div>
31
+
32
+ {% if row.header.subtitle %}
33
+ <div class="mt-0.5 text-xs">
34
+ {{ row.header.subtitle }}
35
+ </div>
36
+ {% endif %}
37
+ </div>
38
+ </td>
39
+
40
+ {% for col in row.cols %}
41
+ <td class="h-full">
42
+ <div class="flex flex-col h-full justify-center px-3 py-2.5 rounded-md {% if col.color %}{{ col.color }}{% else %}bg-gray-50 border border-dashed dark:bg-gray-800 dark:border-gray-700{% endif %}">
43
+ <span>
44
+ {{ col.value }}
45
+ </span>
46
+
47
+ {% if col.subtitle %}
48
+ <span class="mt-0.5">
49
+ {{ col.subtitle }}
50
+ </span>
51
+ {% endif %}
52
+ </div>
53
+ </td>
54
+ {% endfor %}
55
+ </tr>
56
+ {% endfor %}
57
+ </tbody>
58
+ </table>
59
+ </div>
@@ -1,5 +1,5 @@
1
1
  {% if items %}
2
- <nav class="bg-gray-100 flex gap-2 mb-8 p-1 rounded text-sm dark:bg-white/[.04]{% if class %} {{ class }}{% endif %}">
2
+ <nav class="bg-gray-100 flex gap-2 p-1 rounded text-sm dark:bg-white/[.04]{% if class %} {{ class }}{% endif %}">
3
3
  {% for item in items %}
4
4
  <a href="{{ item.link }}" class="flex flex-row font-medium items-center px-2.5 py-1 rounded {% if item.active %} bg-white shadow-sm text-font-important-light hover:bg-white dark:bg-gray-900 dark:hover:bg-gray-900 dark:text-font-important-dark{% else %}text-font-subtle-light dark:text-font-subtle-dark hover:bg-gray-700/[.04] dark:hover:bg-white/[.04]{% endif %}">
5
5
  {% if item.icon %}
@@ -0,0 +1,5 @@
1
+ <ul class="flex flex-row gap-0.5 overflow-hidden rounded">
2
+ {% for item in data %}
3
+ <li class="h-8 px-px size-full {% if item.color %}{{ item.color }}{% else %}bg-gray-300 dark:bg-gray-400{% endif %} hover:opacity-50" title="{{ item.tooltip }}"></li>
4
+ {% endfor %}
5
+ </ul>
@@ -5,7 +5,7 @@
5
5
  <span class="material-symbols-outlined">person</span>
6
6
  </a>
7
7
 
8
- <nav class="absolute bg-white border flex flex-col leading-none overflow-hidden py-1 -right-2 rounded shadow-lg top-7 w-52 z-50 dark:bg-gray-800 dark:border-gray-700" x-cloak x-show="openUserLinks" @click.outside="openUserLinks = false">
8
+ <nav class="absolute bg-white border flex flex-col leading-none py-1 -right-2 rounded shadow-lg top-7 w-52 z-50 dark:bg-gray-800 dark:border-gray-700" x-cloak x-show="openUserLinks" @click.outside="openUserLinks = false">
9
9
  <div class="border-b border-gray-100 flex flex-row flex-shrink-0 items-start justify-start mb-1 pb-1 dark:border-gray-700">
10
10
  <span class="block mx-1 px-3 py-2 truncate">
11
11
  {% firstof user.get_short_name user.get_username %}
@@ -8,13 +8,15 @@
8
8
  more_horiz
9
9
  </span>
10
10
 
11
- <nav x-anchor.offset.4="$refs.rowDropdown{{ action_id }}" class="bg-white border flex flex-col leading-none py-1 rounded-md shadow-lg text-sm top-7 z-50 w-48 dark:bg-gray-800 dark:border-gray-700" x-cloak x-show="openActionsId{{ action_id }}" @click.outside="openActionsId{{ action_id }} = false">
12
- {% for action in actions %}
13
- <a href="{% url action.raw_path instance_pk %}" class="mx-1 px-3 py-2 rounded-md truncate hover:bg-gray-100 dark:hover:bg-gray-700 dark:hover:text-gray-200"{% for attr_name, attr_value in action.attrs.items %} {{ attr_name }}="{{ attr_value }}"{% endfor %}>
14
- {{ action.title }}
15
- </a>
16
- {% endfor %}
17
- </nav>
11
+ <template x-teleport="body">
12
+ <nav x-anchor.bottom-end.offset.4="$refs.rowDropdown{{ action_id }}" class="bg-white border flex flex-col leading-none py-1 rounded-md shadow-lg text-sm top-7 z-50 w-48 dark:bg-gray-800 dark:border-gray-700" x-cloak x-show="openActionsId{{ action_id }}" @click.outside="openActionsId{{ action_id }} = false">
13
+ {% for action in actions %}
14
+ <a href="{% url action.raw_path instance_pk %}" class="mx-1 px-3 py-2 rounded-md truncate hover:bg-gray-100 dark:hover:bg-gray-700 dark:hover:text-gray-200"{% for attr_name, attr_value in action.attrs.items %} {{ attr_name }}="{{ attr_value }}"{% endfor %}>
15
+ {{ action.title }}
16
+ </a>
17
+ {% endfor %}
18
+ </nav>
19
+ </template>
18
20
  </div>
19
21
  {% endwith %}
20
22
  </td>
@@ -1,5 +1,5 @@
1
1
  <div class="flex group mb-6 flex-col last:mb-4">
2
- <label class="block font-medium mb-2 text-gray-900 text-sm dark:text-gray-200">
2
+ <label class="block font-semibold mb-2 text-gray-900 text-sm dark:text-gray-200">
3
3
  {{ title }}
4
4
  </label>
5
5
 
@@ -1,4 +1,4 @@
1
- <label for="{{ field.id_for_label }}" class="block text-font-important-light dark:text-font-important-dark{% if field.field.widget.input_type == "checkbox" %}{% else %} font-medium mb-2{% endif %}">
1
+ <label for="{{ field.id_for_label }}" class="block text-font-important-light dark:text-font-important-dark{% if field.field.widget.input_type == "checkbox" %}{% else %} font-semibold mb-2{% endif %}">
2
2
  {{ field.label }}
3
3
 
4
4
  {% if field.field.required %}
@@ -1,6 +1,6 @@
1
1
  {% if not is_popup %}
2
2
  {% block header %}
3
- <div class="border-b border-gray-200 mb-6 px-4 lg:px-12 dark:border-gray-800">
3
+ <div class="border-b border-gray-200 mb-6 px-4 lg:px-8 dark:border-gray-800">
4
4
  <div class="{% if not cl.model_admin.list_fullwidth %}container{% endif %} flex items-center h-16 mx-auto py-4">
5
5
  <div id="header-inner" class="flex items-center w-full">
6
6
  <div class="flex items-center w-full">
@@ -10,7 +10,7 @@
10
10
  {% elif type == 'primary' %}
11
11
  bg-primary-100 text-primary-700 dark:bg-primary-500/20 dark:text-primary-400
12
12
  {% else %}
13
- bg-gray-100 text-gray-700 dark:bg-gray-500/20 dark:text-gray-400
13
+ bg-gray-100 text-gray-700 dark:bg-gray-500/20 dark:text-gray-200
14
14
  {% endif %}">
15
15
  {{ text }}
16
16
  </span>
@@ -0,0 +1,27 @@
1
+ {% load i18n %}
2
+
3
+ {% get_current_language as LANGUAGE_CODE %}
4
+ {% get_available_languages as LANGUAGES %}
5
+ {% get_language_info_list for LANGUAGES as languages %}
6
+
7
+
8
+ <div class="relative" x-data="{ openLanguageLinks: false }">
9
+ <a class="block cursor-pointer hover:text-gray-700 dark:hover:text-gray-200" x-on:click="openLanguageLinks = !openLanguageLinks">
10
+ <span class="material-symbols-outlined">translate</span>
11
+ </a>
12
+
13
+ <div class="absolute bg-white border flex flex-col leading-none py-1 -right-2 rounded shadow-lg top-7 w-52 z-50 dark:bg-gray-800 dark:border-gray-700" x-cloak x-show="openLanguageLinks" @click.outside="openLanguageLinks = false">
14
+ {% for language in languages %}
15
+ <form action="{% url 'set_language' %}" method="post" class="flex w-full">
16
+ {% csrf_token %}
17
+
18
+ <input name="next" type="hidden" value="{{ redirect_to }}">
19
+ <input name="language" type="hidden" value="{{ language.code }}">
20
+
21
+ <button type="submit" class="block flex-grow mx-1 px-3 py-2 rounded text-left hover:bg-gray-100 hover:text-gray-700 dark:hover:bg-gray-700 dark:hover:text-gray-200 {% if language.code == LANGUAGE_CODE %}text-primary-600 dark:text-primary-500 dark:hover:!text-primary-500 hover:!text-primary-600{% endif %}">
22
+ {{ language.name_local }} ({{ language.code }})
23
+ </button>
24
+ </form>
25
+ {% endfor %}
26
+ </div>
27
+ </div>
@@ -0,0 +1,3 @@
1
+ <p class="mb-3 px-3 py-3 rounded-md text-sm last:mb-8 bg-gray-100 text-gray-700 dark:bg-gray-500/20 dark:text-gray-400">
2
+ {{ message }}
3
+ </p>
@@ -1,13 +1,15 @@
1
1
  {% load i18n %}
2
2
 
3
- {% if errors or error %}
4
- <p class="errornote bg-red-100 mb-8 text-red-600 px-3 py-3 rounded-md text-sm dark:bg-red-500/20 dark:border-red-500/20 dark:text-red-500 group-[.inline-tabular]:mb-0 group-[.inline-tabular]:mt-3 group-[.inline-tabular]:mx-3 group-[.inline-stacked]:mb-3 group-[.inline-stacked]:mt-3 group-[.inline-stacked]:mx-3">
3
+ {% if errors or error or message %}
4
+ <div class="errornote mb-3 px-3 py-3 rounded-md group-[.inline-tabular]:mb-0 group-[.inline-tabular]:mt-3 group-[.inline-tabular]:mx-3 group-[.inline-stacked]:mb-3 group-[.inline-stacked]:mt-3 group-[.inline-stacked]:mx-3 bg-red-100 text-red-700 dark:bg-red-500/20 dark:text-red-400">
5
5
  {% if error %}
6
6
  {{ error }}
7
+ {% elif message %}
8
+ {{ message }}
7
9
  {% else %}
8
10
  {% for error in errors %}
9
11
  {{ error }}
10
12
  {% endfor %}
11
13
  {% endif %}
12
- </p>
14
+ </div>
13
15
  {% endif %}
@@ -1,3 +1,3 @@
1
- <p class="bg-blue-50 mb-8 text-blue-500 px-3 py-3 rounded-md text-sm dark:bg-blue-500/20 dark:border-blue-500/10">
2
- {{ message|safe }}
1
+ <p class="mb-3 px-3 py-3 rounded-md text-sm last:mb-8 bg-blue-100 text-blue-700 dark:bg-blue-500/20 dark:text-blue-400">
2
+ {{ message }}
3
3
  </p>
@@ -0,0 +1,3 @@
1
+ <p class="mb-3 px-3 py-3 rounded-md text-sm last:mb-8 bg-green-100 text-green-700 dark:bg-green-500/20 dark:text-green-400">
2
+ {{ message }}
3
+ </p>
@@ -0,0 +1,3 @@
1
+ <p class="mb-3 px-3 py-3 rounded-md text-sm last:mb-8 bg-orange-100 text-orange-700 dark:bg-orange-500/20 dark:text-orange-400">
2
+ {{ message }}
3
+ </p>
@@ -1,19 +1,18 @@
1
1
  {% if messages %}
2
- <ul>
2
+ <ul class="flex flex-col gap-4 mb-8">
3
3
  {% for message in messages %}
4
- <li class="{{ message.tags }} mb-3 px-3 py-3 rounded-md text-sm last:mb-8
5
- {% if message.tags == 'success' %}
6
- bg-green-100 text-green-700 dark:bg-green-500/20 dark:text-green-400
7
- {% elif message.tags == 'warning' %}
8
- bg-orange-100 text-orange-700 dark:bg-orange-500/20 dark:text-orange-400
9
- {% elif message.tags == 'error' %}
10
- bg-red-100 text-red-700 dark:bg-red-500/20 dark:text-red-400
11
- {% elif message.tags == 'info' %}
12
- bg-blue-100 text-blue-700 dark:bg-blue-500/20 dark:text-blue-400
13
- {% else %}
14
- bg-gray-100 text-gray-700 dark:bg-gray-500/20 dark:text-gray-400
15
- {% endif %}">
16
- {{ message|capfirst }}
4
+ <li class="*:!mb-0">
5
+ {% if message.tags == 'info' %}
6
+ {% include "unfold/helpers/messages/info.html" with message=message %}
7
+ {% elif message.tags == 'success' %}
8
+ {% include "unfold/helpers/messages/success.html" with message=message %}
9
+ {% elif message.tags == 'warning' %}
10
+ {% include "unfold/helpers/messages/warning.html" with message=message %}
11
+ {% elif message.tags == 'error' %}
12
+ {% include "unfold/helpers/messages/error.html" with message=message %}
13
+ {% else %}
14
+ {% include "unfold/helpers/messages/debug.html" with message=message %}
15
+ {% endif %}
17
16
  </li>
18
17
  {% endfor %}
19
18
  </ul>