diff --git a/pyproject.toml b/pyproject.toml index 1a96efb1..4b79718b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "django-smartbase-admin" -version = "1.1.12" +version = "1.1.13b3" description = "" authors = ["SmartBase "] readme = "README.md" diff --git a/src/django_smartbase_admin/engine/field.py b/src/django_smartbase_admin/engine/field.py index 2f97e857..b8339174 100644 --- a/src/django_smartbase_admin/engine/field.py +++ b/src/django_smartbase_admin/engine/field.py @@ -37,6 +37,8 @@ class TabulatorFieldOptions(JSONSerializableMixin): frozen = False title = None editorParams = None + width = None + widthGrow = None def __init__( self, @@ -46,6 +48,8 @@ def __init__( frozen=None, title=None, editorParams=None, + width=None, + widthGrow=None, ) -> None: super().__init__() self.headerFilter = headerFilter @@ -54,6 +58,8 @@ def __init__( self.frozen = frozen self.title = title self.editorParams = editorParams + self.width = width + self.widthGrow = widthGrow class XLSXFieldOptions(JSONSerializableMixin): diff --git a/src/django_smartbase_admin/locale/cs/LC_MESSAGES/django.mo b/src/django_smartbase_admin/locale/cs/LC_MESSAGES/django.mo index 0f61a848..e94cf90f 100644 Binary files a/src/django_smartbase_admin/locale/cs/LC_MESSAGES/django.mo and b/src/django_smartbase_admin/locale/cs/LC_MESSAGES/django.mo differ diff --git a/src/django_smartbase_admin/locale/cs/LC_MESSAGES/django.po b/src/django_smartbase_admin/locale/cs/LC_MESSAGES/django.po index 0f4205ba..4dd7c5d1 100644 --- a/src/django_smartbase_admin/locale/cs/LC_MESSAGES/django.po +++ b/src/django_smartbase_admin/locale/cs/LC_MESSAGES/django.po @@ -2,13 +2,13 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. -# +# #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-16 11:52+0200\n" +"POT-Creation-Date: 2026-04-29 15:03+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: Czech \n" @@ -854,6 +854,11 @@ msgstr "Uložit a přidat další" msgid "Save and continue editing" msgstr "Uložit a pokračovat v úpravách" +#, fuzzy +#| msgid "Select all" +msgid "Select" +msgstr "Vybrat vše" + msgid "Add file" msgstr "Přidat soubor" @@ -969,3 +974,6 @@ msgstr "Stav" msgid " of " msgstr " z " + +msgid "Language" +msgstr "Jazyk" diff --git a/src/django_smartbase_admin/locale/de/LC_MESSAGES/django.po b/src/django_smartbase_admin/locale/de/LC_MESSAGES/django.po index f046b529..af9774a9 100644 --- a/src/django_smartbase_admin/locale/de/LC_MESSAGES/django.po +++ b/src/django_smartbase_admin/locale/de/LC_MESSAGES/django.po @@ -2,13 +2,13 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. -# +# #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-16 11:52+0200\n" +"POT-Creation-Date: 2026-04-29 15:03+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -852,6 +852,11 @@ msgstr "Speichern und weiteres hinzufügen" msgid "Save and continue editing" msgstr "Speichern und weiter bearbeiten" +#, fuzzy +#| msgid "Select all" +msgid "Select" +msgstr "Alle auswählen" + msgid "Add file" msgstr "Datei hinzufügen" @@ -964,3 +969,6 @@ msgstr "Status" msgid " of " msgstr " von " + +msgid "Language" +msgstr "" diff --git a/src/django_smartbase_admin/locale/en/LC_MESSAGES/django.po b/src/django_smartbase_admin/locale/en/LC_MESSAGES/django.po index 8306eeda..585c44cf 100644 --- a/src/django_smartbase_admin/locale/en/LC_MESSAGES/django.po +++ b/src/django_smartbase_admin/locale/en/LC_MESSAGES/django.po @@ -2,13 +2,13 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. -# +# #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-16 11:51+0200\n" +"POT-Creation-Date: 2026-04-29 15:03+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -821,6 +821,9 @@ msgstr "" msgid "Save and continue editing" msgstr "" +msgid "Select" +msgstr "" + msgid "Add file" msgstr "" @@ -933,3 +936,6 @@ msgstr "" msgid " of " msgstr "" + +msgid "Language" +msgstr "" diff --git a/src/django_smartbase_admin/locale/fr/LC_MESSAGES/django.po b/src/django_smartbase_admin/locale/fr/LC_MESSAGES/django.po index 69819945..297889a4 100644 --- a/src/django_smartbase_admin/locale/fr/LC_MESSAGES/django.po +++ b/src/django_smartbase_admin/locale/fr/LC_MESSAGES/django.po @@ -2,13 +2,13 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. -# +# #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-16 11:58+0200\n" +"POT-Creation-Date: 2026-04-29 15:03+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -821,6 +821,9 @@ msgstr "" msgid "Save and continue editing" msgstr "" +msgid "Select" +msgstr "" + msgid "Add file" msgstr "" @@ -933,3 +936,6 @@ msgstr "" msgid " of " msgstr "" + +msgid "Language" +msgstr "" diff --git a/src/django_smartbase_admin/locale/hr/LC_MESSAGES/django.po b/src/django_smartbase_admin/locale/hr/LC_MESSAGES/django.po index 26d14836..dbfed318 100644 --- a/src/django_smartbase_admin/locale/hr/LC_MESSAGES/django.po +++ b/src/django_smartbase_admin/locale/hr/LC_MESSAGES/django.po @@ -2,13 +2,13 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. -# +# #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-16 11:58+0200\n" +"POT-Creation-Date: 2026-04-29 15:03+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -821,6 +821,9 @@ msgstr "" msgid "Save and continue editing" msgstr "" +msgid "Select" +msgstr "" + msgid "Add file" msgstr "" @@ -933,3 +936,6 @@ msgstr "" msgid " of " msgstr "" + +msgid "Language" +msgstr "" diff --git a/src/django_smartbase_admin/locale/hu/LC_MESSAGES/django.po b/src/django_smartbase_admin/locale/hu/LC_MESSAGES/django.po index 3dbdd679..585c44cf 100644 --- a/src/django_smartbase_admin/locale/hu/LC_MESSAGES/django.po +++ b/src/django_smartbase_admin/locale/hu/LC_MESSAGES/django.po @@ -2,13 +2,13 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. -# +# #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-16 11:52+0200\n" +"POT-Creation-Date: 2026-04-29 15:03+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -821,6 +821,9 @@ msgstr "" msgid "Save and continue editing" msgstr "" +msgid "Select" +msgstr "" + msgid "Add file" msgstr "" @@ -933,3 +936,6 @@ msgstr "" msgid " of " msgstr "" + +msgid "Language" +msgstr "" diff --git a/src/django_smartbase_admin/locale/it/LC_MESSAGES/django.mo b/src/django_smartbase_admin/locale/it/LC_MESSAGES/django.mo new file mode 100644 index 00000000..71cbdf3e Binary files /dev/null and b/src/django_smartbase_admin/locale/it/LC_MESSAGES/django.mo differ diff --git a/src/django_smartbase_admin/locale/it/LC_MESSAGES/django.po b/src/django_smartbase_admin/locale/it/LC_MESSAGES/django.po index 3dbdd679..585c44cf 100644 --- a/src/django_smartbase_admin/locale/it/LC_MESSAGES/django.po +++ b/src/django_smartbase_admin/locale/it/LC_MESSAGES/django.po @@ -2,13 +2,13 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. -# +# #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-16 11:52+0200\n" +"POT-Creation-Date: 2026-04-29 15:03+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -821,6 +821,9 @@ msgstr "" msgid "Save and continue editing" msgstr "" +msgid "Select" +msgstr "" + msgid "Add file" msgstr "" @@ -933,3 +936,6 @@ msgstr "" msgid " of " msgstr "" + +msgid "Language" +msgstr "" diff --git a/src/django_smartbase_admin/locale/pl/LC_MESSAGES/django.po b/src/django_smartbase_admin/locale/pl/LC_MESSAGES/django.po index 3e46404e..44f314be 100644 --- a/src/django_smartbase_admin/locale/pl/LC_MESSAGES/django.po +++ b/src/django_smartbase_admin/locale/pl/LC_MESSAGES/django.po @@ -2,13 +2,13 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. -# +# #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-16 11:52+0200\n" +"POT-Creation-Date: 2026-04-29 15:03+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -821,6 +821,9 @@ msgstr "" msgid "Save and continue editing" msgstr "" +msgid "Select" +msgstr "" + msgid "Add file" msgstr "" @@ -933,3 +936,6 @@ msgstr "" msgid " of " msgstr "" + +msgid "Language" +msgstr "" diff --git a/src/django_smartbase_admin/locale/ro/LC_MESSAGES/django.po b/src/django_smartbase_admin/locale/ro/LC_MESSAGES/django.po index f8c453d9..e315f7f2 100644 --- a/src/django_smartbase_admin/locale/ro/LC_MESSAGES/django.po +++ b/src/django_smartbase_admin/locale/ro/LC_MESSAGES/django.po @@ -2,13 +2,13 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. -# +# #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-16 11:52+0200\n" +"POT-Creation-Date: 2026-04-29 15:03+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -821,6 +821,9 @@ msgstr "" msgid "Save and continue editing" msgstr "" +msgid "Select" +msgstr "" + msgid "Add file" msgstr "" @@ -933,3 +936,6 @@ msgstr "" msgid " of " msgstr "" + +msgid "Language" +msgstr "" diff --git a/src/django_smartbase_admin/locale/sk/LC_MESSAGES/django.mo b/src/django_smartbase_admin/locale/sk/LC_MESSAGES/django.mo index 6a443ee9..1005dcf3 100644 Binary files a/src/django_smartbase_admin/locale/sk/LC_MESSAGES/django.mo and b/src/django_smartbase_admin/locale/sk/LC_MESSAGES/django.mo differ diff --git a/src/django_smartbase_admin/locale/sk/LC_MESSAGES/django.po b/src/django_smartbase_admin/locale/sk/LC_MESSAGES/django.po index 3dc1614b..77e9f691 100644 --- a/src/django_smartbase_admin/locale/sk/LC_MESSAGES/django.po +++ b/src/django_smartbase_admin/locale/sk/LC_MESSAGES/django.po @@ -2,12 +2,12 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. -# +# msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-16 11:51+0200\n" +"POT-Creation-Date: 2026-04-29 15:03+0200\n" "PO-Revision-Date: 2023-11-15 15:21+0100\n" "Last-Translator: \n" "Language-Team: \n" @@ -847,6 +847,11 @@ msgstr "Uložiť a pridať ďalšie" msgid "Save and continue editing" msgstr "Uložiť a pokračovať v úpravách" +#, fuzzy +#| msgid "Select all" +msgid "Select" +msgstr "Vybrať všetky" + msgid "Add file" msgstr "Pridať súbor" @@ -959,3 +964,6 @@ msgstr "Stav" msgid " of " msgstr " z " + +msgid "Language" +msgstr "Jazyk" diff --git a/src/django_smartbase_admin/locale/sl/LC_MESSAGES/django.mo b/src/django_smartbase_admin/locale/sl/LC_MESSAGES/django.mo new file mode 100644 index 00000000..9ab5259e Binary files /dev/null and b/src/django_smartbase_admin/locale/sl/LC_MESSAGES/django.mo differ diff --git a/src/django_smartbase_admin/locale/sl/LC_MESSAGES/django.po b/src/django_smartbase_admin/locale/sl/LC_MESSAGES/django.po index 3d0341c3..02bf4f0b 100644 --- a/src/django_smartbase_admin/locale/sl/LC_MESSAGES/django.po +++ b/src/django_smartbase_admin/locale/sl/LC_MESSAGES/django.po @@ -2,13 +2,13 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. -# +# #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-16 11:52+0200\n" +"POT-Creation-Date: 2026-04-29 15:03+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -821,6 +821,9 @@ msgstr "" msgid "Save and continue editing" msgstr "" +msgid "Select" +msgstr "" + msgid "Add file" msgstr "" @@ -933,3 +936,6 @@ msgstr "" msgid " of " msgstr "" + +msgid "Language" +msgstr "" diff --git a/src/django_smartbase_admin/plugins/nested.py b/src/django_smartbase_admin/plugins/nested.py index 9d46d385..847b199c 100644 --- a/src/django_smartbase_admin/plugins/nested.py +++ b/src/django_smartbase_admin/plugins/nested.py @@ -46,7 +46,7 @@ from django.contrib.postgres.aggregates import ArrayAgg from django.core.exceptions import FieldDoesNotExist, ImproperlyConfigured -from django.db.models import Case, F, Max, Q, When +from django.db.models import F, Max, Q, OuterRef, Subquery from django.db.models.functions import Coalesce from django_smartbase_admin.plugins.base import SBAdminPlugin @@ -384,13 +384,24 @@ def _build_grouped_qs( # yields that parent's value — the group sorts by the # parent, not by any of its children. parent_row = Q(**{f"{parent_field}__isnull": True}) + column_fields_map = {cf.field: cf for cf in action.column_fields} sort_annotations: dict = {} new_order: list[str] = [] for idx, expr in enumerate(order_strings): desc = expr.startswith("-") field = expr.lstrip("-+") alias = f"_nested_sort_{idx}" - sort_annotations[alias] = Max(Case(When(parent_row, then=F(field)))) + visible_field = column_fields_map.get(field) + sort_parent_qs = action.get_data_queryset( + visible_fields=[visible_field] if visible_field else [] + ) + sort_annotations[alias] = Max( + Subquery( + sort_parent_qs.filter(id=OuterRef("parent_real_id")).values(field)[ + :1 + ] + ) + ) new_order.append(f"-{alias}" if desc else alias) return grouped.annotate(**sort_annotations).order_by(*new_order) diff --git a/src/django_smartbase_admin/static/sb_admin/src/css/_tabulator.css b/src/django_smartbase_admin/static/sb_admin/src/css/_tabulator.css index 9482e3a0..e5868b23 100644 --- a/src/django_smartbase_admin/static/sb_admin/src/css/_tabulator.css +++ b/src/django_smartbase_admin/static/sb_admin/src/css/_tabulator.css @@ -31,7 +31,7 @@ .tabulator.tabulator--sticky-header-and-footer .tabulator-header { position: sticky; top: 0; - z-index: 10; + z-index: 100; } .tabulator .tabulator-header.tabulator-header-hidden { diff --git a/src/django_smartbase_admin/static/sb_admin/src/js/table.js b/src/django_smartbase_admin/static/sb_admin/src/js/table.js index 3ddf2f8e..977ca04f 100644 --- a/src/django_smartbase_admin/static/sb_admin/src/js/table.js +++ b/src/django_smartbase_admin/static/sb_admin/src/js/table.js @@ -13,6 +13,7 @@ import { HeaderTabsModule } from "./table_modules/header_tabs_module" import { DataTreeModule } from "./table_modules/data_tree_module" import { StickyHeaderAndFooterModule } from "./table_modules/sticky_header_and_footer_module" import { SBAjaxParamsTabulatorModifier } from "./sb_ajax_params_tabulator_modifier" +import { registerFitDataStretchGrowLayout } from "./tabulator_layouts/fit_data_stretch_grow" class SBAdminTable { @@ -252,6 +253,7 @@ class SBAdminTable { return "" + cellContent + "" } }) + registerFitDataStretchGrowLayout(Tabulator, this.tabulatorOptions) this.defaultRowSelectionFormatter = Tabulator.moduleBindings.format.formatters.rowSelection const self = this diff --git a/src/django_smartbase_admin/static/sb_admin/src/js/tabulator_layouts/fit_data_stretch_grow.js b/src/django_smartbase_admin/static/sb_admin/src/js/tabulator_layouts/fit_data_stretch_grow.js new file mode 100644 index 00000000..bf6c403f --- /dev/null +++ b/src/django_smartbase_admin/static/sb_admin/src/js/tabulator_layouts/fit_data_stretch_grow.js @@ -0,0 +1,71 @@ +// Custom fitDataStretch variant: stretch the column marked with widthGrow instead of the last column. +// See https://github.com/olifolkerd/tabulator/issues/2725 and Tabulator's fitDataStretch layout. +export function registerFitDataStretchGrowLayout(Tabulator, tabulatorOptions) { + if(tabulatorOptions.layout !== "fitDataStretchGrow") { + return + } + + Tabulator.extendModule("layout", "modes", { + fitDataStretchGrow: fitDataStretchGrow + }) + + if(Tabulator.moduleBindings.layout?.modes) { + Tabulator.moduleBindings.layout.modes.fitDataStretchGrow = fitDataStretchGrow + } +} + + +function fitDataStretchGrow(columns) { + let colsWidth = 0, + tableWidth = this.table.rowManager.element.clientWidth, + gap = 0, + lastCol = false, + stretchCol = false + + columns.forEach((column) => { + if(column.modules.fitDataStretchGrowWidth) { + column.widthFixed = false + column.modules.fitDataStretchGrowWidth = false + } + + if(column.widthFixed && typeof column.definition.width === "undefined") { + column.widthFixed = false + } + + if(!column.widthFixed) { + column.reinitializeWidth() + } + + if(this.table.options.responsiveLayout ? column.modules.responsive.visible : column.visible) { + lastCol = column + if(column.definition.widthGrow) { + stretchCol = column + } + } + + if(column.visible) { + colsWidth += column.getWidth() + } + }) + + const targetCol = stretchCol || lastCol + const naturalColWidth = targetCol ? targetCol.getWidth() : 0 + + if(targetCol) { + gap = tableWidth - colsWidth + naturalColWidth + + if(this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) { + targetCol.setWidth(0) + this.table.modules.responsiveLayout.update() + } + + if(gap > naturalColWidth) { + targetCol.setWidth(gap) + targetCol.modules.fitDataStretchGrowWidth = true + } else { + targetCol.setWidth(naturalColWidth) + } + } else if(this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) { + this.table.modules.responsiveLayout.update() + } +}