From 48e3610c3a36e8e28232bf4d93553531d557087b Mon Sep 17 00:00:00 2001 From: Viliam Mihalik Date: Mon, 27 Apr 2026 13:53:04 +0200 Subject: [PATCH 1/6] feat: added fitDataStretchGrow layout and widthGrow support for Tabulator --- src/django_smartbase_admin/engine/field.py | 6 ++ .../static/sb_admin/src/css/_tabulator.css | 2 +- .../static/sb_admin/src/js/table.js | 2 + .../fit_data_stretch_grow.js | 70 +++++++++++++++++++ 4 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 src/django_smartbase_admin/static/sb_admin/src/js/tabulator_layouts/fit_data_stretch_grow.js 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/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..4b8ef698 --- /dev/null +++ b/src/django_smartbase_admin/static/sb_admin/src/js/tabulator_layouts/fit_data_stretch_grow.js @@ -0,0 +1,70 @@ +// 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 + + if(targetCol) { + gap = tableWidth - colsWidth + targetCol.getWidth() + + if(this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) { + targetCol.setWidth(0) + this.table.modules.responsiveLayout.update() + } + + if(gap > 0) { + targetCol.setWidth(gap) + targetCol.modules.fitDataStretchGrowWidth = true + } else { + targetCol.reinitializeWidth() + } + } else if(this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) { + this.table.modules.responsiveLayout.update() + } +} From ada6e57f36a40ff5c69e00888de851d1a1ff8589 Mon Sep 17 00:00:00 2001 From: Viliam Mihalik Date: Mon, 27 Apr 2026 14:17:37 +0200 Subject: [PATCH 2/6] feat: added fitDataStretchGrow layout and widthGrow support for Tabulator --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 1a96efb1..87ce7bc9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "django-smartbase-admin" -version = "1.1.12" +version = "1.1.13b1" description = "" authors = ["SmartBase "] readme = "README.md" From ce1dd8017f6c41ad07d1e9108dbe41cb39d4715c Mon Sep 17 00:00:00 2001 From: Viliam Mihalik Date: Wed, 29 Apr 2026 15:05:54 +0200 Subject: [PATCH 3/6] Update translation files for multiple languages --- .../locale/cs/LC_MESSAGES/django.mo | Bin 19740 -> 19771 bytes .../locale/cs/LC_MESSAGES/django.po | 12 ++++++++++-- .../locale/de/LC_MESSAGES/django.po | 12 ++++++++++-- .../locale/en/LC_MESSAGES/django.po | 10 ++++++++-- .../locale/fr/LC_MESSAGES/django.po | 10 ++++++++-- .../locale/hr/LC_MESSAGES/django.po | 10 ++++++++-- .../locale/hu/LC_MESSAGES/django.po | 10 ++++++++-- .../locale/it/LC_MESSAGES/django.mo | Bin 0 -> 380 bytes .../locale/it/LC_MESSAGES/django.po | 10 ++++++++-- .../locale/pl/LC_MESSAGES/django.po | 10 ++++++++-- .../locale/ro/LC_MESSAGES/django.po | 10 ++++++++-- .../locale/sk/LC_MESSAGES/django.mo | Bin 17085 -> 17172 bytes .../locale/sk/LC_MESSAGES/django.po | 12 ++++++++++-- .../locale/sl/LC_MESSAGES/django.mo | Bin 0 -> 432 bytes .../locale/sl/LC_MESSAGES/django.po | 10 ++++++++-- 15 files changed, 94 insertions(+), 22 deletions(-) create mode 100644 src/django_smartbase_admin/locale/it/LC_MESSAGES/django.mo create mode 100644 src/django_smartbase_admin/locale/sl/LC_MESSAGES/django.mo 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 0f61a848c60eba09ab9a0794c8ed5e40d5b479ee..e94cf90fe2f8f5d5f6b8f1657499b3e25a77b9d8 100644 GIT binary patch delta 5821 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 delta 5803 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, 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 0000000000000000000000000000000000000000..71cbdf3e9d8d54be31066ec4ad8628bc2c1f2845 GIT binary patch literal 380 zcmYL@K~KUk7=|%=+R?Lz&%}d9i{c3jGZa>EvE7z2Nc2{r&Y96JZ6W$Y{CoZuJ5A(G zp7i_Dx9RhJeDu}vIq;l#&OC>nD^HugXY4QU{MmN?lNtRkR}RH%w3NnHT4Bh@vF%H^(V-=Ii1iQ$Qo9Pt!I1Rhe%oml#`f^NEGFCKEL->Rc=KoQ6a?!10%_7(V7ey8`V`;n{war z20Z3;uifk31QV^CRQ|iq#``$=;jWunRB8aLH({)F;i8zL{=V00y-I_qTIqGAN(}v% i$^}`yHKImSZ8jEzYJOK6-VWez49^vuhS0kh1f3tbb!oc* literal 0 HcmV?d00001 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 6a443ee99e8e075de0804225247d9208a6022737..1005dcf3a6950459055e45400f7117d79561676c 100644 GIT binary patch delta 4861 zcmZA43slzi9mnw>a)|;|P(YJN1%VI^QxwA#5z|N=%p0j$SV&M_$_qoICpBtrQ>Wpj zR_3MBS(HTKCDF=DVTrnFO@roUTAi}Y)9Gw!+uon&|E1&E|McPY`~4oC-~D;8hN^(- zCj)$+MFp*PJS`-S1YP4?-vH;niBPL^JENSNkGt?Zrgv~I4`Vwz*NoFJ2!}*F7m2wz z9VcKXY`_rw7z42dHO@b%U@J{8r`Y^=n&_yk_U zBrK10PIF(6>gQFn4mHu;*cSI;DC4^(Yxo59hV$kHyn*@;7=}?ShfQ$tW*=k)E*E>^ zIMjq6$KJRKHPE}L_aDPxY)1Zb|Kvwc#&?(Ph2+lO0KHHUcP2<3voub*O<4VmN+e^;2=|zb0^o26+*+McQ}0Aq2H`5vU#Mj5D!2 zYQUAK39P{c+=$#qcMw^FJB?fm_XEGABpI;x~WN3j^yVVfJh9f?2< zoQ68f4Acs8Q4=e$`rT$3>L|)l3t417h25zyL+#vl)Hr*66tvPtRL95cg%)f7()9MaVrAPiNHL=7B+8lWqxzuu@7XQ2ihhFZ`VRJ(7YHQa;h=mAtmGq4SoqqcGZ z>h@QoK8{<=ov8Lkt2d)|>H=zjE2ujW#KloP2GxH&vLK&Jp`bTpqPA=V_Q27YjdL&` z-^8UD%s$?VD^L?YjM|x_sFnX6wekz7o&CuS;DYGLLQxaxh~YZ)I0~BKO{j@vp|&ay zHNbeQPeNU;V)X9_s>5p3iZ-AI-e&DPP!rgX>i;n6_nJ}tpO=j9zNes$uGlYxCVFp( zLhVQ*s-slYR`)@zAlKSQ;b7`xkx!~yg}U`MI1dk?`ni>DEyQfp9e4(PZ76J_5R5OO zX7&ndCH2UcpWBb>@KfaL-(5oOL`agiV_i_cpNc^^z#L@lLs2UqWA#FNy*P>e*Bi@d zScc^og2BmNN8uPqJrZ@s(YP3UAlJcd#WFmMw_!$#w*zx9mHKkj`*)%GZ9t880JYHL zDeV6>6q;$!%sWgMlFK2& zgF4&iQAfHJ)o%@I0dJu$?+2Km&wmSr5*h+-;pSs0PQ~cHd@^t@YR0ksycOl31}H$S zYzpdAQH-}^1!mwosEPfE`o8!XwV+sD?11|;ws-B8k$zar-7>nBKBGmg!kp(JZwMEKk(iE}SdP`lquyVF+JSi(gO#YQuSWH=9<|UKbC-{T zF3~~M08KaozriWkFU$L!uf##ryYNF3F2qha71d!mYQQC^{+_k=&DQ=pY66E)M{&|# z_nouC_o%J;8P&mce4lEC9Z)-wgo&7gdc6d72WF%0$P=ied=9nMwHS?iP&@M%)WB!V zi%9?MKYzM3vks^MyQ2okK%MzuRL8@ty%7DE47si0gxId}%OQ{#p>HyJ0P zCQy(16dl4Kjo(N?TiApe_%v#3&!R5R71V$c+1^B>QSFJS4l_{iAC5Zf0@Th-M%|TJ zsGV4ZdVMWw!5gvAM`1e!-Rf(HdY7*~YULeKJJJ~+!8DA+7jPl&K|cB}GsnCAGm%|& zOECc7M;%2Y>IhGu`n!mlNZ>H`Ujs)_&>ND;cJdUdB=3>Vk(( zOUNr^Eg4JntR~e&lhQMh>?TKv7L@Nle+sQn0fj%3ENl2Z{(+PeZK-x^B+)aD6#7fv zzXzKsk0B3O+tu7aMR#MoHR@j6?Jv{gDQo&=h z`ply+oy3rq)<)bkFdsJu;Cyl;nM=A6JqJA8-|!{U+v=mRo~$5$ zA~VVF$Va4@q>~v$&mNs9m(l!g(EIZmGSm%Ja#to&=7 zbXEI@l>3qwNO!W4EGPQT_~rhMruaTNtTvuwB*96i^&F3LRz2atk4TzCNGi{(usUZ z29i67o^Udl+@%Un5E(`^zW;fZpIfbbyEzR*t$dT&%3mqmX_d)XMqVR<))s{|B#vw* zBZ!{$ bOXd}o6xW@Nuk93^SG1tw!Mdjhq=x+uCH&J6 delta 4787 zcmYk<3shBA9>?*GfJ)*6=Bi*m2=j`9kBoc+zKb!t$F$uiMO^MM(X;%U+x3DQiM z(#&2%`C!Zu#qu?jVvXitnHEiHvsPtkFJrCB!tDFI=WlVAKR$c!d+$Db|IaxWEL|41 z_u(+_WNbv4lQ}8rAD2b6YJdlI2S*|&v6Xa{=xrDhk$bt^nbt@Y`|&Q zs;zTzI3JnPt-x?BL!D<0wsy{QRWzD2aL`_;MSb8))P(ie1|!?~{dTB{lCTg{a4BxW zAogkRoYtO&nrEsx1GUgRY=!yQob$V7Hn0-)f%RrNcA{T_E$|Ssd3VD60@;CUz+{YO zyISx-?2ThkCn`XFemO>BDe}*)h*ZkjuJ5n zyIcP%v%ifGK~-!xYJ;Ou3mu1^b})rTXUxO7xC*ymcnAMlZo?Po$6xN;6}T5w;!}7T zeuY}dkEn?+UtI0?D`Tp_Xt_c(G}xC-PWZa=D`A7dtd-ii8aqHEZ`F2!Kfgu74`so{sN z;U}n-*P|BXy7>KQGahvbf~XDjHTz>C{cBMbn~a+OUQ|UEcr-Mz)C(o{!V~6tRAtIh z3*CV_!7l4pqfT6dIzcUJzK>8lJ%gI}J5&WP*m%hIaHlcEbkDz(nq}ad;;d z;dUI1>C{sTE^)~)9rqge7rE@%??t0YSo`dso9%`O1a3X$#x(7y4<|a5EJ-y);8d_O4 zYA3nKmzv8%P521%b?=@-RbmIKVuw)gufquZ%sgx3-=cPY!TQaD{`&%`&&3C+|D!a5 z3}~m@?G3vzoPIUx8Xv%i@Lkjw(1h;J-Gc>~hM%A+keK9LPfSC7{w{2aGf^j;huY|a zs7e+mQGcy`H3Mm3d=cRy`X_og_cPwiY?(MVnO{h_4mEL6ihrpd#k=W0gZhGr>gAU_ zh&n+EYQd?fie{lIHw$?ZU7<%qC3+h9x_2*`)u<2Dp(Z+q3-LS_;r!mtCE!JDi3xrD z6ZgjE^i$0=hp_G3n@k|pcHj!HlY@B9ND1fPSMZ;elRcE8=76^zcB`*dHr(KW0z#( zsi*tvFp|TiVvc8 zbPja_m+J4V1*$>;9DzxA4bDa_tQ_@yQGwd=K@8wg3{?^%_59b<(8TAl4Ms4FO4$~( zup8=mU4*KDhe0ex?PMEr-?|glzi4*t@1J-iYM${Ji5svAx1gue<__@h(md2nSBlzM z1*&w_)<1>;`lnGlXh4SjHM{6==s+=2RBGU|lssQJdCHkfVW(@_;zfI9EuLDXN* za|r|d(c&IMt+WC=;ckqOR8fBP+A7K#=9>O0DcmTEHFgkJA3^ic_>Vzq%35VHurj1WTEnqh4QY^ODSD0&2 zmGNGrp$RHcJKTe+L@i#4XYKVie9!8hh{yKW3w14rqe`8PZ7~;BnT4nm7ny5N^KV2g zY>(gf++iA8z)93KKaHCBOB)a4S6t{OLvC0Xi#>5P>V5a&JS;+0>H^-1;n(>Kn2dUQ zW~1iMLsc*zLx2A-p`p^2pl+UW)CsFlE8S<~M^HODiJIVR)V2NzRhftk|6YkhRiY>A z^$gTJV{jr)LfzEcFx;c@Dh;h{FRDbZV;&yIjyURi|GPgId9>aCu>-ar>i_oZhhg;R zpe{uo>Jk>B=39eWNCoP|RjBv(Bc2Aj5na>iWHDiWx0R^OI(W)lU8vt^(M|Otd4#-8Mv!-jjyuQ$MBfqrC0#gw=s%OybhzSa|KUe(@`QREdJ=TB^$Gpt zNemrp%u5`j@uYR`!{$O&fpz(rvblfj^PH, 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 0000000000000000000000000000000000000000..9ab5259e78c67528f53109ee4826bb4a6342570e GIT binary patch literal 432 zcmYL@%TB{E6hw<)l_hHycL5RzT>4s+w1Jw&EfINC=|h5@X-x=9?Z|N}kop_^9^b+Z z6=b9%do*KtzK@T-YN!L`1UW?xkt?KB7ujNXgJ;?K*F>v#u{6Y6k%iDjs-z7QI((#K z1`8HXy(qL|kt=OTP$cP!+;5VC%#;n*BqFicrsW&rawBYbVl*Z}L|h6FksWxK&r!%M zpBIMAG?zujjnX!Z=DrUh4H)!UKs|pzT{mXa=`B`evf+s!Gr`w3_%s~P%O!o^A7p7= z>7?r5g1`${HM?1FSVJX^koetaj(d#wFxPp;Q`v*%8`p&}&U`i^-Ktm4dKH>5xm2rE zCN^|mQe#cBjpi8{DZMUikom7IoK6q+SLa-wH5(1bX~G>e04sajLffot8+N, 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 "" From 1bdda684bee8250b86f78dbce175e6083e586e27 Mon Sep 17 00:00:00 2001 From: Viliam Mihalik Date: Wed, 29 Apr 2026 17:17:20 +0200 Subject: [PATCH 4/6] chore: bump version to 1.1.13b2 and update nested plugin for improved sorting with Subquery --- pyproject.toml | 2 +- src/django_smartbase_admin/plugins/nested.py | 9 +++++++-- .../src/js/tabulator_layouts/fit_data_stretch_grow.js | 7 ++++--- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 87ce7bc9..1a96b439 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "django-smartbase-admin" -version = "1.1.13b1" +version = "1.1.13b2" description = "" authors = ["SmartBase "] readme = "README.md" diff --git a/src/django_smartbase_admin/plugins/nested.py b/src/django_smartbase_admin/plugins/nested.py index 9d46d385..946864e9 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, Q, OuterRef, Subquery from django.db.models.functions import Coalesce from django_smartbase_admin.plugins.base import SBAdminPlugin @@ -384,13 +384,18 @@ 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] = 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/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 index 4b8ef698..bf6c403f 100644 --- 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 @@ -49,20 +49,21 @@ function fitDataStretchGrow(columns) { }) const targetCol = stretchCol || lastCol + const naturalColWidth = targetCol ? targetCol.getWidth() : 0 if(targetCol) { - gap = tableWidth - colsWidth + targetCol.getWidth() + gap = tableWidth - colsWidth + naturalColWidth if(this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) { targetCol.setWidth(0) this.table.modules.responsiveLayout.update() } - if(gap > 0) { + if(gap > naturalColWidth) { targetCol.setWidth(gap) targetCol.modules.fitDataStretchGrowWidth = true } else { - targetCol.reinitializeWidth() + targetCol.setWidth(naturalColWidth) } } else if(this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) { this.table.modules.responsiveLayout.update() From 30a0dbe492325f9948a4b0bc9d9750d31f881b1b Mon Sep 17 00:00:00 2001 From: Viliam Mihalik Date: Wed, 29 Apr 2026 17:27:32 +0200 Subject: [PATCH 5/6] chore: bump version to 1.1.13b2 and update nested plugin for improved sorting with Subquery --- src/django_smartbase_admin/plugins/nested.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/django_smartbase_admin/plugins/nested.py b/src/django_smartbase_admin/plugins/nested.py index 946864e9..926320e9 100644 --- a/src/django_smartbase_admin/plugins/nested.py +++ b/src/django_smartbase_admin/plugins/nested.py @@ -392,7 +392,9 @@ def _build_grouped_qs( field = expr.lstrip("-+") alias = f"_nested_sort_{idx}" visible_field = column_fields_map.get(field) - sort_parent_qs = action.get_data_queryset(visible_fields=[visible_field] if visible_field else []) + sort_parent_qs = action.get_data_queryset( + visible_fields=[visible_field] if visible_field else [] + ) sort_annotations[alias] = Subquery( sort_parent_qs.filter(id=OuterRef("parent_real_id")).values(field)[:1] ) From 73ace77d51da8bc7ee10a05d3d4875a337625aa1 Mon Sep 17 00:00:00 2001 From: Viliam Mihalik Date: Wed, 29 Apr 2026 18:19:56 +0200 Subject: [PATCH 6/6] fix: update nested plugin to use Max aggregation to prevent duplication of rows --- pyproject.toml | 2 +- src/django_smartbase_admin/plugins/nested.py | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 1a96b439..4b79718b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "django-smartbase-admin" -version = "1.1.13b2" +version = "1.1.13b3" description = "" authors = ["SmartBase "] readme = "README.md" diff --git a/src/django_smartbase_admin/plugins/nested.py b/src/django_smartbase_admin/plugins/nested.py index 926320e9..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 F, Q, OuterRef, Subquery +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 @@ -395,8 +395,12 @@ def _build_grouped_qs( sort_parent_qs = action.get_data_queryset( visible_fields=[visible_field] if visible_field else [] ) - sort_annotations[alias] = Subquery( - sort_parent_qs.filter(id=OuterRef("parent_real_id")).values(field)[:1] + 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)