django-unfold 0.64.2__py3-none-any.whl → 0.66.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 (34) hide show
  1. {django_unfold-0.64.2.dist-info → django_unfold-0.66.0.dist-info}/METADATA +4 -2
  2. {django_unfold-0.64.2.dist-info → django_unfold-0.66.0.dist-info}/RECORD +34 -33
  3. {django_unfold-0.64.2.dist-info → django_unfold-0.66.0.dist-info}/WHEEL +1 -1
  4. unfold/admin.py +15 -16
  5. unfold/contrib/constance/settings.py +1 -0
  6. unfold/contrib/constance/templates/admin/constance/change_list.html +18 -18
  7. unfold/contrib/constance/templates/admin/constance/includes/results_list.html +13 -11
  8. unfold/contrib/location_field/templates/location_field/map_widget.html +1 -1
  9. unfold/dataclasses.py +1 -0
  10. unfold/mixins/base_model_admin.py +1 -1
  11. unfold/sites.py +45 -18
  12. unfold/static/unfold/css/styles.css +1 -1
  13. unfold/static/unfold/js/app.js +56 -11
  14. unfold/styles.css +24 -10
  15. unfold/templates/admin/change_form.html +6 -2
  16. unfold/templates/admin/nav_sidebar.html +1 -1
  17. unfold/templates/unfold/components/button.html +1 -1
  18. unfold/templates/unfold/components/card.html +3 -3
  19. unfold/templates/unfold/components/layer.html +1 -0
  20. unfold/templates/unfold/components/progress.html +8 -8
  21. unfold/templates/unfold/components/tracker.html +1 -1
  22. unfold/templates/unfold/helpers/app_list.html +1 -1
  23. unfold/templates/unfold/helpers/boolean.html +1 -1
  24. unfold/templates/unfold/helpers/command.html +1 -1
  25. unfold/templates/unfold/helpers/command_results.html +31 -12
  26. unfold/templates/unfold/helpers/header_back_button.html +1 -1
  27. unfold/templates/unfold/helpers/pagination_infinite.html +1 -1
  28. unfold/templates/unfold/helpers/search.html +1 -0
  29. unfold/templates/unfold/helpers/site_dropdown.html +1 -1
  30. unfold/templates/unfold/widgets/clearable_file_input_small.html +1 -1
  31. unfold/templatetags/unfold.py +72 -22
  32. unfold/views.py +2 -0
  33. unfold/widgets.py +5 -3
  34. {django_unfold-0.64.2.dist-info → django_unfold-0.66.0.dist-info/licenses}/LICENSE.md +0 -0
@@ -68,7 +68,7 @@ function searchDropdown() {
68
68
  }
69
69
  },
70
70
  prevItem() {
71
- if (this.currentIndex > 0) {
71
+ if (this.currentIndex > 1) {
72
72
  this.currentIndex--;
73
73
  }
74
74
  },
@@ -93,6 +93,7 @@ function searchCommand() {
93
93
  hasResults: false,
94
94
  openCommandResults: false,
95
95
  currentIndex: 0,
96
+ totalItems: 0,
96
97
  commandHistory: JSON.parse(localStorage.getItem("commandHistory") || "[]"),
97
98
  handleOpen() {
98
99
  this.openCommandResults = true;
@@ -102,6 +103,7 @@ function searchCommand() {
102
103
  }, 20);
103
104
 
104
105
  this.items = document.querySelectorAll("#command-history li");
106
+ this.totalItems = this.items.length;
105
107
  },
106
108
  handleShortcut(event) {
107
109
  if (
@@ -121,21 +123,46 @@ function searchCommand() {
121
123
  this.openCommandResults = false;
122
124
  this.el.innerHTML = "";
123
125
  this.items = undefined;
126
+ this.totalItems = 0;
124
127
  this.currentIndex = 0;
125
128
  } else {
126
129
  this.$refs.searchInputCommand.value = "";
127
130
  }
128
131
  },
129
132
  handleContentLoaded(event) {
130
- this.items = event.target.querySelectorAll("li");
131
- this.currentIndex = 0;
132
- this.hasResults = this.items.length > 0;
133
+ if (
134
+ event.target.id !== "command-results" &&
135
+ event.target.id !== "command-results-list"
136
+ ) {
137
+ return;
138
+ }
139
+
140
+ const commandResultsList = document.getElementById(
141
+ "command-results-list"
142
+ );
143
+ if (commandResultsList) {
144
+ this.items = commandResultsList.querySelectorAll("li");
145
+ this.totalItems = this.items.length;
146
+ } else {
147
+ this.items = undefined;
148
+ this.totalItems = 0;
149
+ }
150
+
151
+ if (event.target.id === "command-results") {
152
+ this.currentIndex = 0;
153
+
154
+ if (this.items) {
155
+ this.totalItems = this.items.length;
156
+ } else {
157
+ this.totalItems = 0;
158
+ }
159
+ }
160
+
161
+ this.hasResults = this.totalItems > 0;
133
162
 
134
163
  if (!this.hasResults) {
135
164
  this.items = document.querySelectorAll("#command-history li");
136
165
  }
137
-
138
- new SimpleBar(event.target);
139
166
  },
140
167
  handleOutsideClick() {
141
168
  this.$refs.searchInputCommand.value = "";
@@ -158,7 +185,7 @@ function searchCommand() {
158
185
  }
159
186
  },
160
187
  nextItem() {
161
- if (this.currentIndex < this.items.length) {
188
+ if (this.currentIndex < this.totalItems) {
162
189
  this.currentIndex++;
163
190
  this.scrollToActiveItem();
164
191
  }
@@ -417,6 +444,11 @@ const DEFAULT_CHART_OPTIONS = {
417
444
  ticks: {
418
445
  color: "#9ca3af",
419
446
  display: true,
447
+ maxTicksLimit: function (context) {
448
+ return context.chart.data.datasets.find(
449
+ (dataset) => dataset.maxTicksXLimit
450
+ )?.maxTicksXLimit;
451
+ },
420
452
  },
421
453
  grid: {
422
454
  display: true,
@@ -430,9 +462,22 @@ const DEFAULT_CHART_OPTIONS = {
430
462
  width: 0,
431
463
  },
432
464
  ticks: {
433
- display: false,
434
- font: {
435
- size: 13,
465
+ color: "#9ca3af",
466
+ display: function (context) {
467
+ return context.chart.data.datasets.some((dataset) => {
468
+ return (
469
+ dataset.hasOwnProperty("displayYAxis") && dataset.displayYAxis
470
+ );
471
+ });
472
+ },
473
+ callback: function (value) {
474
+ const suffix = this.chart.data.datasets.find(
475
+ (dataset) => dataset.suffixYAxis
476
+ )?.suffixYAxis;
477
+ if (suffix) {
478
+ return `${value} ${suffix}`;
479
+ }
480
+ return value;
436
481
  },
437
482
  },
438
483
  grid: {
@@ -505,7 +550,7 @@ const renderCharts = () => {
505
550
  new Chart(ctx, {
506
551
  type: type || "bar",
507
552
  data: parsedData,
508
- options: options ? JSON.parse(options) : DEFAULT_CHART_OPTIONS,
553
+ options: options ? JSON.parse(options) : { ...DEFAULT_CHART_OPTIONS },
509
554
  })
510
555
  );
511
556
  }
unfold/styles.css CHANGED
@@ -9,19 +9,20 @@
9
9
  }
10
10
  }
11
11
 
12
- @source inline("bg-white/[.06] border-white/40 h-3 w-3 h-[64px] w-[65px]! left-[65px] {dark:,}text-base-{50,{100..900},950} dark:hover:bg-white/[.06] translate-x-1/4 -translate-y-1/4");
13
- @source inline("{-,}{top,bottom,left,right}-{0..6}");
12
+ @source inline("aspect-square bg-white/[.06] border-white/40 h-3 w-3 h-[64px] w-[65px]! left-[65px] {dark:,}text-base-{50,{100..900},950} dark:hover:bg-white/[.06] {-,}translate-{x,y}-{1/2}");
13
+ @source inline("{-,}{top,bottom,left,right}-{1/2,0..6} {!,}leading-[38px] text-{default,subtle,important}");
14
+ @source inline("bg-linear-to-{{t,r,b,l,tl,tr,bl,br}} {dark:,}{from, to}-{{{base,primary}-{50,{100..900..100},950}},white}");
14
15
  @source inline("rounded rounded-{t,r,b,l} rounded-{t,r,b,l}-default");
15
16
  @source inline("{md:,lg:,2xl:,}relative {md:,lg:,2xl:,}flex {md:,lg:,2xl:,}absolute {md:,lg:,2xl:,}sticky");
16
- @source inline("{-,}m{t,r,b,l,x,y,}-{0..6} {-,}p{t,r,b,l,x,y,}-{0..6}");
17
+ @source inline("{-,}{lg:,}m{t,r,b,l,x,y,}-{0..24} {-,}{lg:,}p{t,r,b,l,x,y,}-{0..24}");
17
18
  @source inline("{md:,lg:,}border-{0,2} {md:,lg:,}border-{t,r,b,l}-{0,2}");
18
19
  @source inline("{hover:,dark:,}bg-primary-{50,{100..900..100},950}");
19
20
  @source inline("{hover:,dark:,}border-base-{50,{100..900..100},950} {hover:,dark:,}border-transparent");
20
21
  @source inline("{hover:,dark:,}bg-base-{50,{100..900..100},950}");
21
- @source inline("{md:,lg:,}w-{1/2,1/3,2/3,1/4,2/4,3/4,1/5,2/5,3/5,4/5,1/6,2/6,3/6,4/6,5/6,1/7,2/7,3/7,4/7,5/7,6/7}");
22
- @source inline("{md:,lg:,}gap-{0.5,{1..12}}");
23
- @source inline("{md:,lg:,}grid-cols-{1..12}");
24
- @source inline("{md:,lg:,}col-span-{1..12}");
22
+ @source inline("{md:,lg:,}{min-h,h,min-w,w}-{1..8} {md:,lg:,}w-{1/2,1/3,2/3,1/4,2/4,3/4,1/5,2/5,3/5,4/5,1/6,2/6,3/6,4/6,5/6,1/7,2/7,3/7,4/7,5/7,6/7}");
23
+ @source inline("{md:,lg:,xl:,}gap-{0.5,{1..16}}");
24
+ @source inline("{md:,lg:,xl:,}grid-cols-{1..16}");
25
+ @source inline("{md:,lg:,xl:,}col-span-{1..16}");
25
26
 
26
27
  @layer base {
27
28
  *,
@@ -29,7 +30,7 @@
29
30
  ::before,
30
31
  ::backdrop,
31
32
  ::file-selector-button {
32
- border-color: var(--color-gray-200, currentColor);
33
+ border-color: var(--color-base-200, currentColor);
33
34
  }
34
35
  }
35
36
 
@@ -74,6 +75,19 @@
74
75
  --color-font-important-dark: var(--color-font-important-dark);
75
76
  }
76
77
 
78
+
79
+ @utility text-important {
80
+ @apply text-font-important-light dark:text-font-important-dark;
81
+ }
82
+
83
+ @utility text-default {
84
+ @apply text-font-default-light dark:text-font-default-dark;
85
+ }
86
+
87
+ @utility text-subtle {
88
+ @apply text-font-subtle-light dark:text-font-subtle-dark;
89
+ }
90
+
77
91
  @utility field-sizing-content {
78
92
  field-sizing: content;
79
93
  }
@@ -99,7 +113,7 @@
99
113
  }
100
114
 
101
115
  @utility scrollable-top {
102
- @apply after:absolute after:content-[''] after:bg-linear-to-t after:from-gray-100 after:h-4 after:left-0 after:right-0 after:-top-px after:-translate-y-full dark:after:bg-none;
116
+ @apply after:absolute after:content-[''] after:bg-linear-to-t after:from-base-100 after:h-4 after:left-0 after:right-0 after:-top-px after:-translate-y-full dark:after:bg-none;
103
117
  }
104
118
 
105
119
  @utility md-16 {
@@ -264,7 +278,7 @@ table tr.selected th {
264
278
 
265
279
  .selector-chooseall,
266
280
  .selector-clearall {
267
- @apply block border-t border-base-200 py-2 text-center text-sm text-primary-500 dark:border-base-700;
281
+ @apply block border-t border-base-200 cursor-pointer py-2 text-center text-sm text-default;
268
282
  }
269
283
 
270
284
  .selector-clearall {
@@ -52,8 +52,12 @@
52
52
  <input type="hidden" name="{{ to_field_var }}" value="{{ to_field }}">
53
53
  {% endif %}
54
54
 
55
- {% include "unfold/helpers/messages/errornote.html" with errors=errors %}
56
- {% include "unfold/helpers/messages/error.html" with errors=adminform.form.non_field_errors %}
55
+ {% if errors or adminform.form.non_field_errors %}
56
+ <div class="flex flex-col gap-4 *:mb-0">
57
+ {% include "unfold/helpers/messages/errornote.html" with errors=errors %}
58
+ {% include "unfold/helpers/messages/error.html" with errors=adminform.form.non_field_errors %}
59
+ </div>
60
+ {% endif %}
57
61
 
58
62
  {% block field_sets %}
59
63
  {% with has_conditional_display=adminform.model_admin.conditional_fields %}
@@ -2,7 +2,7 @@
2
2
 
3
3
  <div class="relative z-50">
4
4
  <div class="fixed hidden xl:relative xl:block w-[288px] {% element_classes 'navigation_wrapper' %}" x-bind:class="{'xl:hidden!': !sidebarDesktopOpen, 'block!': sidebarMobileOpen}">
5
- <div class="bg-gray-50 relative z-30 dark:bg-gray-900">
5
+ <div class="bg-base-50 relative z-30 dark:bg-base-900">
6
6
  <div id="nav-sidebar" class="bg-base-50 border-r border-base-200 bottom-0 fixed max-h-screen top-0 w-[288px] dark:border-base-800 dark:bg-base-900 {% element_classes 'navigation' %}">
7
7
  {% if templates.navigation %}
8
8
  {% include templates.navigation %}
@@ -3,7 +3,7 @@ class="font-medium flex group items-center gap-2 px-3 py-2 rounded-default justi
3
3
  {% if variant == "default" %}
4
4
  border border-base-200 bg-white text-font-important-light dark:border-base-700 dark:bg-transparent dark:text-font-important-dark
5
5
  {% elif variant == "secondary" %}
6
- bg-gray-100 border border-transparent dark:bg-base-800
6
+ bg-base-100 border border-transparent dark:bg-base-800
7
7
  {% elif variant == "ghost" %}
8
8
  bg-transparent text-font-important-light dark:text-font-important-dark
9
9
  {% else %}
@@ -1,11 +1,11 @@
1
- <{% if href %}a href="{{ href }}"{% else %}div{% endif %} class="bg-white block border border-base-200 flex flex-col grow overflow-hidden p-6 relative rounded-default shadow-xs dark:bg-base-900 dark:border-base-800 {% if href %}cursor-pointer transition-all hover:border-base-300 hover:shadow-md hover:shadow-base-200 dark:hover:border-base-700 dark:hover:shadow-base-800/50 {% endif %}{% if class %} {{ class }}{% endif %}">
1
+ <{% if href %}a href="{{ href }}"{% else %}div{% endif %} class="bg-white block flex flex-col grow overflow-hidden p-6 relative rounded-default shadow-xs dark:bg-base-900 dark:border-base-800 {% if not disable_border %}border border-base-200 {% else %}shadow-base-500/20{% endif %} {% if href %}cursor-pointer transition-all hover:border-base-300 hover:shadow-md dark:hover:border-base-700 dark:hover:shadow-base-800/50 {% endif %}{% if class %} {{ class }}{% endif %}">
2
2
  {% if title %}
3
3
  <h2 class="border-b border-base-200 font-semibold mb-6 -mt-6 -mx-6 py-4 px-6 text-[15px] text-font-important-light dark:text-font-important-dark dark:border-base-800">
4
4
  {{ title }}
5
5
  </h2>
6
6
  {% endif %}
7
7
 
8
- <div class="grow relative {% if icon %} pl-6{% endif %}">
8
+ <div class="grow relative{% if icon %} pl-8{% endif %}">
9
9
  {{ children }}
10
10
 
11
11
  {% if label %}
@@ -15,7 +15,7 @@
15
15
  {% endif %}
16
16
 
17
17
  {% if icon %}
18
- <span class="material-symbols-outlined absolute -left-6 text-base-300 top-1/2 -translate-x-1/3 -translate-y-1/2 text-6xl! dark:text-base-500">{{ icon }}</span>
18
+ <span class="material-symbols-outlined absolute -left-6 text-base-300 top-1/2 -translate-x-1/3 -translate-y-1/2 text-6xl! dark:text-base-500 {{ icon_class }}">{{ icon }}</span>
19
19
  {% endif %}
20
20
  </div>
21
21
 
@@ -0,0 +1 @@
1
+ {{ children }}
@@ -1,5 +1,5 @@
1
- <div class="{% if class %}{{ class }}{% endif %}">
2
- <div class="flex flex-col gap-2 relative">
1
+ <div class="flex flex-col gap-2 relative w-full {% if class %}{{ class }}{% endif %}">
2
+ {% if title or description %}
3
3
  <div class="flex flex-row relative z-20">
4
4
  {% if title %}
5
5
  <h3 class="text-font-important-light dark:text-font-important-dark text-sm">
@@ -13,11 +13,11 @@
13
13
  </strong>
14
14
  {% endif %}
15
15
  </div>
16
+ {% endif %}
16
17
 
17
- {% if value %}
18
- <div class="bg-gray-100 overflow-hidden rounded-default dark:bg-base-800">
19
- <div class="h-1.5 bg-primary-600 rounded-default z-10 dark:bg-primary-500" title="{{ value }}%" style="width: {{ value }}%"></div>
20
- </div>
21
- {% endif %}
22
- </div>
18
+ {% if value %}
19
+ <div class="bg-base-100 overflow-hidden rounded-default dark:bg-base-800">
20
+ <div class="h-1.5 bg-primary-600 rounded-default z-10 dark:bg-primary-500 {{ progress_class }}" title="{{ value }}%" style="width: {{ value }}%"></div>
21
+ </div>
22
+ {% endif %}
23
23
  </div>
@@ -1,4 +1,4 @@
1
- <ul class="flex flex-row gap-0.5 overflow-hidden rounded-default">
1
+ <ul class="flex flex-row gap-0.5 overflow-hidden rounded-default {% if class %}{{ class }}{% endif %}">
2
2
  {% for item in data %}
3
3
  <li class="h-8 px-px size-full {% if item.color %}{{ item.color }}{% else %}bg-base-300 dark:bg-base-400{% endif %} hover:opacity-50" title="{{ item.tooltip }}"></li>
4
4
  {% endfor %}
@@ -72,7 +72,7 @@
72
72
  <div class="absolute bottom-0 left-0 right-0 top-0 z-50 md:left-72" x-cloak x-show="openAllApplications">
73
73
  <div class="absolute bg-base-900/80 backdrop-blur-xs bottom-0 left-0 right-0 top-0 z-10 w-screen"></div>
74
74
 
75
- <div class="bg-white flex flex-col h-full overflow-x-hidden overflow-y-auto py-5 px-8 relative text-sm w-80 z-20 dark:bg-base-900 dark:border-r dark:border-base-800" x-on:click.outside="openAllApplications = false" x-on:keydown.escape.window="openAllApplications = false">
75
+ <div class="bg-white flex flex-col h-full overflow-x-hidden overflow-y-auto py-5 px-8 relative text-sm w-80 z-20 dark:bg-base-900 dark:border-r dark:border-base-800" x-on:click.outside="openAllApplications = false" x-on:keydown.escape.window="openAllApplications = false" data-simplebar>
76
76
  {% for app in app_list %}
77
77
  <div class="mb-6 last:mb-0">
78
78
  <h2 class="mb-4 font-semibold text-font-important-light truncate dark:text-font-important-dark">
@@ -1,6 +1,6 @@
1
1
  {% load i18n %}
2
2
 
3
- <div class="inline-flex font-semibold items-center justify-center leading-normal h-6 w-6 rounded-full uppercase whitespace-nowrap {% if value == '' or value == None %}bg-base-100 text-base-700 dark:bg-base-500/20 dark:text-base-200{% elif value %}bg-green-100 text-green-700 dark:bg-green-500/20 dark:text-green-400{% else %}bg-red-100 text-red-700 dark:bg-red-500/20 dark:text-red-400{% endif %}"
3
+ <div class="inline-flex font-semibold items-center justify-center leading-normal h-6 w-6 !rounded-full uppercase whitespace-nowrap {% if value == '' or value == None %}bg-base-100 text-base-700 dark:bg-base-500/20 dark:text-base-200{% elif value %}bg-green-100 text-green-700 dark:bg-green-500/20 dark:text-green-400{% else %}bg-red-100 text-red-700 dark:bg-red-500/20 dark:text-red-400{% endif %}"
4
4
  title="{% if value == '' or value == None %}{% trans "Unknown" %}{% elif value %}{% trans "True" %}{% else %}{% trans "False" %}{% endif %}">
5
5
 
6
6
  <span class="material-symbols-outlined">
@@ -30,7 +30,7 @@
30
30
  x-on:keydown.escape.prevent="handleEscape()"
31
31
  x-on:keydown.arrow-down.prevent="nextItem()"
32
32
  x-on:keydown.arrow-up.prevent="prevItem()"
33
- x-on:keydown.enter.prevent="selectItem()"
33
+ x-on:keydown.enter.prevent="selectItem({% if command_show_history %}true{% else %}false{% endif %})"
34
34
  hx-get="{% url "admin:search" %}?extended=1"
35
35
  hx-trigger="keyup changed delay:500ms"
36
36
  hx-select="#command-results-list"
@@ -1,12 +1,20 @@
1
- {% load i18n %}
1
+ {% load i18n unfold %}
2
2
 
3
3
  {% if results %}
4
4
  <ul id="command-results-list" class="flex flex-col gap-1.5 p-4">
5
5
  {% for item in results %}
6
6
  <li class="group"
7
- x-bind:class="{'active': currentIndex === {{ forloop.counter }}}"
8
- x-on:mouseenter="currentIndex = {{ forloop.counter }}">
9
- <a class="bg-base-100 flex items-center rounded-default px-3.5 py-3 transition-colors group-[.active]:bg-primary-600 group-[.active]:text-white dark:bg-white/[.04] dark:text-base-200 dark:group-[.active]:bg-primary-600 dark:group-[.active]:text-white"
7
+ {% if forloop.last and results.next_page_number %}
8
+ hx-get="{% url "admin:search" %}{% unfold_querystring extended=1 page=results.next_page_number %}"
9
+ hx-trigger="intersect once threshold:0.5"
10
+ hx-swap="beforeend"
11
+ hx-select="#command-results-list > *"
12
+ hx-target="#command-results-list"
13
+ hx-indicator="#command-results-loading"
14
+ {% endif %}
15
+ x-bind:class="{'active': currentIndex === {{ page_counter|add:forloop.counter }}}"
16
+ x-on:mouseenter="currentIndex = {{ page_counter|add:forloop.counter }}">
17
+ <a class="bg-base-100 flex items-center rounded-default px-3.5 py-3 group-[.active]:bg-primary-600 group-[.active]:text-white dark:bg-white/[.04] dark:text-base-200 dark:group-[.active]:bg-primary-600 dark:group-[.active]:text-white"
10
18
  href="{{ item.link }}"
11
19
  data-title="{{ item.title }}"
12
20
  data-description="{{ item.description }}"
@@ -25,26 +33,37 @@
25
33
  <span class="text-font-subtle-light dark:text-font-subtle-dark group-[.active]:text-white">{{ item.description|capfirst }}</span>
26
34
  </span>
27
35
 
28
- <span class="material-symbols-outlined ml-auto text-sm transition-all group-[.active]:text-white group-[.active]:-mr-1">arrow_forward</span>
36
+ <span class="material-symbols-outlined ml-auto text-sm transition-transform group-[.active]:text-white group-[.active]:-translate-x-[2px]">arrow_forward</span>
29
37
  </a>
30
38
  </li>
31
39
  {% endfor %}
32
40
  </ul>
33
41
  {% else %}
34
- <ul id="command-results-list" class="px-4 py-8 flex items-center justify-center">
42
+ <ul class="px-4 py-8 flex items-center justify-center">
35
43
  <li class="text-lg">
36
44
  {% trans "No results matching your query" %}
37
45
  </li>
38
46
  </ul>
39
47
  {% endif %}
40
48
 
41
-
42
49
  <div id="command-results-note" x-show="hasResults">
43
50
  <div class="border-t border-base-200 px-4 py-3 flex items-center justify-center text-xs dark:border-base-700">
44
- {% blocktranslate count counter=results|length with time=execution_time|floatformat:2 %}
45
- Found {{ counter }} result in {{ time }} seconds
46
- {% plural %}
47
- Found {{ counter }} results in {{ time }} seconds
48
- {% endblocktranslate %}
51
+ <div id="command-results-loading" class="hidden flex-row gap-2 grow h-[16px] items-center justify-center w-[16px] w-full [&.htmx-request]:flex [&.htmx-request+div]:hidden">
52
+ <span class="material-symbols-outlined animate-spin text-sm">
53
+ progress_activity
54
+ </span>
55
+
56
+ <span>
57
+ {% trans "Loading more results..." %}
58
+ </span>
59
+ </div>
60
+
61
+ <div>
62
+ {% blocktranslate count counter=page_obj.count with time=execution_time|floatformat:2 %}
63
+ Found {{ counter }} result in {{ time }} seconds
64
+ {% plural %}
65
+ Found {{ counter }} results in {{ time }} seconds
66
+ {% endblocktranslate %}
67
+ </div>
49
68
  </div>
50
69
  </div>
@@ -2,7 +2,7 @@
2
2
 
3
3
  {% if show_back_button %}
4
4
  {% if object %}
5
- {% url object|admin_object_app_url:"changelist" as changelist_url %}
5
+ {% admin_object_app_url object "changelist" as changelist_url %}
6
6
 
7
7
  <a href="{{ changelist_url }}" class="block h-[18px] mr-3" title="{% trans "Go back" %}">
8
8
  <span class="material-symbols-outlined">
@@ -5,7 +5,7 @@
5
5
  {% trans "Previous" %}
6
6
  </a>
7
7
 
8
- <a {% if cl.result_list|length %}href="{% infinite_paginator_url cl cl.page_num|add:1 %}"{% endif %} class="{% if cl.result_list|length %}hover:text-primary-600 dark:hover:text-primary-500{% endif %}">
8
+ <a {% if cl.result_list|length == cl.paginator.per_page %}href="{% infinite_paginator_url cl cl.page_num|add:1 %}"{% endif %} class="{% if cl.result_list|length and cl.result_list|length == cl.paginator.per_page %}hover:text-primary-600 dark:hover:text-primary-500{% endif %}">
9
9
  {% trans "Next" %}
10
10
  </a>
11
11
  </div>
@@ -27,6 +27,7 @@
27
27
  name="s"
28
28
  x-ref="searchInput"
29
29
  x-on:focus="openSearchResults = true; currentIndex = 0"
30
+ x-on:keydown="openSearchResults = true;"
30
31
  x-on:keydown.arrow-down.prevent="nextItem()"
31
32
  x-on:keydown.arrow-up.prevent="prevItem()"
32
33
  x-on:keydown.escape.prevent="openSearchResults = false; if ($refs.searchInput.value === '') { $refs.searchInput.blur() } else { $refs.searchInput.value = '' }"
@@ -3,7 +3,7 @@
3
3
  {% if site_dropdown %}
4
4
  <div class="absolute bg-white border border-base-200 flex flex-col left-3 py-1 rounded-default shadow-lg top-[73px] w-[264px] z-50 dark:bg-base-800 dark:border-base-700" x-cloak x-show="openDropdown" x-transition x-on:click.outside="openDropdown = false">
5
5
  {% for item in site_dropdown %}
6
- <a href="{{ item.link }}" class="flex flex-row items-center gap-3 max-h-[30px] mx-1 px-2 py-2 rounded-default text-font-default-light dark:text-font-default-dark hover:bg-base-100 hover:text-font-important-light dark:hover:bg-base-700 dark:hover:text-font-important-dark">
6
+ <a href="{{ item.link }}" class="flex flex-row items-center gap-3 max-h-[30px] mx-1 px-2 py-2 rounded-default text-font-default-light dark:text-font-default-dark hover:bg-base-100 hover:text-font-important-light dark:hover:bg-base-700 dark:hover:text-font-important-dark" {% include "unfold/helpers/attrs.html" with attrs=item.attrs %}>
7
7
  {% if item.icon %}
8
8
  <span class="material-symbols-outlined">
9
9
  {{ item.icon }}
@@ -3,7 +3,7 @@
3
3
  <div class="flex flex-row">
4
4
  <div class="{{ widget.file_wrapper_class }}">
5
5
  {% if widget.is_initial and not widget.required %}
6
- <div class="bg-base-50 border-r border-base-200 flex flex-none items-center self-stretch px-3 dark:bg-base-900 dark:border-r-gray-700">
6
+ <div class="bg-base-50 border-r border-base-200 flex flex-none items-center self-stretch px-3 dark:bg-base-900 dark:border-r-base-700">
7
7
  <label for="{{ widget.checkbox_id }}" class="flex items-center">
8
8
  <input type="checkbox"{% if widget.class %} class="{{ widget.class }}"{% endif %} name="{{ widget.checkbox_name }}" id="{{ widget.checkbox_id }}" />
9
9