django-unfold 0.63.0__py3-none-any.whl → 0.64.1__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.63.0.dist-info → django_unfold-0.64.1.dist-info}/METADATA +1 -1
- {django_unfold-0.63.0.dist-info → django_unfold-0.64.1.dist-info}/RECORD +55 -51
- unfold/admin.py +1 -1
- unfold/contrib/constance/templates/admin/constance/change_list.html +0 -18
- unfold/contrib/filters/templates/unfold/filters/filters_numeric_slider.html +1 -1
- unfold/contrib/guardian/templates/admin/guardian/model/obj_perms_manage.html +0 -24
- unfold/contrib/guardian/templates/admin/guardian/model/obj_perms_manage_group.html +0 -26
- unfold/contrib/guardian/templates/admin/guardian/model/obj_perms_manage_user.html +0 -26
- unfold/contrib/import_export/templates/admin/import_export/export.html +0 -23
- unfold/contrib/import_export/templates/admin/import_export/import.html +0 -23
- unfold/contrib/simple_history/templates/simple_history/object_history_form.html +1 -33
- unfold/contrib/simple_history/templates/simple_history/object_history_list.html +0 -1
- unfold/dataclasses.py +8 -0
- unfold/settings.py +28 -22
- unfold/sites.py +120 -43
- unfold/static/unfold/css/styles.css +1 -1
- unfold/static/unfold/js/app.js +147 -9
- unfold/styles.css +32 -32
- unfold/templates/admin/app_index.html +0 -18
- unfold/templates/admin/auth/user/change_password.html +1 -26
- unfold/templates/admin/base.html +0 -16
- unfold/templates/admin/change_form.html +0 -33
- unfold/templates/admin/change_list.html +0 -19
- unfold/templates/admin/change_list_results.html +2 -2
- unfold/templates/admin/delete_confirmation.html +0 -21
- unfold/templates/admin/delete_selected_confirmation.html +0 -22
- unfold/templates/admin/index.html +0 -2
- unfold/templates/admin/object_history.html +0 -24
- unfold/templates/registration/password_change_done.html +0 -17
- unfold/templates/registration/password_change_form.html +0 -17
- unfold/templates/unfold/components/navigation.html +2 -2
- unfold/templates/unfold/components/table.html +55 -9
- unfold/templates/unfold/helpers/boolean.html +6 -6
- unfold/templates/unfold/helpers/command.html +53 -0
- unfold/templates/unfold/helpers/command_history.html +54 -0
- unfold/templates/unfold/helpers/command_results.html +50 -0
- unfold/templates/unfold/helpers/header_back_button.html +10 -2
- unfold/templates/unfold/helpers/header_title.html +11 -0
- unfold/templates/unfold/helpers/label.html +1 -1
- unfold/templates/unfold/helpers/navigation_header.html +2 -2
- unfold/templates/unfold/helpers/search.html +40 -22
- unfold/templates/unfold/helpers/search_results.html +2 -2
- unfold/templates/unfold/helpers/shortcut.html +1 -1
- unfold/templates/unfold/helpers/site_dropdown.html +1 -1
- unfold/templates/unfold/helpers/tab_items.html +15 -33
- unfold/templates/unfold/helpers/tab_list.html +1 -1
- unfold/templates/unfold/helpers/welcomemsg.html +6 -18
- unfold/templates/unfold/layouts/base_simple.html +0 -6
- unfold/templates/unfold/layouts/skeleton.html +4 -1
- unfold/templates/unfold/layouts/unauthenticated.html +0 -2
- unfold/templatetags/unfold.py +141 -0
- unfold/utils.py +29 -10
- unfold/views.py +4 -1
- {django_unfold-0.63.0.dist-info → django_unfold-0.64.1.dist-info}/LICENSE.md +0 -0
- {django_unfold-0.63.0.dist-info → django_unfold-0.64.1.dist-info}/WHEEL +0 -0
@@ -11,10 +11,14 @@
|
|
11
11
|
<div {% if height %}style="max-height: {{ height }}px;" data-simplebar{% endif %}>
|
12
12
|
<table class="block border-spacing-none border-separate w-full lg:table">
|
13
13
|
{% if table.headers %}
|
14
|
-
<thead class="text-font-important-light dark:text-font-important-dark {% if height %}sticky top-0{% endif %}">
|
14
|
+
<thead class="text-font-important-light dark:text-font-important-dark {% if height %}sticky top-0 z-100{% endif %}">
|
15
15
|
<tr class="bg-base-50 dark:bg-base-900">
|
16
|
-
{%
|
17
|
-
<th class="align-middle border-b border-base-200 font-semibold py-2 text-left whitespace-nowrap
|
16
|
+
{% if table|has_nested_tables %}
|
17
|
+
<th class="align-middle border-b border-base-200 font-semibold py-2 text-left whitespace-nowrap hidden px-3 lg:table-cell dark:border-base-800 dark:bg-white/[.02]"></th>
|
18
|
+
{% endif %}
|
19
|
+
|
20
|
+
{% for header in table.headers %}
|
21
|
+
<th class="align-middle border-b border-base-200 font-semibold py-2 text-left whitespace-nowrap hidden px-3 lg:table-cell dark:border-base-800 dark:bg-white/[.02] {% if card_included == 1 %}first:pl-6 last:pr-6{% endif %}">
|
18
22
|
{{ header|capfirst }}
|
19
23
|
</th>
|
20
24
|
{% endfor %}
|
@@ -23,17 +27,59 @@
|
|
23
27
|
{% endif %}
|
24
28
|
|
25
29
|
{% if table.rows %}
|
26
|
-
|
27
|
-
|
28
|
-
<tr class="{% if striped == 1 %}{% cycle '' 'bg-base-50 dark:bg-white/[.02]' %}{% endif %} block group {% if forloop.first %}first-row{% endif %} {% if not card_included == 1 %}border border-base-200 mb-3 rounded-default shadow-xs{% else %}border-b border-base-200 last:border-b-0{% endif %} lg:table-row lg:border-none lg:mb-0 lg:shadow-none dark:border-base-800">
|
29
|
-
{%
|
30
|
+
{% for row in table.rows %}
|
31
|
+
<tbody class="block relative lg:table-row-group" x-data="{ rowOpen: false }">
|
32
|
+
<tr class="{% if striped == 1 %}{% cycle '' 'bg-base-50 dark:bg-white/[.02]' %}{% endif %} block group {% if forloop.first %}first-row{% endif %} {% if not card_included == 1 %}border border-base-200 mb-3 rounded-default shadow-xs{% else %}border-b border-base-200 {% if forloop.last %}last:border-b-0{% endif %}{% endif %} lg:table-row lg:border-none lg:mb-0 lg:shadow-none dark:border-base-800">
|
33
|
+
{% if row.table.rows %}
|
34
|
+
<td class="cursor-pointer px-3 py-2 lg:pr-0 align-middle flex border-t border-base-200 font-normal gap-4 min-w-0 overflow-hidden text-left before:flex before:capitalize before:content-[attr(data-label)] before:font-semibold before:text-font-important-light dark:before:text-font-important-dark before:items-center before:mr-auto max-lg:first:border-t-0 lg:group-[.first-row]:border-t-0 lg:before:hidden lg:py-3 lg:table-cell dark:border-base-800 lg:w-px" data-label="{% trans "Expand row" %}">
|
35
|
+
<span class="material-symbols-outlined select-none block! h-[18px] w-[18px] -rotate-90 transition-all" x-on:click="rowOpen = !rowOpen" x-bind:class="{'rotate-0': rowOpen}">
|
36
|
+
expand_more
|
37
|
+
</span>
|
38
|
+
</td>
|
39
|
+
{% endif %}
|
40
|
+
|
41
|
+
{% for cell in row.cols|default:row %}
|
30
42
|
<td class="px-3 py-2 align-middle flex border-t border-base-200 font-normal gap-4 min-w-0 overflow-hidden text-left before:flex before:capitalize before:content-[attr(data-label)] before:font-semibold before:text-font-important-light dark:before:text-font-important-dark before:items-center before:mr-auto first:border-t-0 lg:group-[.first-row]:border-t-0 lg:before:hidden {% if not forloop.parentloop.first %}lg:first:border-t{% endif %} lg:py-3 lg:table-cell dark:border-base-800 {% if card_included == 1 %}lg:first:pl-6 lg:last:pr-6{% endif %}" {% if table.headers %}data-label="{{ table.headers|index:forloop.counter0 }}"{% endif %}>
|
31
43
|
{{ cell }}
|
32
44
|
</td>
|
33
45
|
{% endfor %}
|
34
46
|
</tr>
|
35
|
-
|
36
|
-
|
47
|
+
|
48
|
+
{% if "table" in row %}
|
49
|
+
<tr class="block lg:table-row" x-show="rowOpen">
|
50
|
+
<td class="block lg:table-cell" colspan="100%">
|
51
|
+
<div class="absolute bg-primary-600 -bottom-px hidden left-0 top-0 w-0.5 z-[50] lg:block" x-show="rowOpen"></div>
|
52
|
+
|
53
|
+
<table class="block w-full lg:table">
|
54
|
+
{% if row.table.headers %}
|
55
|
+
<thead>
|
56
|
+
<tr class="bg-base-50 dark:bg-white/[.02]">
|
57
|
+
{% for header in row.table.headers %}
|
58
|
+
<th class="align-middle border-b border-t border-base-200 font-semibold py-2 text-left whitespace-nowrap sortable column-description hidden px-3 lg:table-cell dark:border-base-800 dark:bg-white/[.02]">
|
59
|
+
{{ header }}
|
60
|
+
</th>
|
61
|
+
{% endfor %}
|
62
|
+
</tr>
|
63
|
+
</thead>
|
64
|
+
{% endif %}
|
65
|
+
|
66
|
+
<tbody class="block lg:table-row-group">
|
67
|
+
{% for nested_row in row.table.rows %}
|
68
|
+
<tr class="{% if row.table.striped == 1 %}{% cycle '' 'bg-base-50 dark:bg-white/[.02]' %}{% endif %} block group {% if forloop.first %}first-row{% endif %} border border-base-200 mb-3 rounded-default shadow-xs lg:table-row lg:border-none lg:mb-0 lg:shadow-none dark:border-base-800">
|
69
|
+
{% for cell in nested_row %}
|
70
|
+
<td class="px-3 py-2 align-middle flex border-t border-base-200 font-normal gap-4 min-w-0 overflow-hidden text-left before:flex before:capitalize before:content-[attr(data-label)] before:font-semibold before:text-font-important-light dark:before:text-font-important-dark before:items-center before:mr-auto first:border-t-0 lg:group-[.first-row]:border-t-0 lg:before:hidden {% if not forloop.parentloop.first %}lg:first:border-t{% endif %} lg:py-3 lg:table-cell dark:border-base-800" {% if row.table.headers %}data-label="{{ row.table.headers|index:forloop.counter0 }}"{% endif %}>
|
71
|
+
{{ cell }}
|
72
|
+
</td>
|
73
|
+
{% endfor %}
|
74
|
+
</tr>
|
75
|
+
{% endfor %}
|
76
|
+
</tbody>
|
77
|
+
</table>
|
78
|
+
</td>
|
79
|
+
</tr>
|
80
|
+
{% endif %}
|
81
|
+
</tbody>
|
82
|
+
{% endfor %}
|
37
83
|
{% endif %}
|
38
84
|
</table>
|
39
85
|
</div>
|
@@ -1,15 +1,15 @@
|
|
1
1
|
{% load i18n %}
|
2
2
|
|
3
|
-
<div class="flex items-center "
|
4
|
-
|
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
|
+
title="{% if value == '' or value == None %}{% trans "Unknown" %}{% elif value %}{% trans "True" %}{% else %}{% trans "False" %}{% endif %}">
|
5
5
|
|
6
|
-
<span>
|
6
|
+
<span class="material-symbols-outlined">
|
7
7
|
{% if value == '' or value == None %}
|
8
|
-
|
8
|
+
question_mark
|
9
9
|
{% elif value %}
|
10
|
-
|
10
|
+
check_small
|
11
11
|
{% else %}
|
12
|
-
|
12
|
+
close_small
|
13
13
|
{% endif %}
|
14
14
|
</span>
|
15
15
|
</div>
|
@@ -0,0 +1,53 @@
|
|
1
|
+
{% load i18n %}
|
2
|
+
|
3
|
+
{% if request.user.is_staff %}
|
4
|
+
<div class="backdrop-blur-xs bg-base-900/80 flex flex-col fixed inset-0 p-4 lg:p-32 z-[1000]"
|
5
|
+
x-data="searchCommand()"
|
6
|
+
x-on:opencommand.window="handleOpen()"
|
7
|
+
x-on:keydown.window="handleShortcut($event)"
|
8
|
+
x-show="openCommandResults">
|
9
|
+
<div class="bg-white flex flex-col max-w-3xl min-h-0 mx-auto overflow-hidden rounded-default shadow-lg w-full dark:bg-base-800" x-on:click.outside="handleOutsideClick()">
|
10
|
+
<div class="flex flex-row items-center px-4 w-full">
|
11
|
+
<button type="submit" id="command-submit" class="group flex items-center focus:outline-hidden">
|
12
|
+
<span class="block material-symbols-outlined text-xl text-base-400 dark:text-base-500 group-[.htmx-request]:hidden">
|
13
|
+
search
|
14
|
+
</span>
|
15
|
+
|
16
|
+
<span class="hidden material-symbols-outlined text-xl text-base-400 dark:text-base-500 group-[.htmx-request]:block animate-spin">
|
17
|
+
progress_activity
|
18
|
+
</span>
|
19
|
+
</button>
|
20
|
+
|
21
|
+
<input
|
22
|
+
autocomplete="off"
|
23
|
+
type="search"
|
24
|
+
placeholder="{% trans "Type to search" %}"
|
25
|
+
class="font-medium grow px-2 py-4 placeholder-font-subtle-light text-font-default-light focus:outline-hidden dark:placeholder-font-subtle-dark dark:text-font-default-dark"
|
26
|
+
name="s"
|
27
|
+
id="search-input-command"
|
28
|
+
x-ref="searchInputCommand"
|
29
|
+
hx-indicator="#command-submit"
|
30
|
+
x-on:keydown.escape.prevent="handleEscape()"
|
31
|
+
x-on:keydown.arrow-down.prevent="nextItem()"
|
32
|
+
x-on:keydown.arrow-up.prevent="prevItem()"
|
33
|
+
x-on:keydown.enter.prevent="selectItem()"
|
34
|
+
hx-get="{% url "admin:search" %}?extended=1"
|
35
|
+
hx-trigger="keyup changed delay:500ms"
|
36
|
+
hx-select="#command-results-list"
|
37
|
+
hx-select-oob="#command-results-note"
|
38
|
+
hx-target="#command-results">
|
39
|
+
|
40
|
+
{% include "unfold/helpers/shortcut.html" with shortcut="esc" %}
|
41
|
+
</div>
|
42
|
+
|
43
|
+
<div class="grow h-full overflow-auto w-full dark:border-base-700" data-simplebar x-on:htmx:after-swap="handleContentLoaded($event)" x-bind:class="{'border-t border-base-200': items !== undefined && items.length > 0}">
|
44
|
+
<div id="command-results"></div>
|
45
|
+
|
46
|
+
{% if command_show_history %}
|
47
|
+
{% include "unfold/helpers/command_history.html" %}
|
48
|
+
{% endif %}
|
49
|
+
|
50
|
+
<div id="command-results-note"></div>
|
51
|
+
</div>
|
52
|
+
</div>
|
53
|
+
{% endif %}
|
@@ -0,0 +1,54 @@
|
|
1
|
+
{% load i18n %}
|
2
|
+
|
3
|
+
<div id="command-history" x-show="!hasResults">
|
4
|
+
<template x-if="commandHistory.length > 0">
|
5
|
+
<div class="">
|
6
|
+
<h3 class="border-b border-base-200 font-semibold text-font-important-light dark:text-font-important-dark dark:border-base-700 p-4">
|
7
|
+
{% trans "Recent searches" %}
|
8
|
+
</h3>
|
9
|
+
|
10
|
+
<ul>
|
11
|
+
<template x-for="(item, index) in commandHistory">
|
12
|
+
<li class="border-b border-base-200 dark:border-base-700 last:border-b-0"
|
13
|
+
x-bind:class="{'active': currentIndex === index + 1}"
|
14
|
+
x-on:mouseenter="currentIndex = index + 1">
|
15
|
+
<a class="block flex flex-row gap-4 items-center p-4 transition-colors"
|
16
|
+
x-bind:data-title="item.title"
|
17
|
+
x-bind:data-description="item.description"
|
18
|
+
x-bind:href="item.link"
|
19
|
+
x-bind:class="{'bg-base-50 dark:bg-white/[.04]': currentIndex === index + 1}">
|
20
|
+
<span class="truncate">
|
21
|
+
<span class="font-medium text-font-important-light dark:text-font-important-dark" x-text="item.title"></span>
|
22
|
+
<span class="mx-1 opacity-50 group-[.active]:text-white">•</span>
|
23
|
+
<span class="text-font-subtle-light dark:text-font-subtle-dark group-[.active]:text-white" x-text="item.description"></span>
|
24
|
+
</span>
|
25
|
+
|
26
|
+
<span class="flex flex-row items-center ml-auto">
|
27
|
+
<span class="material-symbols-outlined text-base-400 dark:text-base-500 hover:text-primary-600 dark:hover:text-primary-500"
|
28
|
+
x-on:click="toggleFavorite($event, index);"
|
29
|
+
x-bind:class="{'text-primary-600 dark:text-primary-500': item.favorite}">
|
30
|
+
favorite
|
31
|
+
</span>
|
32
|
+
|
33
|
+
<span class="bg-base-200 h-6 w-px mx-3"></span>
|
34
|
+
|
35
|
+
<span class="material-symbols-outlined text-base-400 dark:text-base-500 hover:text-base-500 dark:hover:text-base-400" x-on:click="removeFromHistory($event, index);">
|
36
|
+
close
|
37
|
+
</span>
|
38
|
+
</span>
|
39
|
+
</a>
|
40
|
+
</li>
|
41
|
+
</template>
|
42
|
+
</ul>
|
43
|
+
</div>
|
44
|
+
</template>
|
45
|
+
|
46
|
+
<template x-if="commandHistory.length === 0">
|
47
|
+
<div class="border-t border-base-200 px-4 py-8 dark:border-base-700">
|
48
|
+
<p class="text-lg text-center">
|
49
|
+
{% trans "No recent searches" %}
|
50
|
+
</p>
|
51
|
+
</div>
|
52
|
+
</template>
|
53
|
+
</div>
|
54
|
+
</div>
|
@@ -0,0 +1,50 @@
|
|
1
|
+
{% load i18n %}
|
2
|
+
|
3
|
+
{% if results %}
|
4
|
+
<ul id="command-results-list" class="flex flex-col gap-1.5 p-4">
|
5
|
+
{% for item in results %}
|
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"
|
10
|
+
href="{{ item.link }}"
|
11
|
+
data-title="{{ item.title }}"
|
12
|
+
data-description="{{ item.description }}"
|
13
|
+
x-on:click="selectItem({% if command_show_history %}true{% else %}false{% endif %})">
|
14
|
+
{% if item.icon %}
|
15
|
+
<span class="bg-white border border-base-300 h-8 mr-4 w-8 flex items-center justify-center rounded-default group-[.active]:bg-transparent group-[.active]:border-white/40 dark:bg-base-800 dark:border-base-700">
|
16
|
+
<span class="material-symbols-outlined text-font-subtle-light text-sm dark:text-font-subtle-dark group-[.active]:text-white">
|
17
|
+
{{ item.icon }}
|
18
|
+
</span>
|
19
|
+
</span>
|
20
|
+
{% endif %}
|
21
|
+
|
22
|
+
<span>
|
23
|
+
<span class="font-medium">{{ item.title }}</span>
|
24
|
+
<span class="mx-1 opacity-50 group-[.active]:text-white">•</span>
|
25
|
+
<span class="text-font-subtle-light dark:text-font-subtle-dark group-[.active]:text-white">{{ item.description|capfirst }}</span>
|
26
|
+
</span>
|
27
|
+
|
28
|
+
<span class="material-symbols-outlined ml-auto text-sm transition-all group-[.active]:text-white group-[.active]:-mr-1">arrow_forward</span>
|
29
|
+
</a>
|
30
|
+
</li>
|
31
|
+
{% endfor %}
|
32
|
+
</ul>
|
33
|
+
{% else %}
|
34
|
+
<ul id="command-results-list" class="px-4 py-8 flex items-center justify-center">
|
35
|
+
<li class="text-lg">
|
36
|
+
{% trans "No results matching your query" %}
|
37
|
+
</li>
|
38
|
+
</ul>
|
39
|
+
{% endif %}
|
40
|
+
|
41
|
+
|
42
|
+
<div id="command-results-note" x-show="hasResults">
|
43
|
+
<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 %}
|
49
|
+
</div>
|
50
|
+
</div>
|
@@ -1,7 +1,15 @@
|
|
1
|
-
{% load admin_urls i18n %}
|
1
|
+
{% load admin_urls i18n unfold %}
|
2
2
|
|
3
3
|
{% if show_back_button %}
|
4
|
-
{% if
|
4
|
+
{% if object %}
|
5
|
+
{% url object|admin_object_app_url:"changelist" as changelist_url %}
|
6
|
+
|
7
|
+
<a href="{{ changelist_url }}" class="block h-[18px] mr-3" title="{% trans "Go back" %}">
|
8
|
+
<span class="material-symbols-outlined">
|
9
|
+
arrow_back
|
10
|
+
</span>
|
11
|
+
</a>
|
12
|
+
{% elif opts and adminform %}
|
5
13
|
{% url opts|admin_urlname:'changelist' as changelist_url %}
|
6
14
|
|
7
15
|
<a href="{% add_preserved_filters changelist_url %}" class="block h-[18px] mr-3" title="{% trans "Go back" %}">
|
@@ -0,0 +1,11 @@
|
|
1
|
+
{% spaceless %}
|
2
|
+
{% for part in parts %}
|
3
|
+
<{% if part.link %}a href="{{ part.link }}"{% else %}span{% endif %} class="align-middle inline-block leading-5 tracking-tight">
|
4
|
+
{{ part.title|capfirst }}
|
5
|
+
</{% if part.link %}a{% else %}span{% endif %} >
|
6
|
+
|
7
|
+
{% if not forloop.last %}
|
8
|
+
<span class="material-symbols-outlined inline-block align-middle leading-5 mx-2 text-base-400 dark:text-base-500">chevron_right</span>
|
9
|
+
{% endif %}
|
10
|
+
{% endfor %}
|
11
|
+
{% endspaceless %}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<span class="inline-block font-semibold leading-
|
1
|
+
<span class="inline-block font-semibold h-6 leading-6 px-2 rounded-default text-[11px] uppercase whitespace-nowrap
|
2
2
|
{% if type == 'info' %}
|
3
3
|
bg-blue-100 text-blue-700 dark:bg-blue-500/20 dark:text-blue-400
|
4
4
|
{% elif type == 'danger' %}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
{% load unfold %}
|
2
2
|
|
3
|
-
<div class="border-b border-base-200 flex gap-3 items-center h-[65px] mb-
|
3
|
+
<div class="border-b border-base-200 flex gap-3 items-center h-[65px] mb-6 dark:border-base-800 px-3 {% element_classes 'navigation_header' %}" {% if site_dropdown %}x-data="{ openDropdown: false }"{% endif %}>
|
4
4
|
<div class="bg-transparent flex font-semibold gap-3 grow min-w-0 -mx-px h-[54px] items-center px-3 {% if site_dropdown %}cursor-pointer rounded-default transition-all hover:bg-base-100 dark:hover:bg-white/[.06]{% endif %}"
|
5
5
|
{% if site_dropdown %}
|
6
6
|
x-on:click="openDropdown = !openDropdown"
|
@@ -14,7 +14,7 @@
|
|
14
14
|
{% endif %}
|
15
15
|
|
16
16
|
{% if site_dropdown %}
|
17
|
-
<span class="material-symbols-outlined ml-auto select-none">
|
17
|
+
<span class="material-symbols-outlined ml-auto select-none text-font-default-light dark:text-font-default-dark">
|
18
18
|
unfold_more
|
19
19
|
</span>
|
20
20
|
{% endif %}
|
@@ -1,30 +1,48 @@
|
|
1
1
|
{% load i18n %}
|
2
2
|
|
3
3
|
{% if sidebar_show_search %}
|
4
|
-
|
5
|
-
<div class="
|
6
|
-
<
|
4
|
+
{% if sidebar_command_search %}
|
5
|
+
<div class="mb-2.5 mx-3 relative" x-on:click="$dispatch('opencommand')">
|
6
|
+
<div class="bg-white border border-base-200 cursor-pointer 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 dark:bg-base-900 dark:border-base-700">
|
7
|
+
<span class="material-symbols-outlined md-18 text-base-400">manage_search</span>
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
x-ref="searchInput"
|
12
|
-
x-on:focus="openSearchResults = true; currentIndex = 0"
|
13
|
-
x-on:keydown.arrow-down.prevent="nextItem()"
|
14
|
-
x-on:keydown.arrow-up.prevent="prevItem()"
|
15
|
-
x-on:keydown.escape.prevent="openSearchResults = false; if ($refs.searchInput.value === '') { $refs.searchInput.blur() } else { $refs.searchInput.value = '' }"
|
16
|
-
x-on:keydown.enter.prevent="selectItem()"
|
17
|
-
x-on:search="currentIndex = 0"
|
18
|
-
hx-get="{% url "admin:search" %}"
|
19
|
-
hx-trigger="keyup changed delay:500ms"
|
20
|
-
hx-target="#search-results"
|
21
|
-
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"
|
22
|
-
placeholder="{% translate 'Search apps and models...' %}"
|
23
|
-
aria-label="{% translate 'Filter navigation items' %}">
|
9
|
+
<div class="grow font-medium min-w-0 overflow-hidden p-2 text-font-subtle-light truncate focus:outline-hidden dark:bg-base-900 dark:text-font-subtle-dark">
|
10
|
+
{% trans 'Search apps and models...' %}
|
11
|
+
</div>
|
24
12
|
|
25
|
-
|
13
|
+
{% if 'Macintosh' in request.META.HTTP_USER_AGENT %}
|
14
|
+
{% include "unfold/helpers/shortcut.html" with shortcut="⌘K" %}
|
15
|
+
{% else %}
|
16
|
+
{% include "unfold/helpers/shortcut.html" with shortcut="Ctrl + K" %}
|
17
|
+
{% endif %}
|
18
|
+
</div>
|
26
19
|
</div>
|
20
|
+
{% else %}
|
21
|
+
<div class="mb-2.5 mx-3 relative" x-data="searchDropdown()" x-on:keydown.window="applyShortcut($event)" x-on:click.outside="openSearchResults = false">
|
22
|
+
<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 dark:bg-base-900 dark:border-base-700">
|
23
|
+
<span class="material-symbols-outlined md-18 text-base-400">manage_search</span>
|
27
24
|
|
28
|
-
|
29
|
-
|
25
|
+
<input type="search"
|
26
|
+
id="nav-filter"
|
27
|
+
name="s"
|
28
|
+
x-ref="searchInput"
|
29
|
+
x-on:focus="openSearchResults = true; currentIndex = 0"
|
30
|
+
x-on:keydown.arrow-down.prevent="nextItem()"
|
31
|
+
x-on:keydown.arrow-up.prevent="prevItem()"
|
32
|
+
x-on:keydown.escape.prevent="openSearchResults = false; if ($refs.searchInput.value === '') { $refs.searchInput.blur() } else { $refs.searchInput.value = '' }"
|
33
|
+
x-on:keydown.enter.prevent="selectItem()"
|
34
|
+
x-on:search="currentIndex = 0"
|
35
|
+
hx-get="{% url "admin:search" %}"
|
36
|
+
hx-trigger="keyup changed delay:500ms"
|
37
|
+
hx-target="#search-results"
|
38
|
+
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"
|
39
|
+
placeholder="{% trans 'Search apps and models...' %}"
|
40
|
+
aria-label="{% trans 'Filter navigation items' %}">
|
41
|
+
|
42
|
+
{% include "unfold/helpers/shortcut.html" with shortcut="t" %}
|
43
|
+
</div>
|
44
|
+
|
45
|
+
<div id="search-results" x-show="openSearchResults"></div>
|
46
|
+
</div>
|
47
|
+
{% endif %}
|
30
48
|
{% endif %}
|
@@ -2,11 +2,11 @@
|
|
2
2
|
<ul class="absolute bg-white border border-base-200 flex flex-col leading-none left-0 mt-12 py-1 right-0 rounded-default top-0 shadow-xs text-sm z-10 dark:bg-base-800 dark:border-base-700">
|
3
3
|
{% for item in results %}
|
4
4
|
<li class="mx-1">
|
5
|
-
<a href="{{ item.
|
5
|
+
<a href="{{ item.link }}"
|
6
6
|
class="block items-center px-3 py-2 rounded-default truncate"
|
7
7
|
x-on:mouseenter="currentIndex = {{ forloop.counter }}"
|
8
8
|
x-bind:class="{'bg-base-100 text-base-700 dark:bg-base-700 dark:text-base-200': currentIndex === {{ forloop.counter }}}">
|
9
|
-
{{ item.
|
9
|
+
{{ item.title }} <span class="text-font-subtle-light mx-1 dark:text-font-subtle-dark">/</span> {{ item.description }}
|
10
10
|
</a>
|
11
11
|
</li>
|
12
12
|
{% endfor %}
|
@@ -1,3 +1,3 @@
|
|
1
|
-
<kbd class="bg-base-50 border border-base-200 font-
|
1
|
+
<kbd class="bg-base-50 border border-base-200 font-sans text-xs text-font-subtle-light rounded-xs px-1 whitespace-nowrap dark:bg-white/[.04] dark:border-base-700 dark:text-font-subtle-dark">
|
2
2
|
{{ shortcut }}
|
3
3
|
</kbd>
|
@@ -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 hover:bg-base-100 hover:text-
|
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">
|
7
7
|
{% if item.icon %}
|
8
8
|
<span class="material-symbols-outlined">
|
9
9
|
{{ item.icon }}
|
@@ -1,47 +1,29 @@
|
|
1
1
|
{% load i18n %}
|
2
2
|
|
3
3
|
{% if inlines_list or tabs_list %}
|
4
|
-
<
|
4
|
+
<nav class="bg-base-100 flex flex-col font-medium gap-1 p-1 rounded-default w-full dark:border-base-700 md:flex-row md:w-auto dark:bg-white/[.04] *:flex *:flex-row *:font-medium *: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]:text-font-important-light [&>.active]:hover:bg-white [&>.active]:dark:bg-base-900 [&>.active]:dark:hover:bg-base-900 [&>.active]:dark:text-font-important-dark">
|
5
5
|
{% for item in tabs_list %}
|
6
6
|
{% if item.has_permission %}
|
7
|
-
<
|
8
|
-
|
9
|
-
|
10
|
-
{% if item.inline %}
|
11
|
-
x-on:click="activeTab = '{{ item.inline|slugify }}'"
|
12
|
-
x-bind:class="{'border-b border-base-200 dark:border-base-800 md:border-primary-500 dark:md:border-primary-600! font-semibold -mb-px text-primary-600 dark:text-primary-500': activeTab == '{{ item.inline|slugify }}'}"
|
13
|
-
{% endif %}
|
14
|
-
>
|
15
|
-
{{ item.title }}
|
16
|
-
</a>
|
17
|
-
</li>
|
7
|
+
<a href="{% if item.link_callback %}{{ item.link_callback }}{% else %}{{ item.link }}{% endif %}{% if item.inline %}#{{ item.inline|slugify }}{% endif %}" class="{% if item.active and not item.inline %}active{% endif %}" {% if item.inline %}x-on:click="activeTab = '{{ item.inline|slugify }}'" x-bind:class="{'active': activeTab == '{{ item.inline|slugify }}'}"{% endif %}>
|
8
|
+
{{ item.title }}
|
9
|
+
</a>
|
18
10
|
{% endif %}
|
19
11
|
{% endfor %}
|
20
12
|
|
21
13
|
{% if inlines_list %}
|
22
|
-
<
|
23
|
-
|
24
|
-
|
25
|
-
x-on:click="activeTab = 'general'"
|
26
|
-
x-bind:class="{'border-b border-base-200 dark:border-base-800 md:border-primary-500 dark:md:border-primary-600! font-semibold -mb-px text-primary-600 dark:text-primary-500': activeTab == 'general', 'hover:text-primary-600 dark:hover:text-primary-500 dark:border-base-800': activeTab != 'general'}">
|
27
|
-
{% trans "General" %}
|
28
|
-
</a>
|
29
|
-
</li>
|
14
|
+
<a href="#general" x-on:click="activeTab = 'general'" x-bind:class="{'active': activeTab == 'general'}">
|
15
|
+
{% trans "General" %}
|
16
|
+
</a>
|
30
17
|
|
31
18
|
{% for inline in inlines_list %}
|
32
|
-
<
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
{% else %}
|
40
|
-
{{ inline.opts.verbose_name_plural|capfirst }}
|
41
|
-
{% endif %}
|
42
|
-
</a>
|
43
|
-
</li>
|
19
|
+
<a href="#{{ inline.formset.prefix|slugify }}" x-on:click="activeTab = '{{ inline.formset.prefix|slugify }}'" x-bind:class="{'active': activeTab == '{{ inline.formset.prefix|slugify }}'}">
|
20
|
+
{% if inline.formset.max_num == 1 %}
|
21
|
+
{{ inline.opts.verbose_name|capfirst }}
|
22
|
+
{% else %}
|
23
|
+
{{ inline.opts.verbose_name_plural|capfirst }}
|
24
|
+
{% endif %}
|
25
|
+
</a>
|
44
26
|
{% endfor %}
|
45
27
|
{% endif %}
|
46
|
-
</
|
28
|
+
</nav>
|
47
29
|
{% endif %}
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
{% if not is_popup %}
|
4
4
|
{% if tabs_list or inlines_list or actions_list or actions_detail or actions_items or nav_global %}
|
5
|
-
<div class="
|
5
|
+
<div class="flex items-start flex-col mb-4 md:flex-row md:items-center">
|
6
6
|
{% include "unfold/helpers/tab_items.html" %}
|
7
7
|
|
8
8
|
{% include "unfold/helpers/tab_actions.html" %}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
{% load unfold i18n %}
|
1
|
+
{% load unfold i18n admin_urls unfold %}
|
2
2
|
|
3
3
|
<div class="flex flex-row grow font-semibold items-center min-w-0 mr-3">
|
4
4
|
{% if is_nav_sidebar_enabled %}
|
@@ -17,25 +17,13 @@
|
|
17
17
|
|
18
18
|
{% include "unfold/helpers/header_back_button.html" %}
|
19
19
|
|
20
|
-
<h1 class="overflow-hidden text-ellipsis text-
|
21
|
-
{%
|
22
|
-
<span class="tracking-tight">
|
23
|
-
{{ pretitle }}
|
20
|
+
<h1 class="overflow-hidden leading-5 text-ellipsis text-font-important-light whitespace-nowrap xl:text-base dark:text-font-important-dark">
|
21
|
+
{% header_title %}
|
24
22
|
|
25
|
-
|
23
|
+
{% if cl and cl.full_result_count != cl.result_count and cl.paginator|class_name != "InfinitePaginator" %}
|
24
|
+
<span class="font-medium ml-2 text-font-subtle-light text-sm dark:text-font-subtle-dark">
|
25
|
+
{% blocktranslate count counter=cl.result_count %}{{ counter }} result{% plural %}{{ counter }} results{% endblocktranslate %} (<a href="?{% if cl.is_popup %}_popup=1{% endif %}">{% if cl.show_full_result_count %}{% blocktranslate with full_result_count=cl.full_result_count %}{{ full_result_count }} total{% endblocktranslate %}{% else %}{% translate "Show all" %}{% endif %}</a>)
|
26
26
|
</span>
|
27
|
-
|
28
|
-
{% if cl and cl.full_result_count != cl.result_count and cl.paginator|class_name != "InfinitePaginator" %}
|
29
|
-
<span class="font-medium ml-2 text-font-subtle-light text-sm dark:text-font-subtle-dark">
|
30
|
-
{% blocktranslate count counter=cl.result_count %}{{ counter }} result{% plural %}{{ counter }} results{% endblocktranslate %} (<a href="?{% if cl.is_popup %}_popup=1{% endif %}">{% if cl.show_full_result_count %}{% blocktranslate with full_result_count=cl.full_result_count %}{{ full_result_count }} total{% endblocktranslate %}{% else %}{% translate "Show all" %}{% endif %}</a>)
|
31
|
-
</span>
|
32
|
-
{% endif %}
|
33
|
-
|
34
|
-
{% if content_subtitle %}
|
35
|
-
{{ content_subtitle }}
|
36
|
-
{% endif %}
|
37
|
-
{% else %}
|
38
|
-
{% translate 'Welcome,' %} <strong>{% firstof user.get_short_name user.get_username %}</strong>.
|
39
27
|
{% endif %}
|
40
28
|
</h1>
|
41
29
|
</div>
|
@@ -15,12 +15,6 @@
|
|
15
15
|
{% include "unfold/helpers/header.html" %}
|
16
16
|
{% endblock %}
|
17
17
|
|
18
|
-
{% if not is_popup %}
|
19
|
-
{% spaceless %}
|
20
|
-
{% block breadcrumbs %}{% endblock %}
|
21
|
-
{% endspaceless %}
|
22
|
-
{% endif %}
|
23
|
-
|
24
18
|
<div class="px-4">
|
25
19
|
<div id="content" class="container mx-auto {% block coltype %}colM{% endblock %}">
|
26
20
|
{% block content %}
|
@@ -11,6 +11,7 @@
|
|
11
11
|
{% capture as nav_global_side silent %}{% block nav-global-side %}{% endblock %}{% endcapture %}
|
12
12
|
{% capture as actions_items silent %}{% block actions-items %}{% endblock %}{% endcapture %}
|
13
13
|
{% capture as extra_userlinks silent %}{% block extra_userlinks %}{% endblock %}{% endcapture %}
|
14
|
+
{% capture as show_back_button silent %}{% block show_back_button %}{{ show_back_button }}{% endblock %}{% endcapture %}
|
14
15
|
|
15
16
|
<!DOCTYPE html>
|
16
17
|
<html lang="{{ LANGUAGE_CODE|default:"en-us" }}" dir="{{ LANGUAGE_BIDI|yesno:"rtl,ltr,auto" }}" {% if theme %}class="{{ theme }}"{% endif %} x-data="{ adminTheme: {% if theme %}'{{ theme }}'{% else %}$persist('auto').as('adminTheme'){% endif %} }" x-bind:class="{'dark': adminTheme === 'dark' || (adminTheme === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches)}" x-cloak>
|
@@ -78,7 +79,9 @@
|
|
78
79
|
{% block base %}{% endblock %}
|
79
80
|
|
80
81
|
<div id="modal-overlay" class="backdrop-blur-xs bg-base-900/80 bottom-0 fixed hidden left-0 mr-1 right-0 top-0 z-50"></div>
|
82
|
+
|
83
|
+
{% include "unfold/helpers/command.html" %}
|
84
|
+
|
81
85
|
<script src="{% static 'unfold/js/simplebar/simplebar.js' %}"></script>
|
82
86
|
</body>
|
83
|
-
|
84
87
|
</html>
|