django-unfold 0.57.0__py3-none-any.whl → 0.59.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.57.0.dist-info → django_unfold-0.59.0.dist-info}/METADATA +1 -1
- {django_unfold-0.57.0.dist-info → django_unfold-0.59.0.dist-info}/RECORD +57 -55
- unfold/checks.py +24 -2
- unfold/contrib/filters/templates/unfold/filters/filters_numeric_slider.html +2 -2
- unfold/contrib/import_export/templates/admin/import_export/base.html +1 -5
- unfold/contrib/import_export/templates/admin/import_export/import_form.html +1 -1
- unfold/contrib/simple_history/templates/simple_history/object_history_form.html +1 -1
- unfold/decorators.py +28 -15
- unfold/fields.py +1 -1
- unfold/forms.py +4 -2
- unfold/layout.py +16 -0
- unfold/mixins/action_model_admin.py +22 -14
- unfold/paginator.py +12 -1
- unfold/settings.py +8 -1
- unfold/sites.py +87 -40
- unfold/static/admin/js/admin/RelatedObjectLookups.js +9 -3
- unfold/static/unfold/css/styles.css +2 -2
- unfold/styles.css +59 -104
- unfold/templates/admin/auth/user/change_password.html +1 -1
- unfold/templates/admin/base.html +1 -1
- unfold/templates/admin/change_form.html +2 -1
- unfold/templates/admin/edit_inline/stacked.html +1 -1
- unfold/templates/admin/includes/fieldset.html +9 -3
- unfold/templates/admin/login.html +1 -1
- unfold/templates/admin/pagination.html +1 -1
- unfold/templates/admin/submit_line.html +7 -7
- unfold/templates/registration/password_change_done.html +1 -1
- unfold/templates/registration/password_change_form.html +1 -1
- unfold/templates/unfold/components/button.html +1 -1
- unfold/templates/unfold/components/card.html +23 -23
- unfold/templates/unfold/components/progress.html +9 -7
- unfold/templates/unfold/components/table.html +5 -5
- unfold/templates/unfold/helpers/account_links.html +14 -6
- unfold/templates/unfold/helpers/change_list_actions.html +2 -2
- unfold/templates/unfold/helpers/change_list_filter_actions.html +2 -2
- unfold/templates/unfold/helpers/edit_inline/tabular_heading.html +1 -1
- unfold/templates/unfold/helpers/empty_results.html +2 -2
- unfold/templates/unfold/helpers/field.html +2 -2
- unfold/templates/unfold/helpers/header.html +1 -1
- unfold/templates/unfold/helpers/language_form.html +10 -0
- unfold/templates/unfold/helpers/language_switch.html +17 -19
- unfold/templates/unfold/helpers/navigation.html +1 -1
- unfold/templates/unfold/helpers/pagination_infinite.html +3 -3
- unfold/templates/unfold/helpers/theme_switch.html +29 -27
- unfold/templates/unfold/helpers/userlinks.html +2 -6
- unfold/templates/unfold/helpers/welcomemsg.html +9 -7
- unfold/templates/unfold/widgets/select.html +1 -1
- unfold/templates/unfold_crispy/field.html +1 -1
- unfold/templates/unfold_crispy/layout/checkbox.html +2 -2
- unfold/templates/unfold_crispy/layout/fieldset.html +4 -2
- unfold/templates/unfold_crispy/layout/fieldset_subheader.html +3 -0
- unfold/templates/unfold_crispy/layout/table_inline_formset.html +18 -16
- unfold/templatetags/unfold.py +20 -1
- unfold/utils.py +2 -2
- unfold/widgets.py +10 -4
- {django_unfold-0.57.0.dist-info → django_unfold-0.59.0.dist-info}/LICENSE.md +0 -0
- {django_unfold-0.57.0.dist-info → django_unfold-0.59.0.dist-info}/WHEEL +0 -0
@@ -9,7 +9,7 @@
|
|
9
9
|
{{ field.label|capfirst }}
|
10
10
|
|
11
11
|
{% if field.help_text %}
|
12
|
-
<span class="cursor-
|
12
|
+
<span class="cursor-help material-symbols-outlined ml-2 text-base-400 dark:text-base-500" title="{{ field.help_text|striptags }}">help</span>
|
13
13
|
{% endif %}
|
14
14
|
</span>
|
15
15
|
</th>
|
@@ -25,8 +25,8 @@
|
|
25
25
|
{% endif %}
|
26
26
|
|
27
27
|
|
28
|
-
{% if cl.has_filters %}
|
29
|
-
<a href="
|
28
|
+
{% if cl.has_filters or cl.query %}
|
29
|
+
<a href="?" class="border border-base-200 flex flex-row font-medium gap-2 group/button h-[38px] items-center justify-center px-3 py-2 rounded-default w-full hover:text-primary-600 lg:w-auto dark:border-base-700 dark:hover:bg-base-900 dark:hover:text-primary-500">
|
30
30
|
<span class="material-symbols-outlined ml-1">filter_list_off</span> {% trans "Reset filters" %}
|
31
31
|
</a>
|
32
32
|
{% endif %}
|
@@ -1,7 +1,7 @@
|
|
1
1
|
{% load unfold %}
|
2
2
|
|
3
3
|
{% if field.field.widget.input_type == "checkbox" and field.field.widget|class_name != "UnfoldAdminCheckboxSelectMultiple"%}
|
4
|
-
<div class="{% if field.errors %}errors {% endif %}flex flex-col group mb-
|
4
|
+
<div class="{% if field.errors %}errors {% endif %}flex flex-col group mb-5 last:mb-4">
|
5
5
|
<div class="flex flex-row gap-2 items-center">
|
6
6
|
{{ field }}
|
7
7
|
|
@@ -13,7 +13,7 @@
|
|
13
13
|
{% include "unfold/helpers/help_text.html" with help_text=field.help_text %}
|
14
14
|
</div>
|
15
15
|
{% else %}
|
16
|
-
<div class="{% if field.errors %}errors {% endif %}flex flex-col gap-2 group mb-
|
16
|
+
<div class="{% if field.errors %}errors {% endif %}flex flex-col gap-2 group mb-5 last:mb-4">
|
17
17
|
{% include "unfold/helpers/form_label.html" with field=field %}
|
18
18
|
|
19
19
|
{{ field }}
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
{% if not is_popup %}
|
4
4
|
{% block header %}
|
5
|
-
<div class="bg-white border-b border-base-200 mb-6 px-4 z-40 dark:bg-base-900 dark:border-base-800 {% element_classes 'header' %}">
|
5
|
+
<div class="bg-white border-b border-base-200 mb-6 px-4 z-40 dark:bg-base-900 dark:border-base-800 dark:text-font-default-dark {% element_classes 'header' %}">
|
6
6
|
<div class="{% if not cl.model_admin.list_fullwidth %}container{% endif %} flex items-center h-16 mx-auto py-4">
|
7
7
|
<div id="header-inner" class="flex items-center w-full">
|
8
8
|
<div class="flex items-center w-full">
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<form action="{% if languages_action %}{{ languages_action }}{% else %}{% url 'set_language' %}{% endif %}" method="post" class="flex w-full">
|
2
|
+
{% csrf_token %}
|
3
|
+
|
4
|
+
<input name="next" type="hidden" value="{{ redirect_to }}">
|
5
|
+
<input name="language" type="hidden" value="{{ language.code }}">
|
6
|
+
|
7
|
+
<button type="submit" class="block cursor-pointer grow mx-1 px-3 py-2 rounded-default text-left hover:bg-base-100 hover:text-base-700 dark:hover:bg-base-700 dark:hover:text-base-200 {% if language.code == LANGUAGE_CODE %}text-primary-600 dark:text-primary-500 dark:hover:text-primary-500! hover:text-primary-600!{% endif %}">
|
8
|
+
{{ language.name_local }} ({{ language.code }})
|
9
|
+
</button>
|
10
|
+
</form>
|
@@ -4,24 +4,22 @@
|
|
4
4
|
{% get_available_languages as LANGUAGES %}
|
5
5
|
{% get_language_info_list for LANGUAGES as languages %}
|
6
6
|
|
7
|
+
{% if show_languages %}
|
8
|
+
<div class="relative" x-data="{ openLanguageLinks: false }">
|
9
|
+
<a class="block cursor-pointer h-[18px] hover:text-base-700 dark:hover:text-base-200" x-on:click="openLanguageLinks = !openLanguageLinks">
|
10
|
+
<span class="material-symbols-outlined">translate</span>
|
11
|
+
</a>
|
7
12
|
|
8
|
-
<div class="
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
{%
|
17
|
-
|
18
|
-
|
19
|
-
<input name="language" type="hidden" value="{{ language.code }}">
|
20
|
-
|
21
|
-
<button type="submit" class="block grow mx-1 px-3 py-2 rounded-default text-left hover:bg-base-100 hover:text-base-700 dark:hover:bg-base-700 dark:hover:text-base-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 %}
|
13
|
+
<div class="absolute bg-white border border-base-200 flex flex-col leading-none py-1 -right-2 rounded-default shadow-lg top-7 w-52 z-50 dark:bg-base-800 dark:border-base-700" x-cloak x-show="openLanguageLinks" x-transition x-on:click.outside="openLanguageLinks = false">
|
14
|
+
{% if languages_list %}
|
15
|
+
{% for language in languages_list %}
|
16
|
+
{% include "unfold/helpers/language_form.html" with language=language %}
|
17
|
+
{% endfor %}
|
18
|
+
{% else %}
|
19
|
+
{% for language in languages %}
|
20
|
+
{% include "unfold/helpers/language_form.html" with language=language %}
|
21
|
+
{% endfor %}
|
22
|
+
{% endif %}
|
23
|
+
</div>
|
26
24
|
</div>
|
27
|
-
|
25
|
+
{% endif %}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
{% load i18n unfold %}
|
2
2
|
|
3
|
-
<nav class="bg-base-50 flex flex-col min-h-screen dark:bg-base-950/20 {% element_classes 'navigation_inner' %}">
|
3
|
+
<nav id="nav-sidebar-inner" class="bg-base-50 flex flex-col min-h-screen dark:text-font-default-dark dark:bg-base-950/20 {% element_classes 'navigation_inner' %}">
|
4
4
|
{% include "unfold/helpers/navigation_header.html" %}
|
5
5
|
|
6
6
|
{% include "unfold/helpers/search.html" %}
|
@@ -1,11 +1,11 @@
|
|
1
|
-
{% load unfold_list i18n %}
|
1
|
+
{% load unfold unfold_list i18n %}
|
2
2
|
|
3
3
|
<div class="flex flex-row gap-4">
|
4
|
-
<a {% if cl.page_num != 1 %}href="
|
4
|
+
<a {% if cl.page_num != 1 %}href="{% infinite_paginator_url cl cl.page_num|add:-1 %}"{% endif %} class="{% if cl.page_num != 1 %}hover:text-primary-600 dark:hover:text-primary-500{% endif %}">
|
5
5
|
{% trans "Previous" %}
|
6
6
|
</a>
|
7
7
|
|
8
|
-
<a href="
|
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 %}">
|
9
9
|
{% trans "Next" %}
|
10
10
|
</a>
|
11
11
|
</div>
|
@@ -1,32 +1,34 @@
|
|
1
1
|
{% load i18n %}
|
2
2
|
|
3
|
-
|
4
|
-
<
|
5
|
-
<
|
6
|
-
<span
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
<nav class="absolute bg-white border border-base-200 flex flex-col leading-none py-1 -right-2 rounded-default shadow-lg top-7 w-40 z-50 dark:bg-base-800 dark:border-base-700" x-cloak x-show="openTheme" x-transition x-on:click.outside="openTheme = false">
|
11
|
-
<a class="cursor-pointer flex flex-row leading-none mx-1 px-3 py-1.5 rounded-default hover:bg-base-100 hover:text-base-700 dark:hover:bg-base-700 dark:hover:text-base-200"
|
12
|
-
x-on:click="adminTheme = 'dark'"
|
13
|
-
x-bind:class="adminTheme == 'dark' && 'text-primary-600 dark:text-primary-500 dark:hover:text-primary-500! hover:text-primary-600!'">
|
14
|
-
<span class="material-symbols-outlined mr-2">dark_mode</span>
|
15
|
-
<span class="leading-none self-center">{% trans "Dark" %}</span>
|
3
|
+
{% if not theme %}
|
4
|
+
<div class="relative" x-data="{ openTheme: false }">
|
5
|
+
<a class="block cursor-pointer h-[18px] leading-none hover:text-base-700 dark:hover:text-base-200" x-on:click="openTheme = !openTheme">
|
6
|
+
<span class="material-symbols-outlined">
|
7
|
+
<span x-text="adminTheme == 'dark' && 'dark_mode' || adminTheme == 'light' && 'light_mode' || 'computer'"></span>
|
8
|
+
</span>
|
16
9
|
</a>
|
17
10
|
|
18
|
-
<
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
11
|
+
<nav class="absolute bg-white border border-base-200 flex flex-col leading-none py-1 -right-2 rounded-default shadow-lg top-7 w-40 z-50 dark:bg-base-800 dark:border-base-700" x-cloak x-show="openTheme" x-transition x-on:click.outside="openTheme = false">
|
12
|
+
<a class="cursor-pointer flex flex-row leading-none mx-1 px-3 py-1.5 rounded-default hover:bg-base-100 hover:text-base-700 dark:hover:bg-base-700 dark:hover:text-base-200"
|
13
|
+
x-on:click="adminTheme = 'dark'"
|
14
|
+
x-bind:class="adminTheme == 'dark' && 'text-primary-600 dark:text-primary-500 dark:hover:text-primary-500! hover:text-primary-600!'">
|
15
|
+
<span class="material-symbols-outlined mr-2">dark_mode</span>
|
16
|
+
<span class="leading-none self-center">{% trans "Dark" %}</span>
|
17
|
+
</a>
|
24
18
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
19
|
+
<a class="cursor-pointer flex flex-row mx-1 px-3 py-1.5 rounded-default hover:bg-base-100 hover:text-base-700 dark:hover:bg-base-700 dark:hover:text-base-200"
|
20
|
+
x-on:click="adminTheme = 'light'"
|
21
|
+
x-bind:class="adminTheme == 'light' && 'text-primary-600 dark:text-primary-500 dark:hover:text-primary-500! hover:text-primary-600!'">
|
22
|
+
<span class="material-symbols-outlined mr-2">light_mode</span>
|
23
|
+
<span class="leading-none self-center">{% trans "Light" %}</span>
|
24
|
+
</a>
|
25
|
+
|
26
|
+
<a class="cursor-pointer flex flex-row mx-1 px-3 py-1.5 rounded-default hover:bg-base-100 hover:text-base-700 dark:hover:bg-base-700 dark:hover:text-base-200"
|
27
|
+
x-on:click="adminTheme = 'auto'"
|
28
|
+
x-bind:class="adminTheme == 'auto' && 'text-primary-600 dark:text-primary-500 dark:hover:text-primary-500! hover:text-primary-600!'">
|
29
|
+
<span class="material-symbols-outlined mr-2">computer</span>
|
30
|
+
<span class="leading-none self-center">{% trans "System" %}</span>
|
31
|
+
</a>
|
32
|
+
</nav>
|
33
|
+
</div>
|
34
|
+
{% endif %}
|
@@ -11,13 +11,9 @@
|
|
11
11
|
{{ extra_userlinks }}
|
12
12
|
{% endif %}
|
13
13
|
|
14
|
-
{%
|
15
|
-
{% include "unfold/helpers/language_switch.html" %}
|
16
|
-
{% endif %}
|
14
|
+
{% include "unfold/helpers/language_switch.html" %}
|
17
15
|
|
18
|
-
{%
|
19
|
-
{% include "unfold/helpers/theme_switch.html" %}
|
20
|
-
{% endif %}
|
16
|
+
{% include "unfold/helpers/theme_switch.html" %}
|
21
17
|
|
22
18
|
{% include "unfold/helpers/account_links.html" %}
|
23
19
|
</div>
|
@@ -1,15 +1,17 @@
|
|
1
1
|
{% load unfold i18n %}
|
2
2
|
|
3
3
|
<div class="flex flex-row grow font-semibold items-center min-w-0 mr-3">
|
4
|
-
|
5
|
-
<span class="
|
6
|
-
|
7
|
-
|
4
|
+
{% if is_nav_sidebar_enabled %}
|
5
|
+
<span class="cursor-pointer flex flex-row items-center">
|
6
|
+
<span class="material-symbols-outlined hidden! xl:block!" hx-get="{% url "admin:toggle_sidebar" %}" hx-swap="none" x-on:click="sidebarDesktopOpen = !sidebarDesktopOpen">
|
7
|
+
dock_to_right
|
8
|
+
</span>
|
8
9
|
|
9
|
-
|
10
|
-
|
10
|
+
<span class="material-symbols-outlined block! xl:hidden!" x-on:click="sidebarMobileOpen = !sidebarMobileOpen">
|
11
|
+
dock_to_right
|
12
|
+
</span>
|
11
13
|
</span>
|
12
|
-
|
14
|
+
{% endif %}
|
13
15
|
|
14
16
|
<span class="block bg-base-200 h-5 mx-3 w-px dark:bg-base-700"></span>
|
15
17
|
|
@@ -5,5 +5,5 @@
|
|
5
5
|
</optgroup>{% endif %}{% endfor %}
|
6
6
|
</select>
|
7
7
|
|
8
|
-
<span class="material-symbols-outlined absolute group-[.primary]:text-white -
|
8
|
+
<span class="material-symbols-outlined absolute group-[.primary]:text-white pointer-events-none mr-[12px] right-0 text-base-400 top-0 top-1/2 hover:text-base-700 dark:text-base-500 dark:hover:text-base-200 -translate-y-1/2">expand_more</span>
|
9
9
|
</div>
|
@@ -3,7 +3,7 @@
|
|
3
3
|
{% if field.is_hidden %}
|
4
4
|
{{ field }}
|
5
5
|
{% else %}
|
6
|
-
<{% if tag %}{{ tag }}{% else %}div{% endif %} id="div_{{ field.auto_id }}" class="group {% if tag == "td" %}align-top border-t border-base-200 font-normal gap-4 min-w-0 overflow-hidden px-3 py-3 text-left dark:border-base-800 dark:before:text-font-important-dark{% endif%} {% if field.errors %}errors{% endif %} {% if field_class %} {{ field_class }}{% endif %} {% if field|is_checkbox and tag == "td" %}flex flex-row gap-2 items-center{% else %}{% if 'form-horizontal' in form_class %} row{% endif %}{% endif %}{% if wrapper_class %} {{ wrapper_class }}{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}">
|
6
|
+
<{% if tag %}{{ tag }}{% else %}div{% endif %} id="div_{{ field.auto_id }}" class="group {% if tag == "td" %}align-top border-t border-base-200 font-normal gap-4 min-w-0 overflow-hidden px-3 py-3 text-left dark:border-base-800 dark:before:text-font-important-dark {% if form_show_labels and forloop.parentloop.first %}border-t-0{% endif %}{% endif %} {% if field.errors %}errors{% endif %} {% if field_class %} {{ field_class }}{% endif %} {% if field|is_checkbox and tag == "td" %}flex flex-row gap-2 items-center{% else %}{% if 'form-horizontal' in form_class %} row{% endif %}{% endif %}{% if wrapper_class %} {{ wrapper_class }}{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}">
|
7
7
|
{% if field.label and not field|is_checkbox and form_show_labels %}
|
8
8
|
<label {% if field.id_for_label %}for="{{ field.id_for_label }}"{% endif %} class="block font-semibold mb-2 text-font-important-light text-sm dark:text-font-important-dark {% if label_class %} {{ label_class }}{% endif %}">
|
9
9
|
{{ field.label }}{% if field.field.required %} <span class="asteriskField">*</span>{% endif %}
|
@@ -1,13 +1,13 @@
|
|
1
1
|
{% load crispy_forms_field unfold %}
|
2
2
|
|
3
3
|
{% if form_show_labels %}
|
4
|
-
<label for="{{ field.id_for_label }}" class="flex flex-row gap-3 items-center">
|
4
|
+
<label for="{{ field.id_for_label }}" class="flex flex-row gap-3 items-center {% if tag == "td" %}mt-9{% endif %}">
|
5
5
|
{% crispy_field field 'class' form_classes.switch %} <span>{{ field.label }}{% if field.field.required %} <span class="asteriskField">*</span>{% endif %}</span>
|
6
6
|
</label>
|
7
7
|
|
8
8
|
{% include 'unfold_crispy/layout/help_text_and_errors.html' %}
|
9
9
|
{% else %}
|
10
|
-
{% with field=field|add_css_class:form_classes.
|
10
|
+
{% with field=field|add_css_class:form_classes.switch %}
|
11
11
|
{% if tag == "td" %}
|
12
12
|
<div class="flex items-center justify-center h-[38px]">
|
13
13
|
{% crispy_field field %}
|
@@ -1,9 +1,11 @@
|
|
1
1
|
<fieldset {% if fieldset.css_id %}id="{{ fieldset.css_id }}"{% endif %} class="fieldset group flex flex-col gap-5 grow rounded-default border-base-200 shadow-xs aligned border p-3 relative dark:border-base-800 {% if fieldset.css_class %} {{ fieldset.css_class }}{% endif %}" {{ fieldset.flat_attrs }}>
|
2
2
|
{% if legend %}
|
3
|
-
<legend class="border-b border-base-200 font-semibold float-left pb-3 -mx-3 px-3 text-font-important-light dark:text-font-important-dark dark:border-base-800">
|
3
|
+
<legend class="border-b border-base-200 font-semibold float-left pb-3 -mx-3 px-3 text-[15px] text-font-important-light dark:text-font-important-dark dark:border-base-800">
|
4
4
|
{{ legend|safe }}
|
5
5
|
</legend>
|
6
6
|
{% endif %}
|
7
7
|
|
8
|
-
|
8
|
+
<div class="flex flex-col gap-5">
|
9
|
+
{{ fields|safe }}
|
10
|
+
</div>
|
9
11
|
</fieldset>
|
@@ -15,20 +15,22 @@
|
|
15
15
|
{{ formset.management_form|crispy }}
|
16
16
|
|
17
17
|
<table class="w-full">
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
{%
|
24
|
-
|
25
|
-
{{ field.
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
18
|
+
{% if not form_show_labels %}
|
19
|
+
<thead>
|
20
|
+
{% if formset.readonly and not formset.queryset.exists %}
|
21
|
+
{% else %}
|
22
|
+
<tr>
|
23
|
+
{% for field in formset.forms.0 %}
|
24
|
+
{% if field.label and not field.is_hidden %}
|
25
|
+
<th for="{{ field.auto_id }}" class="align-middle font-semibold py-2 text-left text-font-important-light dark:text-font-important-dark whitespace-nowrap px-3 {% if field.name == "DELETE" %}w-0{% endif %}">
|
26
|
+
{{ field.label }}{% if field.field.required and not field|is_checkbox %} <span class="asteriskField">*</span>{% endif %}
|
27
|
+
</th>
|
28
|
+
{% endif %}
|
29
|
+
{% endfor %}
|
30
|
+
</tr>
|
31
|
+
{% endif %}
|
32
|
+
</thead>
|
33
|
+
{% endif %}
|
32
34
|
|
33
35
|
<tbody {% if formset_id %}id="{{ formset_id }}-rows"{% endif %}>
|
34
36
|
{% for form in formset %}
|
@@ -42,7 +44,7 @@
|
|
42
44
|
|
43
45
|
<tr>
|
44
46
|
{% for field in form %}
|
45
|
-
{% include 'unfold_crispy/field.html' with tag="td"
|
47
|
+
{% include 'unfold_crispy/field.html' with tag="td" %}
|
46
48
|
{% endfor %}
|
47
49
|
</tr>
|
48
50
|
{% endfor %}
|
@@ -52,7 +54,7 @@
|
|
52
54
|
<tbody>
|
53
55
|
<tr class="empty-form">
|
54
56
|
{% for field in formset.empty_form %}
|
55
|
-
{% include 'unfold_crispy/field.html' with tag="td"
|
57
|
+
{% include 'unfold_crispy/field.html' with tag="td" %}
|
56
58
|
{% endfor %}
|
57
59
|
</tr>
|
58
60
|
|
unfold/templatetags/unfold.py
CHANGED
@@ -4,7 +4,7 @@ from typing import Any, Optional, Union
|
|
4
4
|
|
5
5
|
from django import template
|
6
6
|
from django.contrib.admin.helpers import AdminForm, Fieldset
|
7
|
-
from django.contrib.admin.views.main import ChangeList
|
7
|
+
from django.contrib.admin.views.main import PAGE_VAR, ChangeList
|
8
8
|
from django.contrib.admin.widgets import RelatedFieldWidgetWrapper
|
9
9
|
from django.db.models import Model
|
10
10
|
from django.db.models.options import Options
|
@@ -108,6 +108,20 @@ def class_name(value: Any) -> str:
|
|
108
108
|
return value.__class__.__name__
|
109
109
|
|
110
110
|
|
111
|
+
@register.filter
|
112
|
+
def is_list(value: Any) -> str:
|
113
|
+
return isinstance(value, list)
|
114
|
+
|
115
|
+
|
116
|
+
@register.filter
|
117
|
+
def has_active_item(items: list[dict]) -> bool:
|
118
|
+
for item in items:
|
119
|
+
if "active" in item and item["active"]:
|
120
|
+
return True
|
121
|
+
|
122
|
+
return False
|
123
|
+
|
124
|
+
|
111
125
|
@register.filter
|
112
126
|
def index(indexable: Mapping[int, Any], i: int) -> Any:
|
113
127
|
try:
|
@@ -555,3 +569,8 @@ def changeform_condition(field: BoundField) -> BoundField:
|
|
555
569
|
field.field.field.widget.attrs["x-model.fill"] = field.field.name
|
556
570
|
|
557
571
|
return field
|
572
|
+
|
573
|
+
|
574
|
+
@register.simple_tag
|
575
|
+
def infinite_paginator_url(cl, i):
|
576
|
+
return cl.get_query_string({PAGE_VAR: i})
|
unfold/utils.py
CHANGED
@@ -150,7 +150,7 @@ def hex_to_rgb(hex_color: str) -> list[int]:
|
|
150
150
|
return (r, g, b)
|
151
151
|
|
152
152
|
|
153
|
-
def prettify_json(data: Any) -> Optional[str]:
|
153
|
+
def prettify_json(data: Any, encoder: Any) -> Optional[str]:
|
154
154
|
try:
|
155
155
|
from pygments import highlight
|
156
156
|
from pygments.formatters import HtmlFormatter
|
@@ -167,7 +167,7 @@ def prettify_json(data: Any) -> Optional[str]:
|
|
167
167
|
)
|
168
168
|
return highlight(response, JsonLexer(), formatter)
|
169
169
|
|
170
|
-
response = json.dumps(data, sort_keys=True, indent=4)
|
170
|
+
response = json.dumps(data, sort_keys=True, indent=4, cls=encoder)
|
171
171
|
|
172
172
|
return mark_safe(
|
173
173
|
f'<div class="block dark:hidden">{format_response(response, "colorful")}</div>'
|
unfold/widgets.py
CHANGED
@@ -123,9 +123,10 @@ TEXTAREA_EXPANDABLE_CLASSES = [
|
|
123
123
|
|
124
124
|
SELECT_CLASSES = [
|
125
125
|
*BASE_INPUT_CLASSES,
|
126
|
-
"pr-8",
|
126
|
+
"pr-8!",
|
127
127
|
"max-w-2xl",
|
128
128
|
"appearance-none",
|
129
|
+
"truncate",
|
129
130
|
]
|
130
131
|
|
131
132
|
PROSE_CLASSES = [
|
@@ -168,7 +169,7 @@ CHECKBOX_CLASSES = [
|
|
168
169
|
"dark:border-base-500",
|
169
170
|
"dark:checked:after:text-white",
|
170
171
|
"focus:outline",
|
171
|
-
"focus:outline-
|
172
|
+
"focus:outline-2",
|
172
173
|
"focus:outline-offset-2",
|
173
174
|
"focus:outline-primary-500",
|
174
175
|
"after:absolute",
|
@@ -210,7 +211,7 @@ RADIO_CLASSES = [
|
|
210
211
|
"dark:border-base-500",
|
211
212
|
"hover:border-base-400",
|
212
213
|
"focus:outline",
|
213
|
-
"focus:outline-
|
214
|
+
"focus:outline-2",
|
214
215
|
"focus:outline-offset-2",
|
215
216
|
"focus:outline-primary-500",
|
216
217
|
"after:absolute",
|
@@ -759,8 +760,13 @@ try:
|
|
759
760
|
template_name = "unfold/widgets/split_money.html"
|
760
761
|
|
761
762
|
def __init__(self, *args, **kwargs):
|
763
|
+
if "attrs" in kwargs:
|
764
|
+
attrs = kwargs.pop("attrs")
|
765
|
+
else:
|
766
|
+
attrs = {}
|
767
|
+
|
762
768
|
super().__init__(
|
763
|
-
amount_widget=UnfoldAdminTextInputWidget,
|
769
|
+
amount_widget=UnfoldAdminTextInputWidget(attrs=attrs),
|
764
770
|
currency_widget=UnfoldAdminSelectWidget(
|
765
771
|
choices=CURRENCY_CHOICES,
|
766
772
|
attrs={
|
File without changes
|
File without changes
|