xladmin 0.3.7 → 0.5.0

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.
package/dist/index.js CHANGED
@@ -53,6 +53,32 @@ function createAdminClient(transport) {
53
53
  payload != null ? payload : {}
54
54
  );
55
55
  },
56
+ async getBulkActionChoices(slug, actionSlug, fieldName, q, ids, options) {
57
+ return await transportGet(
58
+ transport,
59
+ `/xladmin/models/${slug}/bulk-actions/${actionSlug}/fields/${fieldName}/choices/`,
60
+ {
61
+ signal: options == null ? void 0 : options.signal,
62
+ params: {
63
+ ...q ? { q } : {},
64
+ ...ids && ids.length > 0 ? { ids: ids.join(",") } : {}
65
+ }
66
+ }
67
+ );
68
+ },
69
+ async getObjectActionChoices(slug, id, actionSlug, fieldName, q, ids, options) {
70
+ return await transportGet(
71
+ transport,
72
+ `/xladmin/models/${slug}/items/${id}/actions/${actionSlug}/fields/${fieldName}/choices/`,
73
+ {
74
+ signal: options == null ? void 0 : options.signal,
75
+ params: {
76
+ ...q ? { q } : {},
77
+ ...ids && ids.length > 0 ? { ids: ids.join(",") } : {}
78
+ }
79
+ }
80
+ );
81
+ },
56
82
  async getChoices(slug, fieldName, q, ids, options) {
57
83
  return await transportGet(
58
84
  transport,
@@ -302,7 +328,7 @@ function handleNavLinkClick(event, { href, onClick, router }) {
302
328
  }
303
329
 
304
330
  // src/components/FormDialog.tsx
305
- import { useEffect as useEffect4, useMemo as useMemo5, useState as useState4 } from "react";
331
+ import { useEffect as useEffect4, useMemo as useMemo5, useRef as useRef4, useState as useState4 } from "react";
306
332
  import { Alert, Box as Box2, Button, Dialog, DialogActions, DialogContent, DialogTitle } from "@mui/material";
307
333
  import { LocalizationProvider } from "@mui/x-date-pickers";
308
334
  import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
@@ -455,6 +481,7 @@ function useAdminTranslation() {
455
481
  }
456
482
 
457
483
  // src/utils/adminFields.ts
484
+ import dayjs from "dayjs";
458
485
  function buildAdminPayload(values, fields) {
459
486
  const fieldMap = new Map(fields.map((field) => [field.name, field]));
460
487
  const payload = {};
@@ -477,6 +504,26 @@ function buildAdminPayload(values, fields) {
477
504
  }
478
505
  return payload;
479
506
  }
507
+ function buildAdminFormInitialValues(fields, initialValues) {
508
+ var _a, _b, _c, _d;
509
+ const values = { ...initialValues != null ? initialValues : {} };
510
+ for (const field of fields) {
511
+ if (values[field.name] === void 0 && field.required && field.input_kind === "select" && ((_b = (_a = field.options) == null ? void 0 : _a.length) != null ? _b : 0) > 0) {
512
+ values[field.name] = (_d = (_c = field.options) == null ? void 0 : _c[0]) == null ? void 0 : _d.value;
513
+ }
514
+ if (!field.auto_now || values[field.name] !== void 0) {
515
+ continue;
516
+ }
517
+ if (field.input_kind === "date") {
518
+ values[field.name] = dayjs().format("YYYY-MM-DD");
519
+ continue;
520
+ }
521
+ if (field.input_kind === "datetime") {
522
+ values[field.name] = dayjs().format("YYYY-MM-DD[T]HH:mm:ss");
523
+ }
524
+ }
525
+ return values;
526
+ }
480
527
  function formatAdminValue(value, options) {
481
528
  const locale = normalizeAdminLocale(options == null ? void 0 : options.locale);
482
529
  const maxLength = options == null ? void 0 : options.maxLength;
@@ -603,11 +650,21 @@ function trimAdminValue(value, maxLength) {
603
650
  return `${value.slice(0, maxLength).trimEnd()}\u2026`;
604
651
  }
605
652
 
653
+ // src/utils/pickersLocale.ts
654
+ import { enUS, ruRU } from "@mui/x-date-pickers/locales";
655
+ var pickersLocaleTextByLocale = {
656
+ en: enUS.components.MuiLocalizationProvider.defaultProps.localeText,
657
+ ru: ruRU.components.MuiLocalizationProvider.defaultProps.localeText
658
+ };
659
+ function getMuiPickersLocaleText(locale) {
660
+ return pickersLocaleTextByLocale[locale];
661
+ }
662
+
606
663
  // src/components/FieldEditor.tsx
607
664
  import { memo, useCallback, useEffect as useEffect2, useMemo as useMemo3, useState as useState2 } from "react";
608
- import { Autocomplete, CircularProgress, FormControlLabel, Switch, TextField } from "@mui/material";
665
+ import { Autocomplete, CircularProgress, FormControlLabel, MenuItem, Switch, TextField } from "@mui/material";
609
666
  import { DatePicker, DateTimePicker } from "@mui/x-date-pickers";
610
- import dayjs from "dayjs";
667
+ import dayjs2 from "dayjs";
611
668
 
612
669
  // src/hooks/useRemoteChoices.ts
613
670
  import { useEffect, useRef as useRef2, useState } from "react";
@@ -695,23 +752,53 @@ function isAbortReason(reason) {
695
752
 
696
753
  // src/components/FieldEditor.tsx
697
754
  import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
755
+ var DEFAULT_CHOICE_SCOPE = { kind: "model" };
756
+ function handlePickerButtonMouseDown(event, hasAnotherPickerOpen, onRequestPickerOpen) {
757
+ if (!hasAnotherPickerOpen) {
758
+ return;
759
+ }
760
+ event.preventDefault();
761
+ event.stopPropagation();
762
+ onRequestPickerOpen == null ? void 0 : onRequestPickerOpen();
763
+ }
698
764
  var FieldEditor = memo(function FieldEditor2({
699
765
  field,
700
766
  value,
701
767
  onChange,
702
768
  slug,
703
769
  client,
704
- readOnly = false
770
+ choiceScope,
771
+ readOnly = false,
772
+ isPickerOpen,
773
+ hasAnotherPickerOpen = false,
774
+ onRequestPickerOpen,
775
+ onRequestPickerClose
705
776
  }) {
706
- var _a, _b, _c, _d;
777
+ var _a, _b, _c, _d, _e, _f, _g, _h;
707
778
  const t = useAdminTranslation();
708
779
  const [searchValue, setSearchValue] = useState2("");
709
780
  const [jsonTextValue, setJsonTextValue] = useState2(() => stringifyJsonValue(value));
710
781
  const [jsonError, setJsonError] = useState2(null);
782
+ const resolvedChoiceScope = choiceScope != null ? choiceScope : DEFAULT_CHOICE_SCOPE;
711
783
  const selectedIds = useMemo3(() => normalizeSelectedIds(value, field.is_relation_many), [field.is_relation_many, value]);
712
784
  const loadChoices = useCallback(
713
785
  async (signal) => {
714
- const response = await client.getChoices(
786
+ const response = resolvedChoiceScope.kind === "bulk-action" ? await client.getBulkActionChoices(
787
+ slug,
788
+ resolvedChoiceScope.actionSlug,
789
+ field.name,
790
+ searchValue || void 0,
791
+ selectedIds,
792
+ { signal }
793
+ ) : resolvedChoiceScope.kind === "object-action" ? await client.getObjectActionChoices(
794
+ slug,
795
+ resolvedChoiceScope.itemId,
796
+ resolvedChoiceScope.actionSlug,
797
+ field.name,
798
+ searchValue || void 0,
799
+ selectedIds,
800
+ { signal }
801
+ ) : await client.getChoices(
715
802
  slug,
716
803
  field.name,
717
804
  searchValue || void 0,
@@ -720,7 +807,17 @@ var FieldEditor = memo(function FieldEditor2({
720
807
  );
721
808
  return response.items;
722
809
  },
723
- [client, field.name, searchValue, selectedIds, slug]
810
+ [
811
+ client,
812
+ field.name,
813
+ resolvedChoiceScope.kind,
814
+ resolvedChoiceScope.kind === "bulk-action" ? resolvedChoiceScope.actionSlug : null,
815
+ resolvedChoiceScope.kind === "object-action" ? resolvedChoiceScope.actionSlug : null,
816
+ resolvedChoiceScope.kind === "object-action" ? resolvedChoiceScope.itemId : null,
817
+ searchValue,
818
+ selectedIds,
819
+ slug
820
+ ]
724
821
  );
725
822
  const { items: choices, isLoading: isLoadingChoices } = useRemoteChoices({
726
823
  enabled: field.has_choices,
@@ -742,6 +839,7 @@ var FieldEditor = memo(function FieldEditor2({
742
839
  return /* @__PURE__ */ jsx3(
743
840
  FormControlLabel,
744
841
  {
842
+ required: field.required,
745
843
  control: /* @__PURE__ */ jsx3(
746
844
  Switch,
747
845
  {
@@ -750,7 +848,8 @@ var FieldEditor = memo(function FieldEditor2({
750
848
  onChange: (_, checked) => onChange(checked)
751
849
  }
752
850
  ),
753
- label: field.label
851
+ label: field.label,
852
+ sx: buildRequiredLabelSx()
754
853
  }
755
854
  );
756
855
  }
@@ -760,17 +859,30 @@ var FieldEditor = memo(function FieldEditor2({
760
859
  {
761
860
  label: field.label,
762
861
  disabled: readOnly,
763
- value: value ? dayjs(String(value)) : null,
862
+ open: isPickerOpen,
863
+ value: value ? dayjs2(String(value)) : null,
864
+ onOpen: onRequestPickerOpen,
865
+ onClose: onRequestPickerClose,
764
866
  onChange: (nextValue) => onChange(nextValue ? nextValue.format("YYYY-MM-DD") : null),
765
867
  slotProps: {
766
868
  popper: { disablePortal: true },
767
869
  desktopPaper: buildPickerPaperProps(),
768
870
  mobilePaper: buildPickerPaperProps(),
871
+ openPickerButton: {
872
+ onMouseDown: (event) => handlePickerButtonMouseDown(event, hasAnotherPickerOpen, onRequestPickerOpen)
873
+ },
769
874
  textField: {
770
875
  fullWidth: true,
771
876
  size: "small",
877
+ required: field.required,
878
+ sx: buildRequiredLabelSx(),
772
879
  helperText: (_a = field.help_text) != null ? _a : void 0,
773
- slotProps: { htmlInput: buildHtmlInputProps(field) }
880
+ slotProps: {
881
+ htmlInput: {
882
+ ...buildHtmlInputProps(field),
883
+ placeholder: (_b = field.placeholder) != null ? _b : void 0
884
+ }
885
+ }
774
886
  }
775
887
  }
776
888
  }
@@ -782,22 +894,46 @@ var FieldEditor = memo(function FieldEditor2({
782
894
  {
783
895
  label: field.label,
784
896
  disabled: readOnly,
785
- value: value ? dayjs(String(value)) : null,
897
+ open: isPickerOpen,
898
+ value: value ? dayjs2(String(value)) : null,
899
+ onOpen: onRequestPickerOpen,
900
+ onClose: onRequestPickerClose,
786
901
  onChange: (nextValue) => onChange(nextValue ? nextValue.format("YYYY-MM-DD[T]HH:mm:ss") : null),
787
902
  slotProps: {
903
+ actionBar: {
904
+ actions: ["today", "cancel", "accept"]
905
+ },
788
906
  popper: { disablePortal: true },
789
907
  desktopPaper: buildPickerPaperProps(),
790
908
  mobilePaper: buildPickerPaperProps(),
909
+ openPickerButton: {
910
+ onMouseDown: (event) => handlePickerButtonMouseDown(event, hasAnotherPickerOpen, onRequestPickerOpen)
911
+ },
791
912
  textField: {
792
913
  fullWidth: true,
793
914
  size: "small",
794
- helperText: (_b = field.help_text) != null ? _b : void 0,
795
- slotProps: { htmlInput: buildHtmlInputProps(field) }
915
+ required: field.required,
916
+ sx: buildRequiredLabelSx(),
917
+ helperText: (_c = field.help_text) != null ? _c : void 0,
918
+ slotProps: {
919
+ htmlInput: {
920
+ ...buildHtmlInputProps(field),
921
+ placeholder: (_d = field.placeholder) != null ? _d : void 0
922
+ }
923
+ }
796
924
  }
797
925
  }
798
926
  }
799
927
  );
800
928
  }
929
+ if (hasStaticOptions(field)) {
930
+ return renderStaticChoiceEditor({
931
+ field,
932
+ value,
933
+ onChange,
934
+ readOnly
935
+ });
936
+ }
801
937
  if (field.has_choices) {
802
938
  return renderChoiceEditor({
803
939
  field,
@@ -837,7 +973,10 @@ var FieldEditor = memo(function FieldEditor2({
837
973
  multiline: true,
838
974
  minRows: 6,
839
975
  error: jsonError !== null,
840
- helperText: (_c = jsonError != null ? jsonError : field.help_text) != null ? _c : void 0,
976
+ required: field.required,
977
+ sx: buildRequiredLabelSx(),
978
+ helperText: (_e = jsonError != null ? jsonError : field.help_text) != null ? _e : void 0,
979
+ placeholder: (_f = field.placeholder) != null ? _f : void 0,
841
980
  slotProps: {
842
981
  htmlInput: buildHtmlInputProps(field)
843
982
  }
@@ -853,7 +992,10 @@ var FieldEditor = memo(function FieldEditor2({
853
992
  size: "small",
854
993
  fullWidth: true,
855
994
  disabled: readOnly,
856
- helperText: (_d = field.help_text) != null ? _d : void 0,
995
+ required: field.required,
996
+ sx: buildRequiredLabelSx(),
997
+ helperText: (_g = field.help_text) != null ? _g : void 0,
998
+ placeholder: (_h = field.placeholder) != null ? _h : void 0,
857
999
  type: resolveInputType(field),
858
1000
  multiline: field.input_kind === "textarea" || field.type.toLowerCase().includes("text"),
859
1001
  minRows: field.input_kind === "textarea" || field.type.toLowerCase().includes("text") ? 3 : void 0,
@@ -910,25 +1052,28 @@ function renderChoiceEditor({
910
1052
  listbox: { sx: { maxHeight: 240 } }
911
1053
  },
912
1054
  renderInput: (params) => (() => {
913
- var _a2;
914
- const { InputProps, inputProps, ...textFieldParams } = params;
1055
+ var _a2, _b, _c;
1056
+ const { slotProps, ...textFieldParams } = params;
915
1057
  return /* @__PURE__ */ jsx3(
916
1058
  TextField,
917
1059
  {
918
1060
  ...textFieldParams,
919
1061
  label: field.label,
920
- placeholder: searchPlaceholder,
921
- helperText: (_a2 = field.help_text) != null ? _a2 : void 0,
1062
+ required: field.required,
1063
+ sx: buildRequiredLabelSx(),
1064
+ placeholder: (_a2 = field.placeholder) != null ? _a2 : searchPlaceholder,
1065
+ helperText: (_b = field.help_text) != null ? _b : void 0,
922
1066
  slotProps: {
1067
+ inputLabel: slotProps.inputLabel,
923
1068
  input: {
924
- ...InputProps,
1069
+ ...slotProps.input,
925
1070
  endAdornment: /* @__PURE__ */ jsxs(Fragment, { children: [
926
1071
  isLoadingChoices ? /* @__PURE__ */ jsx3(CircularProgress, { color: "inherit", size: 16 }) : null,
927
- InputProps.endAdornment
1072
+ (_c = slotProps.input) == null ? void 0 : _c.endAdornment
928
1073
  ] })
929
1074
  },
930
1075
  htmlInput: {
931
- ...inputProps,
1076
+ ...slotProps.htmlInput,
932
1077
  autoComplete: "new-password",
933
1078
  name: `admin-choice-${field.name}`
934
1079
  }
@@ -968,25 +1113,28 @@ function renderChoiceEditor({
968
1113
  listbox: { sx: { maxHeight: 240 } }
969
1114
  },
970
1115
  renderInput: (params) => (() => {
971
- var _a2;
972
- const { InputProps, inputProps, ...textFieldParams } = params;
1116
+ var _a2, _b, _c;
1117
+ const { slotProps, ...textFieldParams } = params;
973
1118
  return /* @__PURE__ */ jsx3(
974
1119
  TextField,
975
1120
  {
976
1121
  ...textFieldParams,
977
1122
  label: field.label,
978
- placeholder: searchPlaceholder,
979
- helperText: (_a2 = field.help_text) != null ? _a2 : void 0,
1123
+ required: field.required,
1124
+ sx: buildRequiredLabelSx(),
1125
+ placeholder: (_a2 = field.placeholder) != null ? _a2 : searchPlaceholder,
1126
+ helperText: (_b = field.help_text) != null ? _b : void 0,
980
1127
  slotProps: {
1128
+ inputLabel: slotProps.inputLabel,
981
1129
  input: {
982
- ...InputProps,
1130
+ ...slotProps.input,
983
1131
  endAdornment: /* @__PURE__ */ jsxs(Fragment, { children: [
984
1132
  isLoadingChoices ? /* @__PURE__ */ jsx3(CircularProgress, { color: "inherit", size: 16 }) : null,
985
- InputProps.endAdornment
1133
+ (_c = slotProps.input) == null ? void 0 : _c.endAdornment
986
1134
  ] })
987
1135
  },
988
1136
  htmlInput: {
989
- ...inputProps,
1137
+ ...slotProps.htmlInput,
990
1138
  autoComplete: "new-password",
991
1139
  name: `admin-choice-${field.name}`
992
1140
  }
@@ -997,6 +1145,90 @@ function renderChoiceEditor({
997
1145
  }
998
1146
  );
999
1147
  }
1148
+ function renderStaticChoiceEditor({
1149
+ field,
1150
+ value,
1151
+ onChange,
1152
+ readOnly
1153
+ }) {
1154
+ var _a, _b, _c, _d;
1155
+ const options = (_a = field.options) != null ? _a : [];
1156
+ const optionValueMap = new Map(options.map((option) => [String(option.value), option.value]));
1157
+ const canClear = !field.required;
1158
+ if (field.input_kind === "select-multiple") {
1159
+ const selectedValues = Array.isArray(value) ? value.map((item) => String(item)) : [];
1160
+ return /* @__PURE__ */ jsx3(
1161
+ TextField,
1162
+ {
1163
+ select: true,
1164
+ label: field.label,
1165
+ value: selectedValues,
1166
+ onChange: (event) => {
1167
+ const rawValues = event.target.value;
1168
+ const nextValues = Array.isArray(rawValues) ? rawValues : [rawValues];
1169
+ onChange(nextValues.map((item) => {
1170
+ var _a2;
1171
+ return (_a2 = optionValueMap.get(String(item))) != null ? _a2 : item;
1172
+ }));
1173
+ },
1174
+ size: "small",
1175
+ fullWidth: true,
1176
+ disabled: readOnly,
1177
+ required: field.required,
1178
+ sx: buildRequiredLabelSx(),
1179
+ helperText: (_b = field.help_text) != null ? _b : void 0,
1180
+ slotProps: {
1181
+ htmlInput: buildHtmlInputProps(field),
1182
+ select: {
1183
+ multiple: true,
1184
+ displayEmpty: true,
1185
+ renderValue: (selected) => {
1186
+ var _a2;
1187
+ const selectedItems = Array.isArray(selected) ? selected : [selected];
1188
+ if (selectedItems.length === 0) {
1189
+ return (_a2 = field.placeholder) != null ? _a2 : "";
1190
+ }
1191
+ return selectedItems.map((item) => {
1192
+ var _a3, _b2;
1193
+ return (_b2 = (_a3 = options.find((option) => String(option.value) === String(item))) == null ? void 0 : _a3.label) != null ? _b2 : String(item);
1194
+ }).join(", ");
1195
+ }
1196
+ }
1197
+ },
1198
+ children: options.map((option) => /* @__PURE__ */ jsx3(MenuItem, { value: String(option.value), children: option.label }, String(option.value)))
1199
+ }
1200
+ );
1201
+ }
1202
+ return /* @__PURE__ */ jsxs(
1203
+ TextField,
1204
+ {
1205
+ select: true,
1206
+ label: field.label,
1207
+ value: value === null || value === void 0 ? "" : String(value),
1208
+ onChange: (event) => {
1209
+ var _a2;
1210
+ const nextValue = event.target.value;
1211
+ onChange(nextValue === "" ? null : (_a2 = optionValueMap.get(String(nextValue))) != null ? _a2 : nextValue);
1212
+ },
1213
+ size: "small",
1214
+ fullWidth: true,
1215
+ disabled: readOnly,
1216
+ required: field.required,
1217
+ sx: buildRequiredLabelSx(),
1218
+ helperText: (_c = field.help_text) != null ? _c : void 0,
1219
+ slotProps: {
1220
+ htmlInput: buildHtmlInputProps(field),
1221
+ select: {
1222
+ displayEmpty: canClear || Boolean(field.placeholder)
1223
+ }
1224
+ },
1225
+ children: [
1226
+ canClear || field.placeholder ? /* @__PURE__ */ jsx3(MenuItem, { value: "", children: (_d = field.placeholder) != null ? _d : "" }) : null,
1227
+ options.map((option) => /* @__PURE__ */ jsx3(MenuItem, { value: String(option.value), children: option.label }, String(option.value)))
1228
+ ]
1229
+ }
1230
+ );
1231
+ }
1000
1232
  function normalizeSelectedIds(value, isMultiple) {
1001
1233
  if (isMultiple) {
1002
1234
  if (!Array.isArray(value)) {
@@ -1016,6 +1248,20 @@ function mergeChoices(current, next) {
1016
1248
  }
1017
1249
  return [...choiceMap.values()];
1018
1250
  }
1251
+ function hasStaticOptions(field) {
1252
+ var _a, _b;
1253
+ return ((_b = (_a = field.options) == null ? void 0 : _a.length) != null ? _b : 0) > 0 || field.input_kind === "select" || field.input_kind === "select-multiple";
1254
+ }
1255
+ function buildRequiredLabelSx() {
1256
+ return {
1257
+ "& .MuiFormLabel-asterisk": {
1258
+ color: "error.main"
1259
+ },
1260
+ "& .MuiFormControlLabel-asterisk": {
1261
+ color: "error.main"
1262
+ }
1263
+ };
1264
+ }
1019
1265
  function resolveInputType(field) {
1020
1266
  if (field.input_kind === "password") {
1021
1267
  return "password";
@@ -1058,8 +1304,8 @@ function stringifyJsonValue(value) {
1058
1304
 
1059
1305
  // src/components/layout/AdminMessageContext.tsx
1060
1306
  import { createContext as createContext3, useCallback as useCallback2, useContext as useContext3, useEffect as useEffect3, useMemo as useMemo4, useRef as useRef3, useState as useState3 } from "react";
1061
- import CheckCircleOutlineIcon from "@mui/icons-material/CheckCircleOutline";
1062
- import ErrorOutlineIcon from "@mui/icons-material/ErrorOutline";
1307
+ import CheckCircleOutlinedIcon from "@mui/icons-material/CheckCircleOutlined";
1308
+ import ErrorOutlinedIcon from "@mui/icons-material/ErrorOutlined";
1063
1309
  import InfoOutlinedIcon from "@mui/icons-material/InfoOutlined";
1064
1310
  import { Box, Paper, Portal, Stack, Typography } from "@mui/material";
1065
1311
  import { alpha, useTheme } from "@mui/material/styles";
@@ -1199,7 +1445,7 @@ function AdminMessageBubble({
1199
1445
  }
1200
1446
  }
1201
1447
  },
1202
- children: /* @__PURE__ */ jsxs2(Stack, { direction: "row", spacing: 1.125, alignItems: "center", children: [
1448
+ children: /* @__PURE__ */ jsxs2(Stack, { direction: "row", spacing: 1.125, sx: { alignItems: "center" }, children: [
1203
1449
  /* @__PURE__ */ jsx4(
1204
1450
  Box,
1205
1451
  {
@@ -1241,7 +1487,7 @@ function AdminMessageBubble({
1241
1487
  function getBubbleAppearance(theme, kind) {
1242
1488
  if (kind === "success") {
1243
1489
  return {
1244
- icon: CheckCircleOutlineIcon,
1490
+ icon: CheckCircleOutlinedIcon,
1245
1491
  backgroundColor: alpha(theme.palette.success.main, 0.6),
1246
1492
  iconColor: theme.palette.common.white,
1247
1493
  iconBackgroundColor: alpha(theme.palette.common.white, 0.14),
@@ -1250,7 +1496,7 @@ function getBubbleAppearance(theme, kind) {
1250
1496
  }
1251
1497
  if (kind === "error") {
1252
1498
  return {
1253
- icon: ErrorOutlineIcon,
1499
+ icon: ErrorOutlinedIcon,
1254
1500
  backgroundColor: alpha(theme.palette.error.main, 0.6),
1255
1501
  iconColor: theme.palette.common.white,
1256
1502
  iconBackgroundColor: alpha(theme.palette.common.white, 0.14),
@@ -1285,19 +1531,57 @@ function FormDialog({
1285
1531
  const [values, setValues] = useState4({});
1286
1532
  const [error, setError] = useState4(null);
1287
1533
  const [isSaving, setIsSaving] = useState4(false);
1288
- const editableFieldNames = useMemo5(
1289
- () => mode === "create" ? meta.create_fields : meta.update_fields,
1290
- [meta.create_fields, meta.update_fields, mode]
1291
- );
1292
1534
  const editableFields = useMemo5(
1293
- () => meta.fields.filter((field) => editableFieldNames.includes(field.name)),
1294
- [editableFieldNames, meta.fields]
1535
+ () => {
1536
+ if (mode === "create" && meta.create_form && meta.create_form.length > 0) {
1537
+ return meta.create_form;
1538
+ }
1539
+ const editableFieldNames = mode === "create" ? meta.create_fields : meta.update_fields;
1540
+ return meta.fields.filter((field) => editableFieldNames.includes(field.name));
1541
+ },
1542
+ [meta.create_fields, meta.create_form, meta.fields, meta.update_fields, mode]
1295
1543
  );
1544
+ const [openPickerFieldName, setOpenPickerFieldName] = useState4(null);
1545
+ const pendingPickerFrameRef = useRef4(null);
1296
1546
  useEffect4(() => {
1297
- setValues(initialValues != null ? initialValues : {});
1547
+ setValues(buildAdminFormInitialValues(editableFields, initialValues));
1298
1548
  setError(null);
1299
1549
  setIsSaving(false);
1300
- }, [initialValues, open]);
1550
+ setOpenPickerFieldName(null);
1551
+ }, [editableFields, initialValues, open]);
1552
+ useEffect4(() => {
1553
+ return () => {
1554
+ if (pendingPickerFrameRef.current !== null) {
1555
+ window.cancelAnimationFrame(pendingPickerFrameRef.current);
1556
+ pendingPickerFrameRef.current = null;
1557
+ }
1558
+ };
1559
+ }, []);
1560
+ const requestPickerOpen = (fieldName) => {
1561
+ if (openPickerFieldName === fieldName) {
1562
+ return;
1563
+ }
1564
+ if (pendingPickerFrameRef.current !== null) {
1565
+ window.cancelAnimationFrame(pendingPickerFrameRef.current);
1566
+ pendingPickerFrameRef.current = null;
1567
+ }
1568
+ if (openPickerFieldName !== null) {
1569
+ setOpenPickerFieldName(null);
1570
+ pendingPickerFrameRef.current = window.requestAnimationFrame(() => {
1571
+ setOpenPickerFieldName(fieldName);
1572
+ pendingPickerFrameRef.current = null;
1573
+ });
1574
+ return;
1575
+ }
1576
+ setOpenPickerFieldName(fieldName);
1577
+ };
1578
+ const requestPickerClose = (fieldName) => {
1579
+ if (pendingPickerFrameRef.current !== null && openPickerFieldName === fieldName) {
1580
+ window.cancelAnimationFrame(pendingPickerFrameRef.current);
1581
+ pendingPickerFrameRef.current = null;
1582
+ }
1583
+ setOpenPickerFieldName((current) => current === fieldName ? null : current);
1584
+ };
1301
1585
  const handleSave = async () => {
1302
1586
  if (isSaving) {
1303
1587
  return;
@@ -1346,22 +1630,34 @@ function FormDialog({
1346
1630
  },
1347
1631
  children: [
1348
1632
  /* @__PURE__ */ jsx5(DialogTitle, { children: title }),
1349
- /* @__PURE__ */ jsx5(DialogContent, { children: /* @__PURE__ */ jsx5(LocalizationProvider, { dateAdapter: AdapterDayjs, adapterLocale: meta.locale, children: /* @__PURE__ */ jsxs3(Box2, { sx: { display: "grid", gap: 2, pt: 1 }, children: [
1350
- error ? /* @__PURE__ */ jsx5(Alert, { severity: "error", children: error }) : null,
1351
- editableFields.map((field) => /* @__PURE__ */ jsx5(
1352
- FieldEditor,
1353
- {
1354
- field,
1355
- value: values[field.name],
1356
- slug,
1357
- client,
1358
- onChange: (nextValue) => {
1359
- setValues((current) => ({ ...current, [field.name]: nextValue }));
1360
- }
1361
- },
1362
- field.name
1363
- ))
1364
- ] }) }) }),
1633
+ /* @__PURE__ */ jsx5(DialogContent, { children: /* @__PURE__ */ jsx5(
1634
+ LocalizationProvider,
1635
+ {
1636
+ dateAdapter: AdapterDayjs,
1637
+ adapterLocale: meta.locale,
1638
+ localeText: getMuiPickersLocaleText(meta.locale),
1639
+ children: /* @__PURE__ */ jsxs3(Box2, { sx: { display: "grid", gap: 2, pt: 1 }, children: [
1640
+ error ? /* @__PURE__ */ jsx5(Alert, { severity: "error", children: error }) : null,
1641
+ editableFields.map((field) => /* @__PURE__ */ jsx5(
1642
+ FieldEditor,
1643
+ {
1644
+ field,
1645
+ value: values[field.name],
1646
+ slug,
1647
+ client,
1648
+ isPickerOpen: openPickerFieldName === field.name,
1649
+ hasAnotherPickerOpen: openPickerFieldName !== null && openPickerFieldName !== field.name,
1650
+ onChange: (nextValue) => {
1651
+ setValues((current) => ({ ...current, [field.name]: nextValue }));
1652
+ },
1653
+ onRequestPickerOpen: () => requestPickerOpen(field.name),
1654
+ onRequestPickerClose: () => requestPickerClose(field.name)
1655
+ },
1656
+ field.name
1657
+ ))
1658
+ ] })
1659
+ }
1660
+ ) }),
1365
1661
  /* @__PURE__ */ jsxs3(DialogActions, { children: [
1366
1662
  /* @__PURE__ */ jsx5(Button, { onClick: onClose, disabled: isSaving, children: t("cancel") }),
1367
1663
  /* @__PURE__ */ jsx5(Button, { variant: "contained", onClick: () => void handleSave(), disabled: isSaving, children: isSaving ? t("saving") : t("save") })
@@ -1372,7 +1668,7 @@ function FormDialog({
1372
1668
  }
1373
1669
 
1374
1670
  // src/components/OverviewPage.tsx
1375
- import { useEffect as useEffect7, useLayoutEffect, useMemo as useMemo7, useState as useState7 } from "react";
1671
+ import { useEffect as useEffect8, useLayoutEffect, useMemo as useMemo7, useState as useState7 } from "react";
1376
1672
  import { Alert as Alert3, Box as Box6, Grid, Paper as Paper4, Skeleton as Skeleton2, Stack as Stack6 } from "@mui/material";
1377
1673
 
1378
1674
  // src/hooks/useAdminDocumentTitle.ts
@@ -1624,6 +1920,7 @@ function DashboardModelsBlock({ block, basePath }) {
1624
1920
  }
1625
1921
 
1626
1922
  // src/components/models-blocks/SidebarModelsBlock.tsx
1923
+ import { useEffect as useEffect7 } from "react";
1627
1924
  import ExpandMoreIcon2 from "@mui/icons-material/ExpandMore";
1628
1925
  import {
1629
1926
  Accordion as Accordion2,
@@ -1638,6 +1935,12 @@ import {
1638
1935
  import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
1639
1936
  function SidebarModelsBlock({ block, basePath, activeModelSlug, onModelNavigate }) {
1640
1937
  const [isExpanded, setIsExpanded] = useBlockExpandedState(block.slug, block.default_expanded);
1938
+ const hasActiveModel = block.models.some((model) => model.slug === activeModelSlug);
1939
+ useEffect7(() => {
1940
+ if (hasActiveModel && !isExpanded) {
1941
+ setIsExpanded(true);
1942
+ }
1943
+ }, [hasActiveModel, isExpanded, setIsExpanded]);
1641
1944
  if (block.collapsible) {
1642
1945
  return /* @__PURE__ */ jsxs6(
1643
1946
  Accordion2,
@@ -1646,6 +1949,8 @@ function SidebarModelsBlock({ block, basePath, activeModelSlug, onModelNavigate
1646
1949
  onChange: (_, expanded) => setIsExpanded(expanded),
1647
1950
  disableGutters: true,
1648
1951
  elevation: 0,
1952
+ "data-xladmin-active-block": hasActiveModel ? "true" : void 0,
1953
+ "data-xladmin-block-origin": block.isAllModels ? "all-models" : "block",
1649
1954
  sx: {
1650
1955
  ...getBlockSurfaceSx(block, "sidebar"),
1651
1956
  borderRadius: "8px",
@@ -1683,6 +1988,7 @@ function SidebarModelsBlock({ block, basePath, activeModelSlug, onModelNavigate
1683
1988
  models: block.models,
1684
1989
  basePath,
1685
1990
  activeModelSlug,
1991
+ modelOrigin: block.isAllModels ? "all-models" : "block",
1686
1992
  onModelNavigate
1687
1993
  }
1688
1994
  ) })
@@ -1693,6 +1999,8 @@ function SidebarModelsBlock({ block, basePath, activeModelSlug, onModelNavigate
1693
1999
  return /* @__PURE__ */ jsxs6(
1694
2000
  Paper2,
1695
2001
  {
2002
+ "data-xladmin-active-block": hasActiveModel ? "true" : void 0,
2003
+ "data-xladmin-block-origin": block.isAllModels ? "all-models" : "block",
1696
2004
  sx: {
1697
2005
  ...getBlockSurfaceSx(block, "sidebar"),
1698
2006
  borderRadius: "8px",
@@ -1706,6 +2014,7 @@ function SidebarModelsBlock({ block, basePath, activeModelSlug, onModelNavigate
1706
2014
  models: block.models,
1707
2015
  basePath,
1708
2016
  activeModelSlug,
2017
+ modelOrigin: block.isAllModels ? "all-models" : "block",
1709
2018
  onModelNavigate
1710
2019
  }
1711
2020
  )
@@ -1713,7 +2022,7 @@ function SidebarModelsBlock({ block, basePath, activeModelSlug, onModelNavigate
1713
2022
  }
1714
2023
  );
1715
2024
  }
1716
- function SidebarModelsList({ models, basePath, activeModelSlug, onModelNavigate }) {
2025
+ function SidebarModelsList({ models, basePath, activeModelSlug, modelOrigin, onModelNavigate }) {
1717
2026
  return /* @__PURE__ */ jsx11(List, { dense: true, disablePadding: true, sx: { display: "flex", flexDirection: "column", gap: 0.5, p: 1.35 }, children: models.map((model) => {
1718
2027
  const href = `${basePath}/${model.slug}`;
1719
2028
  const isActive = activeModelSlug === model.slug;
@@ -1723,33 +2032,38 @@ function SidebarModelsList({ models, basePath, activeModelSlug, onModelNavigate
1723
2032
  href,
1724
2033
  style: { textDecoration: "none", display: "block" },
1725
2034
  onClick: () => onModelNavigate == null ? void 0 : onModelNavigate(href),
1726
- children: /* @__PURE__ */ jsx11(
1727
- ListItemButton2,
1728
- {
1729
- selected: isActive,
1730
- sx: {
1731
- borderRadius: "8px",
1732
- px: 1.4,
1733
- backgroundColor: isActive ? "rgba(255, 255, 255, 0.18)" : "rgba(255, 255, 255, 0.04)",
1734
- boxShadow: isActive ? "inset 0 0 0 1px rgba(255, 255, 255, 0.08)" : "none",
1735
- "&:hover": {
1736
- backgroundColor: isActive ? "rgba(255, 255, 255, 0.2)" : "rgba(255, 255, 255, 0.06)"
1737
- },
1738
- "&.Mui-selected": {
1739
- backgroundColor: "rgba(255, 255, 255, 0.18)"
1740
- },
1741
- "&.Mui-selected:hover": {
1742
- backgroundColor: "rgba(255, 255, 255, 0.2)"
1743
- }
1744
- },
1745
- children: /* @__PURE__ */ jsx11(ListItemText2, { primary: model.title })
1746
- }
1747
- )
2035
+ children: /* @__PURE__ */ jsx11(SidebarModelListItem, { title: model.title, isActive, modelOrigin })
1748
2036
  },
1749
2037
  model.slug
1750
2038
  );
1751
2039
  }) });
1752
2040
  }
2041
+ function SidebarModelListItem({ title, isActive, modelOrigin }) {
2042
+ return /* @__PURE__ */ jsx11(
2043
+ ListItemButton2,
2044
+ {
2045
+ selected: isActive,
2046
+ "data-xladmin-active-model": isActive ? "true" : void 0,
2047
+ "data-xladmin-model-origin": isActive ? modelOrigin : void 0,
2048
+ sx: {
2049
+ borderRadius: "8px",
2050
+ px: 1.4,
2051
+ backgroundColor: isActive ? "rgba(255, 255, 255, 0.18)" : "rgba(255, 255, 255, 0.04)",
2052
+ boxShadow: isActive ? "inset 0 0 0 1px rgba(255, 255, 255, 0.08)" : "none",
2053
+ "&:hover": {
2054
+ backgroundColor: isActive ? "rgba(255, 255, 255, 0.2)" : "rgba(255, 255, 255, 0.06)"
2055
+ },
2056
+ "&.Mui-selected": {
2057
+ backgroundColor: "rgba(255, 255, 255, 0.18)"
2058
+ },
2059
+ "&.Mui-selected:hover": {
2060
+ backgroundColor: "rgba(255, 255, 255, 0.2)"
2061
+ }
2062
+ },
2063
+ children: /* @__PURE__ */ jsx11(ListItemText2, { primary: title })
2064
+ }
2065
+ );
2066
+ }
1753
2067
 
1754
2068
  // src/components/ModelsBlocks.tsx
1755
2069
  import { jsx as jsx12 } from "react/jsx-runtime";
@@ -1846,84 +2160,64 @@ function MainHeader({ title, subtitle, details, error, beforeTitle, beforeSubtit
1846
2160
  },
1847
2161
  children: [
1848
2162
  /* @__PURE__ */ jsxs7(Stack5, { spacing: 0.5, children: [
1849
- /* @__PURE__ */ jsxs7(
1850
- Stack5,
1851
- {
1852
- direction: "row",
1853
- spacing: 1.5,
1854
- alignItems: "center",
1855
- justifyContent: "space-between",
1856
- sx: { minWidth: 0 },
1857
- children: [
1858
- /* @__PURE__ */ jsxs7(Stack5, { direction: "row", spacing: 1, alignItems: "center", sx: { minWidth: 0, flex: 1 }, children: [
1859
- isMobile ? /* @__PURE__ */ jsx13(Box5, { sx: { display: "flex", alignItems: "center", flexShrink: 0 }, children: /* @__PURE__ */ jsx13(
1860
- IconButton,
1861
- {
1862
- "aria-label": t("menu"),
1863
- onClick: openMobileSidebar,
1864
- size: "small",
1865
- sx: { ml: -0.5 },
1866
- children: /* @__PURE__ */ jsx13(MenuIcon, { fontSize: "small" })
1867
- }
1868
- ) }) : null,
1869
- beforeTitle ? /* @__PURE__ */ jsx13(Box5, { sx: { display: "flex", alignItems: "center", flexShrink: 0 }, children: beforeTitle }) : null,
1870
- /* @__PURE__ */ jsx13(
1871
- Typography3,
1872
- {
1873
- variant: "h5",
1874
- sx: {
1875
- fontWeight: 600,
1876
- lineHeight: "2.125rem",
1877
- minWidth: 0
1878
- },
1879
- children: title
1880
- }
1881
- )
1882
- ] }),
1883
- actions ? /* @__PURE__ */ jsx13(Box5, { sx: { display: "flex", alignItems: "center", flexShrink: 0 }, children: actions }) : null
1884
- ]
1885
- }
1886
- ),
1887
- subtitle && !details ? /* @__PURE__ */ jsxs7(Stack5, { direction: "row", spacing: 0.5, alignItems: "center", sx: { minWidth: 0 }, children: [
2163
+ /* @__PURE__ */ jsxs7(Stack5, { direction: "row", spacing: 1.5, sx: { minWidth: 0, alignItems: "center", justifyContent: "space-between" }, children: [
2164
+ /* @__PURE__ */ jsxs7(Stack5, { direction: "row", spacing: 1, sx: { minWidth: 0, flex: 1, alignItems: "center" }, children: [
2165
+ isMobile ? /* @__PURE__ */ jsx13(Box5, { sx: { display: "flex", alignItems: "center", flexShrink: 0 }, children: /* @__PURE__ */ jsx13(
2166
+ IconButton,
2167
+ {
2168
+ "aria-label": t("menu"),
2169
+ onClick: openMobileSidebar,
2170
+ size: "small",
2171
+ sx: { ml: -0.5 },
2172
+ children: /* @__PURE__ */ jsx13(MenuIcon, { fontSize: "small" })
2173
+ }
2174
+ ) }) : null,
2175
+ beforeTitle ? /* @__PURE__ */ jsx13(Box5, { sx: { display: "flex", alignItems: "center", flexShrink: 0 }, children: beforeTitle }) : null,
2176
+ /* @__PURE__ */ jsx13(
2177
+ Typography3,
2178
+ {
2179
+ variant: "h5",
2180
+ sx: {
2181
+ fontWeight: 600,
2182
+ lineHeight: "2.125rem",
2183
+ minWidth: 0
2184
+ },
2185
+ children: title
2186
+ }
2187
+ )
2188
+ ] }),
2189
+ actions ? /* @__PURE__ */ jsx13(Box5, { sx: { display: "flex", alignItems: "center", flexShrink: 0 }, children: actions }) : null
2190
+ ] }),
2191
+ subtitle && !details ? /* @__PURE__ */ jsxs7(Stack5, { direction: "row", spacing: 0.5, sx: { minWidth: 0, alignItems: "center" }, children: [
1888
2192
  beforeSubtitle ? /* @__PURE__ */ jsx13(Box5, { sx: { display: "flex", alignItems: "center", flexShrink: 0 }, children: beforeSubtitle }) : null,
1889
2193
  /* @__PURE__ */ jsx13(Typography3, { color: "text.secondary", sx: { lineHeight: "1rem", minWidth: 0 }, children: subtitle })
1890
2194
  ] }) : null,
1891
2195
  details ? /* @__PURE__ */ jsxs7(Stack5, { spacing: 0.5, children: [
1892
- /* @__PURE__ */ jsxs7(
1893
- Stack5,
1894
- {
1895
- direction: "row",
1896
- spacing: 0.5,
1897
- alignItems: "center",
1898
- justifyContent: "space-between",
1899
- sx: { minWidth: 0 },
1900
- children: [
1901
- /* @__PURE__ */ jsxs7(Stack5, { direction: "row", spacing: 0.5, alignItems: "center", sx: { minWidth: 0, flex: 1 }, children: [
1902
- beforeSubtitle ? /* @__PURE__ */ jsx13(Box5, { sx: { display: "flex", alignItems: "center", flexShrink: 0 }, children: beforeSubtitle }) : null,
1903
- /* @__PURE__ */ jsx13(Typography3, { color: "text.secondary", sx: { lineHeight: "1rem", minWidth: 0 }, children: subtitle })
1904
- ] }),
1905
- /* @__PURE__ */ jsx13(
1906
- IconButton,
2196
+ /* @__PURE__ */ jsxs7(Stack5, { direction: "row", spacing: 0.5, sx: { minWidth: 0, alignItems: "center", justifyContent: "space-between" }, children: [
2197
+ /* @__PURE__ */ jsxs7(Stack5, { direction: "row", spacing: 0.5, sx: { minWidth: 0, flex: 1, alignItems: "center" }, children: [
2198
+ beforeSubtitle ? /* @__PURE__ */ jsx13(Box5, { sx: { display: "flex", alignItems: "center", flexShrink: 0 }, children: beforeSubtitle }) : null,
2199
+ /* @__PURE__ */ jsx13(Typography3, { color: "text.secondary", sx: { lineHeight: "1rem", minWidth: 0 }, children: subtitle })
2200
+ ] }),
2201
+ /* @__PURE__ */ jsx13(
2202
+ IconButton,
2203
+ {
2204
+ "aria-label": isDetailsOpen ? t("hide_details") : t("show_details"),
2205
+ onClick: () => setIsDetailsOpen((current) => !current),
2206
+ size: "small",
2207
+ sx: { mr: -0.5 },
2208
+ children: /* @__PURE__ */ jsx13(
2209
+ ExpandMoreIcon3,
1907
2210
  {
1908
- "aria-label": isDetailsOpen ? t("hide_details") : t("show_details"),
1909
- onClick: () => setIsDetailsOpen((current) => !current),
1910
- size: "small",
1911
- sx: { mr: -0.5 },
1912
- children: /* @__PURE__ */ jsx13(
1913
- ExpandMoreIcon3,
1914
- {
1915
- fontSize: "small",
1916
- sx: {
1917
- transform: isDetailsOpen ? "rotate(180deg)" : "rotate(0deg)",
1918
- transition: "transform 0.2s ease"
1919
- }
1920
- }
1921
- )
2211
+ fontSize: "small",
2212
+ sx: {
2213
+ transform: isDetailsOpen ? "rotate(180deg)" : "rotate(0deg)",
2214
+ transition: "transform 0.2s ease"
2215
+ }
1922
2216
  }
1923
2217
  )
1924
- ]
1925
- }
1926
- ),
2218
+ }
2219
+ )
2220
+ ] }),
1927
2221
  /* @__PURE__ */ jsx13(Collapse, { in: isDetailsOpen, children: /* @__PURE__ */ jsx13(Box5, { sx: { pt: 0.5 }, children: details }) })
1928
2222
  ] }) : null
1929
2223
  ] }),
@@ -1995,7 +2289,7 @@ function OverviewPage({ client, basePath }) {
1995
2289
  const [data, setData] = useState7(shellModelsResponse != null ? shellModelsResponse : cachedModelsResponse);
1996
2290
  const [error, setError] = useState7(null);
1997
2291
  const [isLoading, setIsLoading] = useState7(shellModelsResponse === null && cachedModelsResponse === null);
1998
- useEffect7(() => {
2292
+ useEffect8(() => {
1999
2293
  let isMounted = true;
2000
2294
  if (shellModelsResponse !== null) {
2001
2295
  cachedModelsResponse = shellModelsResponse;
@@ -2115,17 +2409,17 @@ import ChevronRightIcon from "@mui/icons-material/ChevronRight";
2115
2409
  import ExpandMoreIcon4 from "@mui/icons-material/ExpandMore";
2116
2410
  import FilterListIcon from "@mui/icons-material/FilterList";
2117
2411
  import {
2118
- Alert as Alert5,
2119
- Box as Box10,
2120
- Button as Button4,
2412
+ Alert as Alert6,
2413
+ Box as Box11,
2414
+ Button as Button5,
2121
2415
  Checkbox as Checkbox2,
2122
- Dialog as Dialog3,
2123
- DialogContent as DialogContent3,
2124
- DialogTitle as DialogTitle3,
2416
+ Dialog as Dialog4,
2417
+ DialogContent as DialogContent4,
2418
+ DialogTitle as DialogTitle4,
2125
2419
  IconButton as IconButton3,
2126
2420
  InputBase,
2127
2421
  Menu,
2128
- MenuItem as MenuItem2,
2422
+ MenuItem as MenuItem3,
2129
2423
  Paper as Paper7,
2130
2424
  Stack as Stack10,
2131
2425
  Table,
@@ -2140,20 +2434,165 @@ import {
2140
2434
  } from "@mui/material";
2141
2435
  import { useTheme as useTheme3 } from "@mui/material/styles";
2142
2436
 
2437
+ // src/components/ActionFormDialog.tsx
2438
+ import { useEffect as useEffect9, useRef as useRef5, useState as useState8 } from "react";
2439
+ import { Alert as Alert4, Box as Box7, Button as Button2, Dialog as Dialog2, DialogActions as DialogActions2, DialogContent as DialogContent2, DialogTitle as DialogTitle2 } from "@mui/material";
2440
+ import { LocalizationProvider as LocalizationProvider2 } from "@mui/x-date-pickers";
2441
+ import { AdapterDayjs as AdapterDayjs2 } from "@mui/x-date-pickers/AdapterDayjs";
2442
+ import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
2443
+ function ActionFormDialog({
2444
+ open,
2445
+ onClose,
2446
+ onSuccess,
2447
+ title,
2448
+ submitLabel,
2449
+ slug,
2450
+ locale,
2451
+ fields,
2452
+ client,
2453
+ choiceScope,
2454
+ initialValues,
2455
+ onSubmit
2456
+ }) {
2457
+ const t = useAdminTranslation();
2458
+ const message = useAdminMessage();
2459
+ const [values, setValues] = useState8({});
2460
+ const [error, setError] = useState8(null);
2461
+ const [isSubmitting, setIsSubmitting] = useState8(false);
2462
+ const [openPickerFieldName, setOpenPickerFieldName] = useState8(null);
2463
+ const pendingPickerFrameRef = useRef5(null);
2464
+ useEffect9(() => {
2465
+ setValues(buildAdminFormInitialValues(fields, initialValues));
2466
+ setError(null);
2467
+ setIsSubmitting(false);
2468
+ setOpenPickerFieldName(null);
2469
+ }, [fields, initialValues, open]);
2470
+ useEffect9(() => {
2471
+ return () => {
2472
+ if (pendingPickerFrameRef.current !== null) {
2473
+ window.cancelAnimationFrame(pendingPickerFrameRef.current);
2474
+ pendingPickerFrameRef.current = null;
2475
+ }
2476
+ };
2477
+ }, []);
2478
+ const requestPickerOpen = (fieldName) => {
2479
+ if (openPickerFieldName === fieldName) {
2480
+ return;
2481
+ }
2482
+ if (pendingPickerFrameRef.current !== null) {
2483
+ window.cancelAnimationFrame(pendingPickerFrameRef.current);
2484
+ pendingPickerFrameRef.current = null;
2485
+ }
2486
+ if (openPickerFieldName !== null) {
2487
+ setOpenPickerFieldName(null);
2488
+ pendingPickerFrameRef.current = window.requestAnimationFrame(() => {
2489
+ setOpenPickerFieldName(fieldName);
2490
+ pendingPickerFrameRef.current = null;
2491
+ });
2492
+ return;
2493
+ }
2494
+ setOpenPickerFieldName(fieldName);
2495
+ };
2496
+ const requestPickerClose = (fieldName) => {
2497
+ if (pendingPickerFrameRef.current !== null && openPickerFieldName === fieldName) {
2498
+ window.cancelAnimationFrame(pendingPickerFrameRef.current);
2499
+ pendingPickerFrameRef.current = null;
2500
+ }
2501
+ setOpenPickerFieldName((current) => current === fieldName ? null : current);
2502
+ };
2503
+ const handleSubmit = async () => {
2504
+ if (isSubmitting) {
2505
+ return;
2506
+ }
2507
+ setIsSubmitting(true);
2508
+ setError(null);
2509
+ try {
2510
+ await onSubmit(buildAdminPayload(values, fields));
2511
+ onSuccess();
2512
+ onClose();
2513
+ } catch (reason) {
2514
+ const nextError = reason instanceof Error ? reason.message : t("object_action_error");
2515
+ setError(nextError);
2516
+ message.error(nextError);
2517
+ } finally {
2518
+ setIsSubmitting(false);
2519
+ }
2520
+ };
2521
+ return /* @__PURE__ */ jsxs9(
2522
+ Dialog2,
2523
+ {
2524
+ open,
2525
+ onClose,
2526
+ fullWidth: true,
2527
+ maxWidth: "md",
2528
+ slotProps: {
2529
+ paper: {
2530
+ sx: {
2531
+ m: { xs: 1, sm: 2, md: 3 },
2532
+ width: { xs: "calc(100% - 16px)", sm: void 0 },
2533
+ maxWidth: { xs: "calc(100% - 16px)", md: 900 },
2534
+ maxHeight: {
2535
+ xs: "calc(100% - 16px)",
2536
+ sm: "calc(100% - 32px)",
2537
+ md: "calc(100% - 48px)"
2538
+ }
2539
+ }
2540
+ }
2541
+ },
2542
+ children: [
2543
+ /* @__PURE__ */ jsx15(DialogTitle2, { children: title }),
2544
+ /* @__PURE__ */ jsx15(DialogContent2, { children: /* @__PURE__ */ jsx15(
2545
+ LocalizationProvider2,
2546
+ {
2547
+ dateAdapter: AdapterDayjs2,
2548
+ adapterLocale: locale,
2549
+ localeText: getMuiPickersLocaleText(locale),
2550
+ children: /* @__PURE__ */ jsxs9(Box7, { sx: { display: "grid", gap: 2, pt: 1 }, children: [
2551
+ error ? /* @__PURE__ */ jsx15(Alert4, { severity: "error", children: error }) : null,
2552
+ fields.map((field) => /* @__PURE__ */ jsx15(
2553
+ FieldEditor,
2554
+ {
2555
+ field,
2556
+ value: values[field.name],
2557
+ slug,
2558
+ client,
2559
+ choiceScope,
2560
+ isPickerOpen: openPickerFieldName === field.name,
2561
+ hasAnotherPickerOpen: openPickerFieldName !== null && openPickerFieldName !== field.name,
2562
+ onChange: (nextValue) => {
2563
+ setValues((current) => ({ ...current, [field.name]: nextValue }));
2564
+ },
2565
+ onRequestPickerOpen: () => requestPickerOpen(field.name),
2566
+ onRequestPickerClose: () => requestPickerClose(field.name)
2567
+ },
2568
+ field.name
2569
+ ))
2570
+ ] })
2571
+ }
2572
+ ) }),
2573
+ /* @__PURE__ */ jsxs9(DialogActions2, { children: [
2574
+ /* @__PURE__ */ jsx15(Button2, { onClick: onClose, disabled: isSubmitting, children: t("cancel") }),
2575
+ /* @__PURE__ */ jsx15(Button2, { variant: "contained", onClick: () => void handleSubmit(), disabled: isSubmitting, children: isSubmitting ? t("saving") : submitLabel != null ? submitLabel : t("save") })
2576
+ ] })
2577
+ ]
2578
+ }
2579
+ );
2580
+ }
2581
+
2143
2582
  // src/components/DeletePreviewDialog.tsx
2144
2583
  import {
2145
- Alert as Alert4,
2146
- Box as Box7,
2147
- Button as Button2,
2584
+ Alert as Alert5,
2585
+ Box as Box8,
2586
+ Button as Button3,
2148
2587
  CircularProgress as CircularProgress2,
2149
- Dialog as Dialog2,
2150
- DialogActions as DialogActions2,
2151
- DialogContent as DialogContent2,
2152
- DialogTitle as DialogTitle2,
2588
+ Dialog as Dialog3,
2589
+ DialogActions as DialogActions3,
2590
+ DialogContent as DialogContent3,
2591
+ DialogTitle as DialogTitle3,
2153
2592
  Stack as Stack7,
2154
2593
  Typography as Typography4
2155
2594
  } from "@mui/material";
2156
- import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
2595
+ import { jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
2157
2596
  function DeletePreviewDialog({
2158
2597
  open,
2159
2598
  title,
@@ -2165,8 +2604,8 @@ function DeletePreviewDialog({
2165
2604
  onConfirm
2166
2605
  }) {
2167
2606
  const t = useAdminTranslation();
2168
- return /* @__PURE__ */ jsxs9(
2169
- Dialog2,
2607
+ return /* @__PURE__ */ jsxs10(
2608
+ Dialog3,
2170
2609
  {
2171
2610
  open,
2172
2611
  onClose: isSubmitting ? void 0 : onClose,
@@ -2187,27 +2626,27 @@ function DeletePreviewDialog({
2187
2626
  }
2188
2627
  },
2189
2628
  children: [
2190
- /* @__PURE__ */ jsx15(DialogTitle2, { children: title }),
2191
- /* @__PURE__ */ jsxs9(DialogContent2, { dividers: true, children: [
2192
- isLoading ? /* @__PURE__ */ jsxs9(Stack7, { spacing: 1.5, alignItems: "center", justifyContent: "center", sx: { minHeight: 180 }, children: [
2193
- /* @__PURE__ */ jsx15(CircularProgress2, { size: 28, thickness: 4.2, color: "inherit" }),
2194
- /* @__PURE__ */ jsx15(Typography4, { color: "text.secondary", children: t("delete_preview_loading") })
2629
+ /* @__PURE__ */ jsx16(DialogTitle3, { children: title }),
2630
+ /* @__PURE__ */ jsxs10(DialogContent3, { dividers: true, children: [
2631
+ isLoading ? /* @__PURE__ */ jsxs10(Stack7, { spacing: 1.5, sx: { minHeight: 180, alignItems: "center", justifyContent: "center" }, children: [
2632
+ /* @__PURE__ */ jsx16(CircularProgress2, { size: 28, thickness: 4.2, color: "inherit" }),
2633
+ /* @__PURE__ */ jsx16(Typography4, { color: "text.secondary", children: t("delete_preview_loading") })
2195
2634
  ] }) : null,
2196
- !isLoading && error ? /* @__PURE__ */ jsx15(Alert4, { severity: "error", children: error }) : null,
2197
- !isLoading && !error && preview ? /* @__PURE__ */ jsxs9(Stack7, { spacing: 1.5, children: [
2198
- /* @__PURE__ */ jsx15(Typography4, { color: "text.secondary", children: preview.can_delete ? t("delete_preview_hint") : t("delete_preview_blocked_hint") }),
2199
- !preview.can_delete ? /* @__PURE__ */ jsx15(Alert4, { severity: "warning", children: t("delete_preview_blocked_hint") }) : null,
2200
- /* @__PURE__ */ jsxs9(Stack7, { spacing: 0.5, children: [
2201
- /* @__PURE__ */ jsx15(Typography4, { variant: "body2", color: "text.secondary", children: t("delete_preview_roots", { count: preview.summary.roots }) }),
2202
- /* @__PURE__ */ jsx15(Typography4, { variant: "body2", color: "text.secondary", children: t("delete_preview_delete", { count: preview.summary.delete }) }),
2203
- /* @__PURE__ */ jsx15(Typography4, { variant: "body2", color: "text.secondary", children: t("delete_preview_protect", { count: preview.summary.protect }) }),
2204
- /* @__PURE__ */ jsx15(Typography4, { variant: "body2", color: "text.secondary", children: t("delete_preview_set_null", { count: preview.summary.set_null }) }),
2205
- /* @__PURE__ */ jsx15(Typography4, { variant: "body2", color: "text.secondary", children: t("delete_preview_total", { count: preview.summary.total }) })
2635
+ !isLoading && error ? /* @__PURE__ */ jsx16(Alert5, { severity: "error", children: error }) : null,
2636
+ !isLoading && !error && preview ? /* @__PURE__ */ jsxs10(Stack7, { spacing: 1.5, children: [
2637
+ /* @__PURE__ */ jsx16(Typography4, { color: "text.secondary", children: preview.can_delete ? t("delete_preview_hint") : t("delete_preview_blocked_hint") }),
2638
+ !preview.can_delete ? /* @__PURE__ */ jsx16(Alert5, { severity: "warning", children: t("delete_preview_blocked_hint") }) : null,
2639
+ /* @__PURE__ */ jsxs10(Stack7, { spacing: 0.5, children: [
2640
+ /* @__PURE__ */ jsx16(Typography4, { variant: "body2", color: "text.secondary", children: t("delete_preview_roots", { count: preview.summary.roots }) }),
2641
+ /* @__PURE__ */ jsx16(Typography4, { variant: "body2", color: "text.secondary", children: t("delete_preview_delete", { count: preview.summary.delete }) }),
2642
+ /* @__PURE__ */ jsx16(Typography4, { variant: "body2", color: "text.secondary", children: t("delete_preview_protect", { count: preview.summary.protect }) }),
2643
+ /* @__PURE__ */ jsx16(Typography4, { variant: "body2", color: "text.secondary", children: t("delete_preview_set_null", { count: preview.summary.set_null }) }),
2644
+ /* @__PURE__ */ jsx16(Typography4, { variant: "body2", color: "text.secondary", children: t("delete_preview_total", { count: preview.summary.total }) })
2206
2645
  ] }),
2207
- preview.summary.delete === 0 && preview.summary.protect === 0 && preview.summary.set_null === 0 ? /* @__PURE__ */ jsx15(Typography4, { variant: "body2", color: "text.secondary", children: t("delete_preview_empty") }) : null,
2208
- preview.roots.length > 0 ? /* @__PURE__ */ jsx15(Stack7, { spacing: 1, children: preview.roots.map((rootNode, index) => {
2646
+ preview.summary.delete === 0 && preview.summary.protect === 0 && preview.summary.set_null === 0 ? /* @__PURE__ */ jsx16(Typography4, { variant: "body2", color: "text.secondary", children: t("delete_preview_empty") }) : null,
2647
+ preview.roots.length > 0 ? /* @__PURE__ */ jsx16(Stack7, { spacing: 1, children: preview.roots.map((rootNode, index) => {
2209
2648
  var _a;
2210
- return /* @__PURE__ */ jsx15(
2649
+ return /* @__PURE__ */ jsx16(
2211
2650
  DeletePreviewNode,
2212
2651
  {
2213
2652
  node: rootNode,
@@ -2215,7 +2654,7 @@ function DeletePreviewDialog({
2215
2654
  },
2216
2655
  `${(_a = rootNode.model_slug) != null ? _a : "model"}:${rootNode.id}:${index}`
2217
2656
  );
2218
- }) }) : /* @__PURE__ */ jsx15(
2657
+ }) }) : /* @__PURE__ */ jsx16(
2219
2658
  Typography4,
2220
2659
  {
2221
2660
  variant: "body2",
@@ -2225,10 +2664,10 @@ function DeletePreviewDialog({
2225
2664
  )
2226
2665
  ] }) : null
2227
2666
  ] }),
2228
- /* @__PURE__ */ jsxs9(DialogActions2, { children: [
2229
- /* @__PURE__ */ jsx15(Button2, { onClick: onClose, disabled: isSubmitting, children: t("cancel") }),
2230
- /* @__PURE__ */ jsx15(
2231
- Button2,
2667
+ /* @__PURE__ */ jsxs10(DialogActions3, { children: [
2668
+ /* @__PURE__ */ jsx16(Button3, { onClick: onClose, disabled: isSubmitting, children: t("cancel") }),
2669
+ /* @__PURE__ */ jsx16(
2670
+ Button3,
2232
2671
  {
2233
2672
  color: "error",
2234
2673
  variant: "contained",
@@ -2244,8 +2683,8 @@ function DeletePreviewDialog({
2244
2683
  }
2245
2684
  function DeletePreviewNode({ node, depth }) {
2246
2685
  const t = useAdminTranslation();
2247
- return /* @__PURE__ */ jsxs9(
2248
- Box7,
2686
+ return /* @__PURE__ */ jsxs10(
2687
+ Box8,
2249
2688
  {
2250
2689
  sx: {
2251
2690
  pl: depth === 0 ? 0 : 1.5,
@@ -2253,17 +2692,17 @@ function DeletePreviewNode({ node, depth }) {
2253
2692
  borderLeft: depth === 0 ? "none" : "1px solid rgba(255, 255, 255, 0.08)"
2254
2693
  },
2255
2694
  children: [
2256
- /* @__PURE__ */ jsxs9(Stack7, { spacing: 0.25, children: [
2257
- /* @__PURE__ */ jsx15(Typography4, { sx: { fontWeight: 600 }, children: node.label }),
2258
- /* @__PURE__ */ jsxs9(Typography4, { variant: "body2", color: "text.secondary", children: [
2695
+ /* @__PURE__ */ jsxs10(Stack7, { spacing: 0.25, children: [
2696
+ /* @__PURE__ */ jsx16(Typography4, { sx: { fontWeight: 600 }, children: node.label }),
2697
+ /* @__PURE__ */ jsxs10(Typography4, { variant: "body2", color: "text.secondary", children: [
2259
2698
  node.model_title,
2260
2699
  node.relation_name ? ` \u2022 ${node.relation_name}` : "",
2261
2700
  ` \u2022 ${getEffectLabel(node.effect, t)}`
2262
2701
  ] })
2263
2702
  ] }),
2264
- node.children.length > 0 ? /* @__PURE__ */ jsx15(Stack7, { spacing: 0.75, sx: { mt: 1 }, children: node.children.map((childNode, index) => {
2703
+ node.children.length > 0 ? /* @__PURE__ */ jsx16(Stack7, { spacing: 0.75, sx: { mt: 1 }, children: node.children.map((childNode, index) => {
2265
2704
  var _a;
2266
- return /* @__PURE__ */ jsx15(
2705
+ return /* @__PURE__ */ jsx16(
2267
2706
  DeletePreviewNode,
2268
2707
  {
2269
2708
  node: childNode,
@@ -2287,19 +2726,19 @@ function getEffectLabel(effect, t) {
2287
2726
  }
2288
2727
 
2289
2728
  // src/components/model-page/ListFiltersBar.tsx
2290
- import { memo as memo3, useCallback as useCallback4, useEffect as useEffect8, useMemo as useMemo8, useState as useState8 } from "react";
2729
+ import { memo as memo3, useCallback as useCallback4, useEffect as useEffect10, useMemo as useMemo8, useState as useState9 } from "react";
2291
2730
  import {
2292
2731
  Autocomplete as Autocomplete2,
2293
- Button as Button3,
2732
+ Button as Button4,
2294
2733
  CircularProgress as CircularProgress3,
2295
2734
  Divider,
2296
- MenuItem,
2735
+ MenuItem as MenuItem2,
2297
2736
  Paper as Paper5,
2298
2737
  Stack as Stack8,
2299
2738
  TextField as TextField2,
2300
2739
  Typography as Typography5
2301
2740
  } from "@mui/material";
2302
- import { Fragment as Fragment2, jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
2741
+ import { Fragment as Fragment2, jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
2303
2742
  var ListFiltersSidebar = memo3(function ListFiltersSidebar2({
2304
2743
  client,
2305
2744
  slug,
@@ -2334,7 +2773,7 @@ var ListFiltersSidebar = memo3(function ListFiltersSidebar2({
2334
2773
  [filters, values]
2335
2774
  );
2336
2775
  if (filters.length === 0) return null;
2337
- return /* @__PURE__ */ jsx16(
2776
+ return /* @__PURE__ */ jsx17(
2338
2777
  Paper5,
2339
2778
  {
2340
2779
  sx: {
@@ -2346,14 +2785,14 @@ var ListFiltersSidebar = memo3(function ListFiltersSidebar2({
2346
2785
  p: 1.5,
2347
2786
  overflow: "auto"
2348
2787
  },
2349
- children: /* @__PURE__ */ jsxs10(Stack8, { spacing: 1.5, children: [
2350
- /* @__PURE__ */ jsxs10(Stack8, { direction: "row", spacing: 1, alignItems: "center", justifyContent: "space-between", children: [
2351
- /* @__PURE__ */ jsxs10(Stack8, { spacing: 0.25, children: [
2352
- /* @__PURE__ */ jsx16(Typography5, { sx: { fontSize: 15, fontWeight: 700 }, children: t("filters") }),
2353
- activeFiltersCount > 0 ? /* @__PURE__ */ jsx16(Typography5, { color: "text.secondary", sx: { fontSize: 12 }, children: t("active_filters", { count: activeFiltersCount }) }) : null
2788
+ children: /* @__PURE__ */ jsxs11(Stack8, { spacing: 1.5, children: [
2789
+ /* @__PURE__ */ jsxs11(Stack8, { direction: "row", spacing: 1, sx: { alignItems: "center", justifyContent: "space-between" }, children: [
2790
+ /* @__PURE__ */ jsxs11(Stack8, { spacing: 0.25, children: [
2791
+ /* @__PURE__ */ jsx17(Typography5, { sx: { fontSize: 15, fontWeight: 700 }, children: t("filters") }),
2792
+ activeFiltersCount > 0 ? /* @__PURE__ */ jsx17(Typography5, { color: "text.secondary", sx: { fontSize: 12 }, children: t("active_filters", { count: activeFiltersCount }) }) : null
2354
2793
  ] }),
2355
- /* @__PURE__ */ jsx16(
2356
- Button3,
2794
+ /* @__PURE__ */ jsx17(
2795
+ Button4,
2357
2796
  {
2358
2797
  size: "small",
2359
2798
  onClick: onReset,
@@ -2363,8 +2802,8 @@ var ListFiltersSidebar = memo3(function ListFiltersSidebar2({
2363
2802
  }
2364
2803
  )
2365
2804
  ] }),
2366
- /* @__PURE__ */ jsx16(Divider, {}),
2367
- filterGroups.map((group) => /* @__PURE__ */ jsx16(
2805
+ /* @__PURE__ */ jsx17(Divider, {}),
2806
+ filterGroups.map((group) => /* @__PURE__ */ jsx17(
2368
2807
  FilterGroupSection,
2369
2808
  {
2370
2809
  client,
@@ -2381,11 +2820,11 @@ var ListFiltersSidebar = memo3(function ListFiltersSidebar2({
2381
2820
  );
2382
2821
  });
2383
2822
  function FilterGroupSection({ client, slug, group, values, onChange, debounceMs }) {
2384
- return /* @__PURE__ */ jsxs10(Stack8, { spacing: 1, children: [
2385
- /* @__PURE__ */ jsx16(Typography5, { sx: { fontSize: 13, fontWeight: 700, color: "text.secondary" }, children: group.title }),
2386
- /* @__PURE__ */ jsx16(Stack8, { spacing: 1, children: group.filters.map((filter) => {
2823
+ return /* @__PURE__ */ jsxs11(Stack8, { spacing: 1, children: [
2824
+ /* @__PURE__ */ jsx17(Typography5, { sx: { fontSize: 13, fontWeight: 700, color: "text.secondary" }, children: group.title }),
2825
+ /* @__PURE__ */ jsx17(Stack8, { spacing: 1, children: group.filters.map((filter) => {
2387
2826
  var _a;
2388
- return /* @__PURE__ */ jsx16(
2827
+ return /* @__PURE__ */ jsx17(
2389
2828
  ListFilterField,
2390
2829
  {
2391
2830
  client,
@@ -2403,8 +2842,8 @@ function FilterGroupSection({ client, slug, group, values, onChange, debounceMs
2403
2842
  function ListFilterField({ client, slug, filter, value, onChange, debounceMs }) {
2404
2843
  var _a, _b;
2405
2844
  const t = useAdminTranslation();
2406
- const [draftValue, setDraftValue] = useState8(value);
2407
- const [searchValue, setSearchValue] = useState8("");
2845
+ const [draftValue, setDraftValue] = useState9(value);
2846
+ const [searchValue, setSearchValue] = useState9("");
2408
2847
  const selectedValues = useMemo8(() => parseSelectedFilterValues(value, filter.multiple), [filter.multiple, value]);
2409
2848
  const isSelectFilter = filter.input_kind === "select" || filter.input_kind === "select-multiple";
2410
2849
  const loadChoices = useCallback4(
@@ -2431,13 +2870,13 @@ function ListFilterField({ client, slug, filter, value, onChange, debounceMs })
2431
2870
  queryKey: `${slug}:${filter.slug}:${searchValue}:${value}`,
2432
2871
  load: loadChoices
2433
2872
  });
2434
- useEffect8(() => {
2873
+ useEffect10(() => {
2435
2874
  setDraftValue(value);
2436
2875
  }, [value]);
2437
- useEffect8(() => {
2876
+ useEffect10(() => {
2438
2877
  setSearchValue("");
2439
2878
  }, [filter.slug]);
2440
- useEffect8(() => {
2879
+ useEffect10(() => {
2441
2880
  if (filter.input_kind !== "text") {
2442
2881
  return;
2443
2882
  }
@@ -2451,7 +2890,7 @@ function ListFilterField({ client, slug, filter, value, onChange, debounceMs })
2451
2890
  };
2452
2891
  }, [debounceMs, draftValue, filter.input_kind, filter.slug, onChange, value]);
2453
2892
  if (filter.input_kind === "boolean") {
2454
- return /* @__PURE__ */ jsxs10(
2893
+ return /* @__PURE__ */ jsxs11(
2455
2894
  TextField2,
2456
2895
  {
2457
2896
  select: true,
@@ -2461,8 +2900,8 @@ function ListFilterField({ client, slug, filter, value, onChange, debounceMs })
2461
2900
  value,
2462
2901
  onChange: (event) => onChange(filter.slug, event.target.value),
2463
2902
  children: [
2464
- /* @__PURE__ */ jsx16(MenuItem, { value: "", children: t("all") }),
2465
- filter.options.map((option) => /* @__PURE__ */ jsx16(MenuItem, { value: option.value, children: option.label }, `${filter.slug}-${option.value}`))
2903
+ /* @__PURE__ */ jsx17(MenuItem2, { value: "", children: t("all") }),
2904
+ filter.options.map((option) => /* @__PURE__ */ jsx17(MenuItem2, { value: option.value, children: option.label }, `${filter.slug}-${option.value}`))
2466
2905
  ]
2467
2906
  }
2468
2907
  );
@@ -2476,7 +2915,7 @@ function ListFilterField({ client, slug, filter, value, onChange, debounceMs })
2476
2915
  };
2477
2916
  });
2478
2917
  const selectedOption = filter.multiple ? selectedOptions : (_a = selectedOptions[0]) != null ? _a : null;
2479
- return /* @__PURE__ */ jsx16(
2918
+ return /* @__PURE__ */ jsx17(
2480
2919
  Autocomplete2,
2481
2920
  {
2482
2921
  options,
@@ -2500,23 +2939,24 @@ function ListFilterField({ client, slug, filter, value, onChange, debounceMs })
2500
2939
  },
2501
2940
  onInputChange: (_, nextInputValue) => setSearchValue(nextInputValue),
2502
2941
  renderInput: (params) => (() => {
2503
- var _a2;
2504
- const { InputProps, inputProps, ...textFieldParams } = params;
2505
- return /* @__PURE__ */ jsx16(
2942
+ var _a2, _b2;
2943
+ const { slotProps, ...textFieldParams } = params;
2944
+ return /* @__PURE__ */ jsx17(
2506
2945
  TextField2,
2507
2946
  {
2508
2947
  ...textFieldParams,
2509
2948
  label: filter.label,
2510
2949
  placeholder: (_a2 = filter.placeholder) != null ? _a2 : t("search"),
2511
2950
  slotProps: {
2951
+ inputLabel: slotProps.inputLabel,
2512
2952
  input: {
2513
- ...InputProps,
2514
- endAdornment: /* @__PURE__ */ jsxs10(Fragment2, { children: [
2515
- isLoadingChoices ? /* @__PURE__ */ jsx16(CircularProgress3, { color: "inherit", size: 16 }) : null,
2516
- InputProps.endAdornment
2953
+ ...slotProps.input,
2954
+ endAdornment: /* @__PURE__ */ jsxs11(Fragment2, { children: [
2955
+ isLoadingChoices ? /* @__PURE__ */ jsx17(CircularProgress3, { color: "inherit", size: 16 }) : null,
2956
+ (_b2 = slotProps.input) == null ? void 0 : _b2.endAdornment
2517
2957
  ] })
2518
2958
  },
2519
- htmlInput: inputProps
2959
+ htmlInput: slotProps.htmlInput
2520
2960
  }
2521
2961
  }
2522
2962
  );
@@ -2524,7 +2964,7 @@ function ListFilterField({ client, slug, filter, value, onChange, debounceMs })
2524
2964
  }
2525
2965
  );
2526
2966
  }
2527
- return /* @__PURE__ */ jsx16(
2967
+ return /* @__PURE__ */ jsx17(
2528
2968
  TextField2,
2529
2969
  {
2530
2970
  size: "small",
@@ -2549,8 +2989,8 @@ function parseSelectedFilterValues(value, multiple) {
2549
2989
  // src/components/model-page/ListRow.tsx
2550
2990
  import { memo as memo4 } from "react";
2551
2991
  import MoreVertIcon from "@mui/icons-material/MoreVert";
2552
- import { Box as Box8, Checkbox, IconButton as IconButton2, TableCell, TableRow } from "@mui/material";
2553
- import { jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
2992
+ import { Box as Box9, Checkbox, IconButton as IconButton2, TableCell, TableRow } from "@mui/material";
2993
+ import { jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime";
2554
2994
  var ListRow = memo4(function ListRow2({
2555
2995
  row,
2556
2996
  pkField,
@@ -2566,7 +3006,7 @@ var ListRow = memo4(function ListRow2({
2566
3006
  const checkboxColumnWidth = 56;
2567
3007
  const actionsColumnWidth = 56;
2568
3008
  const rowId = row[pkField];
2569
- return /* @__PURE__ */ jsxs11(
3009
+ return /* @__PURE__ */ jsxs12(
2570
3010
  TableRow,
2571
3011
  {
2572
3012
  hover: true,
@@ -2580,7 +3020,7 @@ var ListRow = memo4(function ListRow2({
2580
3020
  }
2581
3021
  },
2582
3022
  children: [
2583
- /* @__PURE__ */ jsx17(
3023
+ /* @__PURE__ */ jsx18(
2584
3024
  TableCell,
2585
3025
  {
2586
3026
  padding: "none",
@@ -2592,7 +3032,7 @@ var ListRow = memo4(function ListRow2({
2592
3032
  textAlign: "center",
2593
3033
  px: 1
2594
3034
  },
2595
- children: /* @__PURE__ */ jsx17(
3035
+ children: /* @__PURE__ */ jsx18(
2596
3036
  Checkbox,
2597
3037
  {
2598
3038
  checked: isSelected,
@@ -2617,8 +3057,8 @@ var ListRow = memo4(function ListRow2({
2617
3057
  textOverflow: "ellipsis"
2618
3058
  };
2619
3059
  if (imageUrl) {
2620
- return /* @__PURE__ */ jsx17(TableCell, { title: fullFieldValue, sx: { ...commonCellSx, py: 0.75 }, children: /* @__PURE__ */ jsx17(
2621
- Box8,
3060
+ return /* @__PURE__ */ jsx18(TableCell, { title: fullFieldValue, sx: { ...commonCellSx, py: 0.75 }, children: /* @__PURE__ */ jsx18(
3061
+ Box9,
2622
3062
  {
2623
3063
  component: "img",
2624
3064
  src: imageUrl,
@@ -2635,7 +3075,7 @@ var ListRow = memo4(function ListRow2({
2635
3075
  ) }, fieldName);
2636
3076
  }
2637
3077
  if (index === 0) {
2638
- return /* @__PURE__ */ jsx17(
3078
+ return /* @__PURE__ */ jsx18(
2639
3079
  TableCell,
2640
3080
  {
2641
3081
  title: fullFieldValue,
@@ -2653,7 +3093,7 @@ var ListRow = memo4(function ListRow2({
2653
3093
  color: "primary.main"
2654
3094
  }
2655
3095
  },
2656
- children: /* @__PURE__ */ jsx17(
3096
+ children: /* @__PURE__ */ jsx18(
2657
3097
  NavLink,
2658
3098
  {
2659
3099
  href: `${basePath}/${slug}/${rowId}`,
@@ -2666,9 +3106,9 @@ var ListRow = memo4(function ListRow2({
2666
3106
  fieldName
2667
3107
  );
2668
3108
  }
2669
- return /* @__PURE__ */ jsx17(TableCell, { title: fullFieldValue, sx: commonCellSx, children: fieldValue }, fieldName);
3109
+ return /* @__PURE__ */ jsx18(TableCell, { title: fullFieldValue, sx: commonCellSx, children: fieldValue }, fieldName);
2670
3110
  }),
2671
- /* @__PURE__ */ jsx17(
3111
+ /* @__PURE__ */ jsx18(
2672
3112
  TableCell,
2673
3113
  {
2674
3114
  align: "right",
@@ -2677,7 +3117,7 @@ var ListRow = memo4(function ListRow2({
2677
3117
  minWidth: actionsColumnWidth,
2678
3118
  maxWidth: actionsColumnWidth
2679
3119
  },
2680
- children: /* @__PURE__ */ jsx17(IconButton2, { size: "small", onClick: (event) => onOpenMenu(event, rowId), children: /* @__PURE__ */ jsx17(MoreVertIcon, { fontSize: "small" }) })
3120
+ children: /* @__PURE__ */ jsx18(IconButton2, { size: "small", onClick: (event) => onOpenMenu(event, rowId), children: /* @__PURE__ */ jsx18(MoreVertIcon, { fontSize: "small" }) })
2681
3121
  }
2682
3122
  )
2683
3123
  ]
@@ -2686,20 +3126,20 @@ var ListRow = memo4(function ListRow2({
2686
3126
  });
2687
3127
 
2688
3128
  // src/components/model-page/SearchField.tsx
2689
- import { memo as memo5, useEffect as useEffect9, useState as useState9 } from "react";
3129
+ import { memo as memo5, useEffect as useEffect11, useState as useState10 } from "react";
2690
3130
  import { TextField as TextField3 } from "@mui/material";
2691
- import { jsx as jsx18 } from "react/jsx-runtime";
3131
+ import { jsx as jsx19 } from "react/jsx-runtime";
2692
3132
  var SearchField = memo5(function SearchField2({
2693
3133
  value,
2694
3134
  onCommit,
2695
3135
  debounceMs,
2696
3136
  placeholder
2697
3137
  }) {
2698
- const [draftValue, setDraftValue] = useState9(value);
2699
- useEffect9(() => {
3138
+ const [draftValue, setDraftValue] = useState10(value);
3139
+ useEffect11(() => {
2700
3140
  setDraftValue(value);
2701
3141
  }, [value]);
2702
- useEffect9(() => {
3142
+ useEffect11(() => {
2703
3143
  const timerId = window.setTimeout(() => {
2704
3144
  if (draftValue !== value) {
2705
3145
  onCommit(draftValue);
@@ -2709,7 +3149,7 @@ var SearchField = memo5(function SearchField2({
2709
3149
  window.clearTimeout(timerId);
2710
3150
  };
2711
3151
  }, [debounceMs, draftValue, onCommit, value]);
2712
- return /* @__PURE__ */ jsx18(
3152
+ return /* @__PURE__ */ jsx19(
2713
3153
  TextField3,
2714
3154
  {
2715
3155
  size: "small",
@@ -2728,7 +3168,7 @@ var SearchField = memo5(function SearchField2({
2728
3168
  });
2729
3169
 
2730
3170
  // src/components/model-page/useModelPageController.ts
2731
- import { useCallback as useCallback5, useEffect as useEffect10, useLayoutEffect as useLayoutEffect2, useMemo as useMemo9, useRef as useRef4, useState as useState10 } from "react";
3171
+ import { useCallback as useCallback5, useEffect as useEffect12, useLayoutEffect as useLayoutEffect2, useMemo as useMemo9, useRef as useRef6, useState as useState11 } from "react";
2732
3172
 
2733
3173
  // src/cache.ts
2734
3174
  var MAX_CACHE_ENTRIES = 100;
@@ -2837,34 +3277,35 @@ function useModelPageController({
2837
3277
  ...initialFilters
2838
3278
  })
2839
3279
  )) != null ? _c : null;
2840
- const [selectedIds, setSelectedIds] = useState10([]);
2841
- const [isAllMatchingSelected, setIsAllMatchingSelected] = useState10(false);
2842
- const [createOpen, setCreateOpen] = useState10(false);
2843
- const [data, setData] = useState10(() => initialCachedResponse);
2844
- const [error, setError] = useState10(null);
2845
- const [isLoading, setIsLoading] = useState10(initialCachedResponse === null);
2846
- const [rowActionMenuAnchor, setRowActionMenuAnchor] = useState10(null);
2847
- const [rowActionMenuId, setRowActionMenuId] = useState10(null);
2848
- const [bulkActionMenuAnchor, setBulkActionMenuAnchor] = useState10(null);
2849
- const [appliedQuery, setAppliedQuery] = useState10(initialQuery);
2850
- const [sortValue, setSortValue] = useState10(initialSort);
2851
- const [currentPage, setCurrentPage] = useState10(initialPage);
2852
- const [pageInput, setPageInput] = useState10(String(initialPage));
2853
- const [appliedFilters, setAppliedFilters] = useState10(initialFilters);
2854
- const [deletePreviewOpen, setDeletePreviewOpen] = useState10(false);
2855
- const [deletePreview, setDeletePreview] = useState10(null);
2856
- const [deletePreviewError, setDeletePreviewError] = useState10(null);
2857
- const [isDeletePreviewLoading, setIsDeletePreviewLoading] = useState10(false);
2858
- const [isDeleteSubmitting, setIsDeleteSubmitting] = useState10(false);
2859
- const [pendingDeleteIds, setPendingDeleteIds] = useState10([]);
2860
- const [pendingDeleteSelectAll, setPendingDeleteSelectAll] = useState10(false);
2861
- const [pendingDeleteScope, setPendingDeleteScope] = useState10(null);
2862
- const [pendingDeleteMode, setPendingDeleteMode] = useState10("single");
2863
- const [filtersOpen, setFiltersOpen] = useState10(false);
2864
- const requestIdRef = useRef4(0);
2865
- const dataRef = useRef4(initialCachedResponse);
2866
- const pageSizeRef = useRef4((_d = initialCachedResponse == null ? void 0 : initialCachedResponse.meta.page_size) != null ? _d : DEFAULT_PAGE_SIZE);
2867
- const previousSlugRef = useRef4(slug);
3280
+ const [selectedIds, setSelectedIds] = useState11([]);
3281
+ const [isAllMatchingSelected, setIsAllMatchingSelected] = useState11(false);
3282
+ const [createOpen, setCreateOpen] = useState11(false);
3283
+ const [data, setData] = useState11(() => initialCachedResponse);
3284
+ const [error, setError] = useState11(null);
3285
+ const [isLoading, setIsLoading] = useState11(initialCachedResponse === null);
3286
+ const [rowActionMenuAnchor, setRowActionMenuAnchor] = useState11(null);
3287
+ const [rowActionMenuId, setRowActionMenuId] = useState11(null);
3288
+ const [bulkActionMenuAnchor, setBulkActionMenuAnchor] = useState11(null);
3289
+ const [bulkActionFormSlug, setBulkActionFormSlug] = useState11(null);
3290
+ const [appliedQuery, setAppliedQuery] = useState11(initialQuery);
3291
+ const [sortValue, setSortValue] = useState11(initialSort);
3292
+ const [currentPage, setCurrentPage] = useState11(initialPage);
3293
+ const [pageInput, setPageInput] = useState11(String(initialPage));
3294
+ const [appliedFilters, setAppliedFilters] = useState11(initialFilters);
3295
+ const [deletePreviewOpen, setDeletePreviewOpen] = useState11(false);
3296
+ const [deletePreview, setDeletePreview] = useState11(null);
3297
+ const [deletePreviewError, setDeletePreviewError] = useState11(null);
3298
+ const [isDeletePreviewLoading, setIsDeletePreviewLoading] = useState11(false);
3299
+ const [isDeleteSubmitting, setIsDeleteSubmitting] = useState11(false);
3300
+ const [pendingDeleteIds, setPendingDeleteIds] = useState11([]);
3301
+ const [pendingDeleteSelectAll, setPendingDeleteSelectAll] = useState11(false);
3302
+ const [pendingDeleteScope, setPendingDeleteScope] = useState11(null);
3303
+ const [pendingDeleteMode, setPendingDeleteMode] = useState11("single");
3304
+ const [filtersOpen, setFiltersOpen] = useState11(false);
3305
+ const requestIdRef = useRef6(0);
3306
+ const dataRef = useRef6(initialCachedResponse);
3307
+ const pageSizeRef = useRef6((_d = initialCachedResponse == null ? void 0 : initialCachedResponse.meta.page_size) != null ? _d : DEFAULT_PAGE_SIZE);
3308
+ const previousSlugRef = useRef6(slug);
2868
3309
  const sortFields = useMemo9(() => sortValue.split(",").filter(Boolean), [sortValue]);
2869
3310
  const meta = (_e = data == null ? void 0 : data.meta) != null ? _e : null;
2870
3311
  const rows = (_f = data == null ? void 0 : data.items) != null ? _f : [];
@@ -2908,10 +3349,10 @@ function useModelPageController({
2908
3349
  });
2909
3350
  const hasSelection = isAllMatchingSelected || selectedIds.length > 0;
2910
3351
  const selectionCount = isAllMatchingSelected ? total : selectedIds.length;
2911
- useEffect10(() => {
3352
+ useEffect12(() => {
2912
3353
  dataRef.current = data;
2913
3354
  }, [data]);
2914
- useEffect10(() => {
3355
+ useEffect12(() => {
2915
3356
  setPageInput(String(currentPage));
2916
3357
  }, [currentPage]);
2917
3358
  useLayoutEffect2(() => {
@@ -2944,6 +3385,7 @@ function useModelPageController({
2944
3385
  setRowActionMenuAnchor(null);
2945
3386
  setRowActionMenuId(null);
2946
3387
  setBulkActionMenuAnchor(null);
3388
+ setBulkActionFormSlug(null);
2947
3389
  setDeletePreviewOpen(false);
2948
3390
  setDeletePreview(null);
2949
3391
  setDeletePreviewError(null);
@@ -3015,7 +3457,7 @@ function useModelPageController({
3015
3457
  }
3016
3458
  }
3017
3459
  }, [appliedFilters, appliedQuery, client, currentPage, isAllMatchingSelected, slug, sortValue, t]);
3018
- useEffect10(() => {
3460
+ useEffect12(() => {
3019
3461
  void loadItems();
3020
3462
  }, [loadItems]);
3021
3463
  const refresh = useCallback5(async () => {
@@ -3167,7 +3609,7 @@ function useModelPageController({
3167
3609
  }
3168
3610
  }, [clearSelection, client, message, pendingDeleteIds, pendingDeleteMode, pendingDeleteScope, pendingDeleteSelectAll, refresh, slug, t]);
3169
3611
  const handleRunNamedBulkAction = useCallback5(async (actionSlug) => {
3170
- var _a2, _b2;
3612
+ var _a2, _b2, _c2, _d2;
3171
3613
  if (!actionSlug || !hasSelection) {
3172
3614
  return;
3173
3615
  }
@@ -3175,6 +3617,12 @@ function useModelPageController({
3175
3617
  await openBulkDeletePreview();
3176
3618
  return;
3177
3619
  }
3620
+ const action = bulkActions.find((item) => item.slug === actionSlug);
3621
+ if (((_b2 = (_a2 = action == null ? void 0 : action.form) == null ? void 0 : _a2.length) != null ? _b2 : 0) > 0) {
3622
+ setBulkActionMenuAnchor(null);
3623
+ setBulkActionFormSlug(actionSlug);
3624
+ return;
3625
+ }
3178
3626
  try {
3179
3627
  const response = await client.runBulkAction(
3180
3628
  slug,
@@ -3186,7 +3634,7 @@ function useModelPageController({
3186
3634
  setBulkActionMenuAnchor(null);
3187
3635
  clearSelection();
3188
3636
  await refresh();
3189
- const actionLabel = (_b2 = (_a2 = bulkActions.find((item) => item.slug === actionSlug)) == null ? void 0 : _a2.label) != null ? _b2 : actionSlug;
3637
+ const actionLabel = (_d2 = (_c2 = bulkActions.find((item) => item.slug === actionSlug)) == null ? void 0 : _c2.label) != null ? _d2 : actionSlug;
3190
3638
  message.success(t("action_success", { action: actionLabel, count: response.processed }));
3191
3639
  } catch (reason) {
3192
3640
  const nextError = reason instanceof Error ? reason.message : t("object_action_error");
@@ -3194,6 +3642,34 @@ function useModelPageController({
3194
3642
  message.error(nextError);
3195
3643
  }
3196
3644
  }, [bulkActions, clearSelection, client, hasSelection, isAllMatchingSelected, message, openBulkDeletePreview, refresh, selectedIds, selectionScope, slug, t]);
3645
+ const handleSubmitBulkActionForm = useCallback5(async (payload) => {
3646
+ var _a2, _b2;
3647
+ if (!bulkActionFormSlug || !hasSelection) {
3648
+ return;
3649
+ }
3650
+ const response = await client.runBulkAction(
3651
+ slug,
3652
+ bulkActionFormSlug,
3653
+ isAllMatchingSelected ? [] : selectedIds,
3654
+ payload,
3655
+ isAllMatchingSelected ? { selectAll: true, selectionScope } : void 0
3656
+ );
3657
+ setBulkActionFormSlug(null);
3658
+ clearSelection();
3659
+ await refresh();
3660
+ const actionLabel = (_b2 = (_a2 = bulkActions.find((item) => item.slug === bulkActionFormSlug)) == null ? void 0 : _a2.label) != null ? _b2 : bulkActionFormSlug;
3661
+ message.success(t("action_success", { action: actionLabel, count: response.processed }));
3662
+ }, [bulkActionFormSlug, bulkActions, clearSelection, client, hasSelection, isAllMatchingSelected, message, refresh, selectedIds, selectionScope, slug, t]);
3663
+ const handleCloseBulkActionForm = useCallback5(() => {
3664
+ setBulkActionFormSlug(null);
3665
+ }, []);
3666
+ const activeBulkAction = useMemo9(
3667
+ () => {
3668
+ var _a2;
3669
+ return (_a2 = bulkActions.find((item) => item.slug === bulkActionFormSlug)) != null ? _a2 : null;
3670
+ },
3671
+ [bulkActionFormSlug, bulkActions]
3672
+ );
3197
3673
  const handleRowDelete = useCallback5(async (rowId) => {
3198
3674
  setRowActionMenuAnchor(null);
3199
3675
  setRowActionMenuId(null);
@@ -3271,6 +3747,7 @@ function useModelPageController({
3271
3747
  appliedQuery,
3272
3748
  bulkActionMenuAnchor,
3273
3749
  bulkActions,
3750
+ activeBulkAction,
3274
3751
  clearBulkDeleteState,
3275
3752
  createOpen,
3276
3753
  currentPage,
@@ -3283,6 +3760,7 @@ function useModelPageController({
3283
3760
  filtersOpen,
3284
3761
  handleClearDeletePreview,
3285
3762
  handleCloseBulkActionMenu,
3763
+ handleCloseBulkActionForm,
3286
3764
  handleCloseRowMenu,
3287
3765
  handleConfirmDelete,
3288
3766
  handleFilterChange,
@@ -3292,6 +3770,7 @@ function useModelPageController({
3292
3770
  handleResetFilters,
3293
3771
  handleRowDelete,
3294
3772
  handleRunNamedBulkAction,
3773
+ handleSubmitBulkActionForm,
3295
3774
  handleSearchCommit,
3296
3775
  handleSelectAllMatching,
3297
3776
  handleToggleAllVisible,
@@ -3373,34 +3852,34 @@ function extractFilterParams(params) {
3373
3852
  }
3374
3853
 
3375
3854
  // src/components/model-page/Skeletons.tsx
3376
- import { Box as Box9, Paper as Paper6, Skeleton as Skeleton3, Stack as Stack9 } from "@mui/material";
3377
- import { jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
3855
+ import { Box as Box10, Paper as Paper6, Skeleton as Skeleton3, Stack as Stack9 } from "@mui/material";
3856
+ import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
3378
3857
  function ModelPageSkeleton() {
3379
- return /* @__PURE__ */ jsxs12(Stack9, { spacing: 1.5, sx: { height: "100%", minHeight: 0 }, children: [
3380
- /* @__PURE__ */ jsx19(MainHeaderSkeleton, { titleWidth: 240, subtitleWidth: "38%" }),
3381
- /* @__PURE__ */ jsx19(Paper6, { sx: { p: 1.5, borderRadius: "10px", flexShrink: 0 }, children: /* @__PURE__ */ jsxs12(Stack9, { direction: { xs: "column", lg: "row" }, spacing: 1.5, alignItems: { lg: "center" }, children: [
3382
- /* @__PURE__ */ jsx19(Skeleton3, { variant: "rounded", width: 360, height: 40 }),
3383
- /* @__PURE__ */ jsx19(Skeleton3, { variant: "rounded", width: 128, height: 40 }),
3384
- /* @__PURE__ */ jsx19(Box9, { sx: { flex: 1 } }),
3385
- /* @__PURE__ */ jsx19(Skeleton3, { variant: "rounded", width: 110, height: 24 })
3858
+ return /* @__PURE__ */ jsxs13(Stack9, { spacing: 1.5, sx: { height: "100%", minHeight: 0 }, children: [
3859
+ /* @__PURE__ */ jsx20(MainHeaderSkeleton, { titleWidth: 240, subtitleWidth: "38%" }),
3860
+ /* @__PURE__ */ jsx20(Paper6, { sx: { p: 1.5, borderRadius: "10px", flexShrink: 0 }, children: /* @__PURE__ */ jsxs13(Stack9, { direction: { xs: "column", lg: "row" }, spacing: 1.5, sx: { alignItems: { lg: "center" } }, children: [
3861
+ /* @__PURE__ */ jsx20(Skeleton3, { variant: "rounded", width: 360, height: 40 }),
3862
+ /* @__PURE__ */ jsx20(Skeleton3, { variant: "rounded", width: 128, height: 40 }),
3863
+ /* @__PURE__ */ jsx20(Box10, { sx: { flex: 1 } }),
3864
+ /* @__PURE__ */ jsx20(Skeleton3, { variant: "rounded", width: 110, height: 24 })
3386
3865
  ] }) }),
3387
- /* @__PURE__ */ jsx19(Paper6, { sx: { borderRadius: "10px", flex: 1, minHeight: 0, overflow: "hidden" }, children: /* @__PURE__ */ jsx19(ModelTableSkeleton, {}) })
3866
+ /* @__PURE__ */ jsx20(Paper6, { sx: { borderRadius: "10px", flex: 1, minHeight: 0, overflow: "hidden" }, children: /* @__PURE__ */ jsx20(ModelTableSkeleton, {}) })
3388
3867
  ] });
3389
3868
  }
3390
3869
  function ModelTableSkeleton() {
3391
- return /* @__PURE__ */ jsx19(Box9, { sx: { height: "100%", overflow: "auto", p: 1.5 }, children: /* @__PURE__ */ jsxs12(Stack9, { spacing: 1, children: [
3392
- /* @__PURE__ */ jsx19(Skeleton3, { variant: "rounded", width: "100%", height: 42 }),
3393
- Array.from({ length: 10 }).map((_, index) => /* @__PURE__ */ jsx19(Skeleton3, { variant: "rounded", width: "100%", height: 48 }, index))
3870
+ return /* @__PURE__ */ jsx20(Box10, { sx: { height: "100%", overflow: "auto", p: 1.5 }, children: /* @__PURE__ */ jsxs13(Stack9, { spacing: 1, children: [
3871
+ /* @__PURE__ */ jsx20(Skeleton3, { variant: "rounded", width: "100%", height: 42 }),
3872
+ Array.from({ length: 10 }).map((_, index) => /* @__PURE__ */ jsx20(Skeleton3, { variant: "rounded", width: "100%", height: 48 }, index))
3394
3873
  ] }) });
3395
3874
  }
3396
3875
 
3397
3876
  // src/components/ModelPage.tsx
3398
- import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
3877
+ import { jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
3399
3878
  var SEARCH_DEBOUNCE_MS = 300;
3400
3879
  var CHECKBOX_COLUMN_WIDTH = 56;
3401
3880
  var ACTIONS_COLUMN_WIDTH = 56;
3402
3881
  function ModelPage({ client, basePath, slug, router, renderBeforePagination }) {
3403
- var _a, _b;
3882
+ var _a, _b, _c;
3404
3883
  const locale = useAdminLocale();
3405
3884
  const t = useAdminTranslation();
3406
3885
  const selectAllLabel = locale === "ru" ? "\u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0432\u0441\u0435" : "Select All";
@@ -3434,10 +3913,10 @@ function ModelPage({ client, basePath, slug, router, renderBeforePagination }) {
3434
3913
  }, [controller.error, controller.isLoading, controller.meta, finishPendingNavigation, location.pathname, pendingPath, slug]);
3435
3914
  useAdminDocumentTitle(t("admin_title"), (_b = (_a = controller.meta) == null ? void 0 : _a.title) != null ? _b : slug);
3436
3915
  if (!controller.isLoading && controller.error && !controller.data) {
3437
- return /* @__PURE__ */ jsx20(Alert5, { severity: "error", children: controller.error });
3916
+ return /* @__PURE__ */ jsx21(Alert6, { severity: "error", children: controller.error });
3438
3917
  }
3439
3918
  if (!controller.data || !controller.meta) {
3440
- return /* @__PURE__ */ jsx20(ModelPageSkeleton, {});
3919
+ return /* @__PURE__ */ jsx21(ModelPageSkeleton, {});
3441
3920
  }
3442
3921
  const meta = controller.meta;
3443
3922
  const beforePagination = renderBeforePagination == null ? void 0 : renderBeforePagination({
@@ -3456,12 +3935,12 @@ function ModelPage({ client, basePath, slug, router, renderBeforePagination }) {
3456
3935
  appliedFilters: controller.appliedFilters,
3457
3936
  refresh: controller.refresh
3458
3937
  });
3459
- return /* @__PURE__ */ jsx20(AdminRouterProvider, { router: resolvedRouter, children: /* @__PURE__ */ jsxs13(Stack10, { spacing: 1.5, sx: { height: "100%", minHeight: 0 }, children: [
3460
- /* @__PURE__ */ jsx20(
3938
+ return /* @__PURE__ */ jsx21(AdminRouterProvider, { router: resolvedRouter, children: /* @__PURE__ */ jsxs14(Stack10, { spacing: 1.5, sx: { height: "100%", minHeight: 0 }, children: [
3939
+ /* @__PURE__ */ jsx21(
3461
3940
  MainHeader,
3462
3941
  {
3463
3942
  title: controller.meta.title,
3464
- actions: /* @__PURE__ */ jsx20(Tooltip, { title: t("create"), children: /* @__PURE__ */ jsx20(
3943
+ actions: /* @__PURE__ */ jsx21(Tooltip, { title: t("create"), children: /* @__PURE__ */ jsx21(
3465
3944
  IconButton3,
3466
3945
  {
3467
3946
  "aria-label": t("create"),
@@ -3476,14 +3955,14 @@ function ModelPage({ client, basePath, slug, router, renderBeforePagination }) {
3476
3955
  backgroundColor: "primary.dark"
3477
3956
  }
3478
3957
  },
3479
- children: /* @__PURE__ */ jsx20(AddIcon, { fontSize: "small" })
3958
+ children: /* @__PURE__ */ jsx21(AddIcon, { fontSize: "small" })
3480
3959
  }
3481
3960
  ) }),
3482
3961
  subtitle: `${controller.meta.slug} | ${t("objects_count", { count: controller.total })}`,
3483
- details: controller.meta.description ? /* @__PURE__ */ jsx20(Typography6, { color: "text.secondary", sx: { fontSize: 14, lineHeight: 1.45 }, children: controller.meta.description }) : void 0
3962
+ details: controller.meta.description ? /* @__PURE__ */ jsx21(Typography6, { color: "text.secondary", sx: { fontSize: 14, lineHeight: 1.45 }, children: controller.meta.description }) : void 0
3484
3963
  }
3485
3964
  ),
3486
- /* @__PURE__ */ jsx20(
3965
+ /* @__PURE__ */ jsx21(
3487
3966
  Paper7,
3488
3967
  {
3489
3968
  sx: {
@@ -3491,16 +3970,15 @@ function ModelPage({ client, basePath, slug, router, renderBeforePagination }) {
3491
3970
  borderRadius: "10px",
3492
3971
  flexShrink: 0
3493
3972
  },
3494
- children: /* @__PURE__ */ jsxs13(Stack10, { direction: { xs: "column", lg: "row" }, spacing: 1.5, alignItems: { lg: "center" }, children: [
3495
- /* @__PURE__ */ jsxs13(
3973
+ children: /* @__PURE__ */ jsxs14(Stack10, { direction: { xs: "column", lg: "row" }, spacing: 1.5, sx: { alignItems: { lg: "center" } }, children: [
3974
+ /* @__PURE__ */ jsxs14(
3496
3975
  Stack10,
3497
3976
  {
3498
3977
  direction: { xs: "column", xl: "row" },
3499
3978
  spacing: 1.5,
3500
- alignItems: { xl: "center" },
3501
- sx: { flex: 1, minWidth: 0 },
3979
+ sx: { flex: 1, minWidth: 0, alignItems: { xl: "center" } },
3502
3980
  children: [
3503
- /* @__PURE__ */ jsx20(
3981
+ /* @__PURE__ */ jsx21(
3504
3982
  SearchField,
3505
3983
  {
3506
3984
  value: controller.appliedQuery,
@@ -3509,18 +3987,18 @@ function ModelPage({ client, basePath, slug, router, renderBeforePagination }) {
3509
3987
  placeholder: t("search")
3510
3988
  }
3511
3989
  ),
3512
- controller.hasSelection ? /* @__PURE__ */ jsxs13(Stack10, { direction: "row", spacing: 1, alignItems: "center", sx: { minWidth: 0, flexWrap: "wrap" }, children: [
3513
- /* @__PURE__ */ jsx20(
3514
- Button4,
3990
+ controller.hasSelection ? /* @__PURE__ */ jsxs14(Stack10, { direction: "row", spacing: 1, sx: { minWidth: 0, flexWrap: "wrap", alignItems: "center" }, children: [
3991
+ /* @__PURE__ */ jsx21(
3992
+ Button5,
3515
3993
  {
3516
3994
  variant: "outlined",
3517
- endIcon: /* @__PURE__ */ jsx20(ExpandMoreIcon4, {}),
3995
+ endIcon: /* @__PURE__ */ jsx21(ExpandMoreIcon4, {}),
3518
3996
  onClick: (event) => controller.setBulkActionMenuAnchor(event.currentTarget),
3519
3997
  children: t("actions")
3520
3998
  }
3521
3999
  ),
3522
- !controller.isAllMatchingSelected && controller.selectionCount < controller.total ? /* @__PURE__ */ jsx20(
3523
- Button4,
4000
+ !controller.isAllMatchingSelected && controller.selectionCount < controller.total ? /* @__PURE__ */ jsx21(
4001
+ Button5,
3524
4002
  {
3525
4003
  variant: "text",
3526
4004
  onClick: controller.handleSelectAllMatching,
@@ -3528,7 +4006,7 @@ function ModelPage({ client, basePath, slug, router, renderBeforePagination }) {
3528
4006
  children: selectAllLabel
3529
4007
  }
3530
4008
  ) : null,
3531
- /* @__PURE__ */ jsxs13(Typography6, { color: "text.secondary", sx: { alignSelf: "center", whiteSpace: "nowrap" }, children: [
4009
+ /* @__PURE__ */ jsxs14(Typography6, { color: "text.secondary", sx: { alignSelf: "center", whiteSpace: "nowrap" }, children: [
3532
4010
  t("selected_count", { count: controller.selectionCount }),
3533
4011
  " / ",
3534
4012
  controller.total
@@ -3537,28 +4015,28 @@ function ModelPage({ client, basePath, slug, router, renderBeforePagination }) {
3537
4015
  ]
3538
4016
  }
3539
4017
  ),
3540
- /* @__PURE__ */ jsxs13(Stack10, { direction: "row", spacing: 1, alignItems: "center", sx: { marginLeft: "auto" }, children: [
3541
- beforePagination ? /* @__PURE__ */ jsx20(Box10, { sx: { display: "flex", alignItems: "center", flexShrink: 0 }, children: beforePagination }) : null,
3542
- isMobile && controller.hasListFilters ? /* @__PURE__ */ jsx20(Tooltip, { title: t("filters"), children: /* @__PURE__ */ jsx20(
4018
+ /* @__PURE__ */ jsxs14(Stack10, { direction: "row", spacing: 1, sx: { marginLeft: "auto", alignItems: "center" }, children: [
4019
+ beforePagination ? /* @__PURE__ */ jsx21(Box11, { sx: { display: "flex", alignItems: "center", flexShrink: 0 }, children: beforePagination }) : null,
4020
+ isMobile && controller.hasListFilters ? /* @__PURE__ */ jsx21(Tooltip, { title: t("filters"), children: /* @__PURE__ */ jsx21(
3543
4021
  IconButton3,
3544
4022
  {
3545
4023
  size: "small",
3546
4024
  "aria-label": t("filters"),
3547
4025
  onClick: () => controller.setFiltersOpen(true),
3548
- children: /* @__PURE__ */ jsx20(FilterListIcon, { fontSize: "small" })
4026
+ children: /* @__PURE__ */ jsx21(FilterListIcon, { fontSize: "small" })
3549
4027
  }
3550
4028
  ) }) : null,
3551
- /* @__PURE__ */ jsx20(
4029
+ /* @__PURE__ */ jsx21(
3552
4030
  IconButton3,
3553
4031
  {
3554
4032
  size: "small",
3555
4033
  onClick: () => controller.handlePageChange(controller.currentPage - 1),
3556
4034
  disabled: controller.currentPage <= 1,
3557
4035
  sx: { mr: "-5px" },
3558
- children: /* @__PURE__ */ jsx20(ChevronLeftIcon, { fontSize: "small" })
4036
+ children: /* @__PURE__ */ jsx21(ChevronLeftIcon, { fontSize: "small" })
3559
4037
  }
3560
4038
  ),
3561
- /* @__PURE__ */ jsx20(
4039
+ /* @__PURE__ */ jsx21(
3562
4040
  InputBase,
3563
4041
  {
3564
4042
  value: controller.pageInput,
@@ -3588,7 +4066,7 @@ function ModelPage({ client, basePath, slug, router, renderBeforePagination }) {
3588
4066
  }
3589
4067
  }
3590
4068
  ),
3591
- /* @__PURE__ */ jsxs13(
4069
+ /* @__PURE__ */ jsxs14(
3592
4070
  Typography6,
3593
4071
  {
3594
4072
  color: "text.secondary",
@@ -3599,22 +4077,22 @@ function ModelPage({ client, basePath, slug, router, renderBeforePagination }) {
3599
4077
  ]
3600
4078
  }
3601
4079
  ),
3602
- /* @__PURE__ */ jsx20(
4080
+ /* @__PURE__ */ jsx21(
3603
4081
  IconButton3,
3604
4082
  {
3605
4083
  size: "small",
3606
4084
  onClick: () => controller.handlePageChange(controller.currentPage + 1),
3607
4085
  disabled: controller.currentPage >= controller.totalPages,
3608
4086
  sx: { ml: "-5px" },
3609
- children: /* @__PURE__ */ jsx20(ChevronRightIcon, { fontSize: "small" })
4087
+ children: /* @__PURE__ */ jsx21(ChevronRightIcon, { fontSize: "small" })
3610
4088
  }
3611
4089
  )
3612
4090
  ] })
3613
4091
  ] })
3614
4092
  }
3615
4093
  ),
3616
- /* @__PURE__ */ jsxs13(Stack10, { direction: { xs: "column", lg: "row" }, spacing: 1.5, sx: { flex: 1, minHeight: 0 }, children: [
3617
- /* @__PURE__ */ jsx20(
4094
+ /* @__PURE__ */ jsxs14(Stack10, { direction: { xs: "column", lg: "row" }, spacing: 1.5, sx: { flex: 1, minHeight: 0 }, children: [
4095
+ /* @__PURE__ */ jsx21(
3618
4096
  Paper7,
3619
4097
  {
3620
4098
  sx: {
@@ -3624,9 +4102,9 @@ function ModelPage({ client, basePath, slug, router, renderBeforePagination }) {
3624
4102
  minHeight: 0,
3625
4103
  overflow: "hidden"
3626
4104
  },
3627
- children: controller.isLoading ? /* @__PURE__ */ jsx20(ModelTableSkeleton, {}) : /* @__PURE__ */ jsx20(Box10, { sx: { height: "100%", overflow: "auto" }, children: /* @__PURE__ */ jsxs13(Table, { stickyHeader: true, size: "small", sx: { tableLayout: "fixed" }, children: [
3628
- /* @__PURE__ */ jsx20(TableHead, { children: /* @__PURE__ */ jsxs13(TableRow2, { children: [
3629
- /* @__PURE__ */ jsx20(
4105
+ children: controller.isLoading ? /* @__PURE__ */ jsx21(ModelTableSkeleton, {}) : /* @__PURE__ */ jsx21(Box11, { sx: { height: "100%", overflow: "auto" }, children: /* @__PURE__ */ jsxs14(Table, { stickyHeader: true, size: "small", sx: { tableLayout: "fixed" }, children: [
4106
+ /* @__PURE__ */ jsx21(TableHead, { children: /* @__PURE__ */ jsxs14(TableRow2, { children: [
4107
+ /* @__PURE__ */ jsx21(
3630
4108
  TableCell2,
3631
4109
  {
3632
4110
  padding: "none",
@@ -3639,7 +4117,7 @@ function ModelPage({ client, basePath, slug, router, renderBeforePagination }) {
3639
4117
  textAlign: "center",
3640
4118
  px: 1
3641
4119
  },
3642
- children: /* @__PURE__ */ jsx20(
4120
+ children: /* @__PURE__ */ jsx21(
3643
4121
  Checkbox2,
3644
4122
  {
3645
4123
  checked: controller.allVisibleSelected,
@@ -3654,7 +4132,7 @@ function ModelPage({ client, basePath, slug, router, renderBeforePagination }) {
3654
4132
  const field = controller.fieldMap.get(fieldName);
3655
4133
  const sortDirection = resolveSortDirection(controller.sortFields, fieldName);
3656
4134
  const isSortable = resolveFieldSortable(field);
3657
- return /* @__PURE__ */ jsx20(
4135
+ return /* @__PURE__ */ jsx21(
3658
4136
  TableCell2,
3659
4137
  {
3660
4138
  sortDirection: sortDirection != null ? sortDirection : false,
@@ -3667,7 +4145,7 @@ function ModelPage({ client, basePath, slug, router, renderBeforePagination }) {
3667
4145
  maxWidth: getListFieldWidthPx(field)
3668
4146
  },
3669
4147
  onClick: isSortable ? () => controller.toggleSort(fieldName) : void 0,
3670
- children: isSortable ? /* @__PURE__ */ jsx20(
4148
+ children: isSortable ? /* @__PURE__ */ jsx21(
3671
4149
  TableSortLabel,
3672
4150
  {
3673
4151
  active: Boolean(sortDirection),
@@ -3681,7 +4159,7 @@ function ModelPage({ client, basePath, slug, router, renderBeforePagination }) {
3681
4159
  },
3682
4160
  children: (_a2 = field == null ? void 0 : field.label) != null ? _a2 : fieldName
3683
4161
  }
3684
- ) : /* @__PURE__ */ jsx20(Typography6, { component: "span", sx: {
4162
+ ) : /* @__PURE__ */ jsx21(Typography6, { component: "span", sx: {
3685
4163
  fontSize: 14,
3686
4164
  fontWeight: 700,
3687
4165
  color: "rgba(255, 255, 255, 0.96)"
@@ -3690,7 +4168,7 @@ function ModelPage({ client, basePath, slug, router, renderBeforePagination }) {
3690
4168
  fieldName
3691
4169
  );
3692
4170
  }),
3693
- /* @__PURE__ */ jsx20(
4171
+ /* @__PURE__ */ jsx21(
3694
4172
  TableCell2,
3695
4173
  {
3696
4174
  align: "right",
@@ -3703,9 +4181,9 @@ function ModelPage({ client, basePath, slug, router, renderBeforePagination }) {
3703
4181
  }
3704
4182
  )
3705
4183
  ] }) }),
3706
- /* @__PURE__ */ jsx20(TableBody, { children: controller.rows.map((row) => {
4184
+ /* @__PURE__ */ jsx21(TableBody, { children: controller.rows.map((row) => {
3707
4185
  const rowId = row[meta.pk_field];
3708
- return /* @__PURE__ */ jsx20(
4186
+ return /* @__PURE__ */ jsx21(
3709
4187
  ListRow,
3710
4188
  {
3711
4189
  row,
@@ -3725,7 +4203,7 @@ function ModelPage({ client, basePath, slug, router, renderBeforePagination }) {
3725
4203
  ] }) })
3726
4204
  }
3727
4205
  ),
3728
- !isMobile && controller.hasListFilters ? /* @__PURE__ */ jsx20(
4206
+ !isMobile && controller.hasListFilters ? /* @__PURE__ */ jsx21(
3729
4207
  ListFiltersSidebar,
3730
4208
  {
3731
4209
  client,
@@ -3738,14 +4216,14 @@ function ModelPage({ client, basePath, slug, router, renderBeforePagination }) {
3738
4216
  }
3739
4217
  ) : null
3740
4218
  ] }),
3741
- /* @__PURE__ */ jsx20(
4219
+ /* @__PURE__ */ jsx21(
3742
4220
  Menu,
3743
4221
  {
3744
4222
  anchorEl: controller.bulkActionMenuAnchor,
3745
4223
  open: Boolean(controller.bulkActionMenuAnchor),
3746
4224
  onClose: controller.handleCloseBulkActionMenu,
3747
- children: controller.bulkActions.map((action) => /* @__PURE__ */ jsx20(
3748
- MenuItem2,
4225
+ children: controller.bulkActions.map((action) => /* @__PURE__ */ jsx21(
4226
+ MenuItem3,
3749
4227
  {
3750
4228
  onClick: () => void controller.handleRunNamedBulkAction(action.slug),
3751
4229
  children: action.label
@@ -3754,14 +4232,14 @@ function ModelPage({ client, basePath, slug, router, renderBeforePagination }) {
3754
4232
  ))
3755
4233
  }
3756
4234
  ),
3757
- /* @__PURE__ */ jsx20(
4235
+ /* @__PURE__ */ jsx21(
3758
4236
  Menu,
3759
4237
  {
3760
4238
  anchorEl: controller.rowActionMenuAnchor,
3761
4239
  open: Boolean(controller.rowActionMenuAnchor),
3762
4240
  onClose: controller.handleCloseRowMenu,
3763
- children: /* @__PURE__ */ jsx20(
3764
- MenuItem2,
4241
+ children: /* @__PURE__ */ jsx21(
4242
+ MenuItem3,
3765
4243
  {
3766
4244
  onClick: () => {
3767
4245
  if (controller.rowActionMenuId !== null) {
@@ -3773,7 +4251,7 @@ function ModelPage({ client, basePath, slug, router, renderBeforePagination }) {
3773
4251
  )
3774
4252
  }
3775
4253
  ),
3776
- /* @__PURE__ */ jsx20(
4254
+ /* @__PURE__ */ jsx21(
3777
4255
  FormDialog,
3778
4256
  {
3779
4257
  open: controller.createOpen,
@@ -3786,8 +4264,24 @@ function ModelPage({ client, basePath, slug, router, renderBeforePagination }) {
3786
4264
  client
3787
4265
  }
3788
4266
  ),
3789
- /* @__PURE__ */ jsxs13(
3790
- Dialog3,
4267
+ ((_c = controller.activeBulkAction) == null ? void 0 : _c.form) ? /* @__PURE__ */ jsx21(
4268
+ ActionFormDialog,
4269
+ {
4270
+ open: true,
4271
+ onClose: controller.handleCloseBulkActionForm,
4272
+ onSuccess: () => void 0,
4273
+ title: `${controller.activeBulkAction.label}: ${meta.title}`,
4274
+ submitLabel: controller.activeBulkAction.label,
4275
+ slug,
4276
+ locale: meta.locale,
4277
+ fields: controller.activeBulkAction.form,
4278
+ client,
4279
+ choiceScope: { kind: "bulk-action", actionSlug: controller.activeBulkAction.slug },
4280
+ onSubmit: controller.handleSubmitBulkActionForm
4281
+ }
4282
+ ) : null,
4283
+ /* @__PURE__ */ jsxs14(
4284
+ Dialog4,
3791
4285
  {
3792
4286
  open: controller.filtersOpen,
3793
4287
  onClose: () => controller.setFiltersOpen(false),
@@ -3807,8 +4301,8 @@ function ModelPage({ client, basePath, slug, router, renderBeforePagination }) {
3807
4301
  }
3808
4302
  },
3809
4303
  children: [
3810
- /* @__PURE__ */ jsx20(DialogTitle3, { children: t("filters") }),
3811
- /* @__PURE__ */ jsx20(DialogContent3, { sx: { px: 2, pb: 2 }, children: controller.hasListFilters ? /* @__PURE__ */ jsx20(
4304
+ /* @__PURE__ */ jsx21(DialogTitle4, { children: t("filters") }),
4305
+ /* @__PURE__ */ jsx21(DialogContent4, { sx: { px: 2, pb: 2 }, children: controller.hasListFilters ? /* @__PURE__ */ jsx21(
3812
4306
  ListFiltersSidebar,
3813
4307
  {
3814
4308
  client,
@@ -3823,7 +4317,7 @@ function ModelPage({ client, basePath, slug, router, renderBeforePagination }) {
3823
4317
  ]
3824
4318
  }
3825
4319
  ),
3826
- /* @__PURE__ */ jsx20(
4320
+ /* @__PURE__ */ jsx21(
3827
4321
  DeletePreviewDialog,
3828
4322
  {
3829
4323
  open: controller.deletePreviewOpen,
@@ -3859,16 +4353,16 @@ function resolveFieldSortable(field) {
3859
4353
  import { useLayoutEffect as useLayoutEffect5 } from "react";
3860
4354
  import ArrowBackIcon from "@mui/icons-material/ArrowBack";
3861
4355
  import MoreVertIcon2 from "@mui/icons-material/MoreVert";
3862
- import { Alert as Alert6, Box as Box13, Button as Button5, IconButton as IconButton4, Menu as Menu2, MenuItem as MenuItem3, Paper as Paper9, Stack as Stack13, Typography as Typography7, useMediaQuery as useMediaQuery3 } from "@mui/material";
3863
- import { LocalizationProvider as LocalizationProvider2 } from "@mui/x-date-pickers";
3864
- import { AdapterDayjs as AdapterDayjs2 } from "@mui/x-date-pickers/AdapterDayjs";
4356
+ import { Alert as Alert7, Box as Box14, Button as Button6, IconButton as IconButton4, Menu as Menu2, MenuItem as MenuItem4, Paper as Paper9, Stack as Stack13, Typography as Typography7, useMediaQuery as useMediaQuery3 } from "@mui/material";
4357
+ import { LocalizationProvider as LocalizationProvider3 } from "@mui/x-date-pickers";
4358
+ import { AdapterDayjs as AdapterDayjs3 } from "@mui/x-date-pickers/AdapterDayjs";
3865
4359
  import { useTheme as useTheme4 } from "@mui/material/styles";
3866
4360
  import "dayjs/locale/en.js";
3867
4361
  import "dayjs/locale/ru.js";
3868
4362
 
3869
4363
  // src/components/object-page/ObjectField.tsx
3870
4364
  import { memo as memo6, useCallback as useCallback6 } from "react";
3871
- import { jsx as jsx21 } from "react/jsx-runtime";
4365
+ import { jsx as jsx22 } from "react/jsx-runtime";
3872
4366
  var ObjectField = memo6(function ObjectField2({
3873
4367
  field,
3874
4368
  value,
@@ -3879,7 +4373,7 @@ var ObjectField = memo6(function ObjectField2({
3879
4373
  const handleChange = useCallback6((nextValue) => {
3880
4374
  onFieldChange(field.name, nextValue);
3881
4375
  }, [field.name, onFieldChange]);
3882
- return /* @__PURE__ */ jsx21(
4376
+ return /* @__PURE__ */ jsx22(
3883
4377
  FieldEditor,
3884
4378
  {
3885
4379
  field,
@@ -3892,20 +4386,20 @@ var ObjectField = memo6(function ObjectField2({
3892
4386
  });
3893
4387
 
3894
4388
  // src/components/object-page/ObjectPageSkeleton.tsx
3895
- import { Box as Box11, Paper as Paper8, Skeleton as Skeleton4, Stack as Stack11 } from "@mui/material";
3896
- import { jsx as jsx22, jsxs as jsxs14 } from "react/jsx-runtime";
4389
+ import { Box as Box12, Paper as Paper8, Skeleton as Skeleton4, Stack as Stack11 } from "@mui/material";
4390
+ import { jsx as jsx23, jsxs as jsxs15 } from "react/jsx-runtime";
3897
4391
  function ObjectPageSkeleton() {
3898
- return /* @__PURE__ */ jsxs14(Stack11, { spacing: 1.5, sx: { height: "100%", minHeight: 0 }, children: [
3899
- /* @__PURE__ */ jsx22(MainHeaderSkeleton, { titleWidth: 420, subtitleWidth: "32%" }),
3900
- /* @__PURE__ */ jsxs14(
4392
+ return /* @__PURE__ */ jsxs15(Stack11, { spacing: 1.5, sx: { height: "100%", minHeight: 0 }, children: [
4393
+ /* @__PURE__ */ jsx23(MainHeaderSkeleton, { titleWidth: 420, subtitleWidth: "32%" }),
4394
+ /* @__PURE__ */ jsxs15(
3901
4395
  Stack11,
3902
4396
  {
3903
4397
  direction: { xs: "column", lg: "row" },
3904
4398
  spacing: 1.5,
3905
4399
  sx: { flex: 1, minHeight: 0, alignItems: "stretch" },
3906
4400
  children: [
3907
- /* @__PURE__ */ jsx22(Paper8, { sx: { borderRadius: "10px", flex: 1, minHeight: 0, overflow: "hidden" }, children: /* @__PURE__ */ jsx22(Box11, { sx: { height: "100%", overflow: "auto", p: 2.5 }, children: /* @__PURE__ */ jsx22(Stack11, { spacing: 1.5, children: Array.from({ length: 9 }).map((_, index) => /* @__PURE__ */ jsx22(Skeleton4, { variant: "rounded", width: "100%", height: 56 }, index)) }) }) }),
3908
- /* @__PURE__ */ jsx22(
4401
+ /* @__PURE__ */ jsx23(Paper8, { sx: { borderRadius: "10px", flex: 1, minHeight: 0, overflow: "hidden" }, children: /* @__PURE__ */ jsx23(Box12, { sx: { height: "100%", overflow: "auto", p: 2.5 }, children: /* @__PURE__ */ jsx23(Stack11, { spacing: 1.5, children: Array.from({ length: 9 }).map((_, index) => /* @__PURE__ */ jsx23(Skeleton4, { variant: "rounded", width: "100%", height: 56 }, index)) }) }) }),
4402
+ /* @__PURE__ */ jsx23(
3909
4403
  Paper8,
3910
4404
  {
3911
4405
  sx: {
@@ -3915,10 +4409,10 @@ function ObjectPageSkeleton() {
3915
4409
  p: 1.5,
3916
4410
  alignSelf: "flex-start"
3917
4411
  },
3918
- children: /* @__PURE__ */ jsxs14(Stack11, { spacing: 1, children: [
3919
- /* @__PURE__ */ jsx22(Skeleton4, { variant: "text", width: 90, height: 28 }),
3920
- /* @__PURE__ */ jsx22(Skeleton4, { variant: "rounded", width: "100%", height: 40 }),
3921
- /* @__PURE__ */ jsx22(Skeleton4, { variant: "rounded", width: "100%", height: 40 })
4412
+ children: /* @__PURE__ */ jsxs15(Stack11, { spacing: 1, children: [
4413
+ /* @__PURE__ */ jsx23(Skeleton4, { variant: "text", width: 90, height: 28 }),
4414
+ /* @__PURE__ */ jsx23(Skeleton4, { variant: "rounded", width: "100%", height: 40 }),
4415
+ /* @__PURE__ */ jsx23(Skeleton4, { variant: "rounded", width: "100%", height: 40 })
3922
4416
  ] })
3923
4417
  }
3924
4418
  )
@@ -3930,8 +4424,8 @@ function ObjectPageSkeleton() {
3930
4424
 
3931
4425
  // src/components/object-page/ReadonlyObjectField.tsx
3932
4426
  import { memo as memo7 } from "react";
3933
- import { Box as Box12, Stack as Stack12, TextField as TextField4 } from "@mui/material";
3934
- import { jsx as jsx23, jsxs as jsxs15 } from "react/jsx-runtime";
4427
+ import { Box as Box13, Stack as Stack12, TextField as TextField4 } from "@mui/material";
4428
+ import { jsx as jsx24, jsxs as jsxs16 } from "react/jsx-runtime";
3935
4429
  var ReadonlyObjectField = memo7(function ReadonlyObjectField2({
3936
4430
  field,
3937
4431
  value,
@@ -3939,9 +4433,9 @@ var ReadonlyObjectField = memo7(function ReadonlyObjectField2({
3939
4433
  }) {
3940
4434
  var _a;
3941
4435
  const isMultiline = field.input_kind === "textarea" || field.input_kind === "json" || field.type.toLowerCase().includes("text") || value.includes("\n") || value.length > 120;
3942
- return /* @__PURE__ */ jsxs15(Stack12, { spacing: 1, children: [
3943
- imageUrl ? /* @__PURE__ */ jsx23(
3944
- Box12,
4436
+ return /* @__PURE__ */ jsxs16(Stack12, { spacing: 1, children: [
4437
+ imageUrl ? /* @__PURE__ */ jsx24(
4438
+ Box13,
3945
4439
  {
3946
4440
  component: "img",
3947
4441
  src: imageUrl,
@@ -3957,7 +4451,7 @@ var ReadonlyObjectField = memo7(function ReadonlyObjectField2({
3957
4451
  }
3958
4452
  }
3959
4453
  ) : null,
3960
- /* @__PURE__ */ jsx23(
4454
+ /* @__PURE__ */ jsx24(
3961
4455
  TextField4,
3962
4456
  {
3963
4457
  label: field.label,
@@ -3974,7 +4468,7 @@ var ReadonlyObjectField = memo7(function ReadonlyObjectField2({
3974
4468
  });
3975
4469
 
3976
4470
  // src/components/object-page/useObjectPageController.ts
3977
- import { useCallback as useCallback7, useLayoutEffect as useLayoutEffect4, useMemo as useMemo10, useState as useState11 } from "react";
4471
+ import { useCallback as useCallback7, useLayoutEffect as useLayoutEffect4, useMemo as useMemo10, useState as useState12 } from "react";
3978
4472
 
3979
4473
  // src/utils/isDeepEqual.ts
3980
4474
  function isDeepEqual(left, right) {
@@ -4016,28 +4510,29 @@ function useObjectPageController({
4016
4510
  var _a, _b, _c;
4017
4511
  const message = useAdminMessage();
4018
4512
  const cacheKey = buildDetailCacheKey(slug, id);
4019
- const [data, setData] = useState11(() => {
4513
+ const [data, setData] = useState12(() => {
4020
4514
  var _a2;
4021
4515
  return (_a2 = getClientCacheBucket(client).detailResponseCache.get(cacheKey)) != null ? _a2 : null;
4022
4516
  });
4023
- const [values, setValues] = useState11(() => {
4517
+ const [values, setValues] = useState12(() => {
4024
4518
  var _a2, _b2;
4025
4519
  return (_b2 = (_a2 = getClientCacheBucket(client).detailResponseCache.get(cacheKey)) == null ? void 0 : _a2.item) != null ? _b2 : {};
4026
4520
  });
4027
- const [initialValues, setInitialValues] = useState11(() => {
4521
+ const [initialValues, setInitialValues] = useState12(() => {
4028
4522
  var _a2, _b2;
4029
4523
  return (_b2 = (_a2 = getClientCacheBucket(client).detailResponseCache.get(cacheKey)) == null ? void 0 : _a2.item) != null ? _b2 : {};
4030
4524
  });
4031
- const [error, setError] = useState11(null);
4032
- const [isLoading, setIsLoading] = useState11(data === null);
4033
- const [isSaving, setIsSaving] = useState11(false);
4034
- const [isDeleting, setIsDeleting] = useState11(false);
4035
- const [activeActionSlug, setActiveActionSlug] = useState11(null);
4036
- const [deleteConfirmOpen, setDeleteConfirmOpen] = useState11(false);
4037
- const [deletePreview, setDeletePreview] = useState11(null);
4038
- const [isDeletePreviewLoading, setIsDeletePreviewLoading] = useState11(false);
4039
- const [deletePreviewError, setDeletePreviewError] = useState11(null);
4040
- const [actionsAnchorEl, setActionsAnchorEl] = useState11(null);
4525
+ const [error, setError] = useState12(null);
4526
+ const [isLoading, setIsLoading] = useState12(data === null);
4527
+ const [isSaving, setIsSaving] = useState12(false);
4528
+ const [isDeleting, setIsDeleting] = useState12(false);
4529
+ const [activeActionSlug, setActiveActionSlug] = useState12(null);
4530
+ const [deleteConfirmOpen, setDeleteConfirmOpen] = useState12(false);
4531
+ const [deletePreview, setDeletePreview] = useState12(null);
4532
+ const [isDeletePreviewLoading, setIsDeletePreviewLoading] = useState12(false);
4533
+ const [deletePreviewError, setDeletePreviewError] = useState12(null);
4534
+ const [actionsAnchorEl, setActionsAnchorEl] = useState12(null);
4535
+ const [objectActionFormSlug, setObjectActionFormSlug] = useState12(null);
4041
4536
  useLayoutEffect4(() => {
4042
4537
  var _a2;
4043
4538
  let isMounted = true;
@@ -4108,6 +4603,13 @@ function useObjectPageController({
4108
4603
  [data, id, meta]
4109
4604
  );
4110
4605
  const isActionsMenuOpen = actionsAnchorEl !== null;
4606
+ const activeObjectAction = useMemo10(
4607
+ () => {
4608
+ var _a2;
4609
+ return (_a2 = objectActions.find((item) => item.slug === objectActionFormSlug)) != null ? _a2 : null;
4610
+ },
4611
+ [objectActionFormSlug, objectActions]
4612
+ );
4111
4613
  const currentPayload = useMemo10(
4112
4614
  () => buildAdminPayload(values, editableFields),
4113
4615
  [editableFields, values]
@@ -4171,7 +4673,13 @@ function useObjectPageController({
4171
4673
  router.push(listPath);
4172
4674
  }, [listPath, router]);
4173
4675
  const handleRunObjectAction = useCallback7(async (actionSlug) => {
4174
- var _a2, _b2;
4676
+ var _a2, _b2, _c2, _d;
4677
+ const action = objectActions.find((item) => item.slug === actionSlug);
4678
+ if (((_b2 = (_a2 = action == null ? void 0 : action.form) == null ? void 0 : _a2.length) != null ? _b2 : 0) > 0) {
4679
+ setActionsAnchorEl(null);
4680
+ setObjectActionFormSlug(actionSlug);
4681
+ return;
4682
+ }
4175
4683
  setActiveActionSlug(actionSlug);
4176
4684
  setError(null);
4177
4685
  try {
@@ -4184,7 +4692,7 @@ function useObjectPageController({
4184
4692
  setData(nextDetail);
4185
4693
  setValues(response.item);
4186
4694
  setInitialValues(response.item);
4187
- const actionLabel = (_b2 = (_a2 = objectActions.find((item) => item.slug === actionSlug)) == null ? void 0 : _a2.label) != null ? _b2 : actionSlug;
4695
+ const actionLabel = (_d = (_c2 = objectActions.find((item) => item.slug === actionSlug)) == null ? void 0 : _c2.label) != null ? _d : actionSlug;
4188
4696
  message.success(t("action_success", { action: actionLabel, count: 1 }));
4189
4697
  } catch (reason) {
4190
4698
  const nextError = reason instanceof Error ? reason.message : t("object_action_error");
@@ -4194,6 +4702,33 @@ function useObjectPageController({
4194
4702
  setActiveActionSlug(null);
4195
4703
  }
4196
4704
  }, [cacheKey, client, data, id, message, objectActions, slug, t]);
4705
+ const handleSubmitObjectActionForm = useCallback7(async (payload) => {
4706
+ var _a2, _b2;
4707
+ if (!objectActionFormSlug) {
4708
+ return;
4709
+ }
4710
+ setActiveActionSlug(objectActionFormSlug);
4711
+ setError(null);
4712
+ try {
4713
+ const response = await client.runObjectAction(slug, id, objectActionFormSlug, payload);
4714
+ const nextDetail = data ? { ...data, item: response.item } : null;
4715
+ if (nextDetail) {
4716
+ invalidateModelCache(client, slug);
4717
+ setCachedDetailResponse(client, cacheKey, nextDetail);
4718
+ }
4719
+ setData(nextDetail);
4720
+ setValues(response.item);
4721
+ setInitialValues(response.item);
4722
+ const actionLabel = (_b2 = (_a2 = objectActions.find((item) => item.slug === objectActionFormSlug)) == null ? void 0 : _a2.label) != null ? _b2 : objectActionFormSlug;
4723
+ message.success(t("action_success", { action: actionLabel, count: 1 }));
4724
+ setObjectActionFormSlug(null);
4725
+ } finally {
4726
+ setActiveActionSlug(null);
4727
+ }
4728
+ }, [cacheKey, client, data, id, message, objectActionFormSlug, objectActions, slug, t]);
4729
+ const handleCloseObjectActionForm = useCallback7(() => {
4730
+ setObjectActionFormSlug(null);
4731
+ }, []);
4197
4732
  const handleOpenDeletePreview = useCallback7(async () => {
4198
4733
  setActionsAnchorEl(null);
4199
4734
  setDeleteConfirmOpen(true);
@@ -4212,6 +4747,7 @@ function useObjectPageController({
4212
4747
  return {
4213
4748
  actionsAnchorEl,
4214
4749
  activeActionSlug,
4750
+ activeObjectAction,
4215
4751
  data,
4216
4752
  deleteConfirmOpen,
4217
4753
  deletePreview,
@@ -4226,6 +4762,8 @@ function useObjectPageController({
4226
4762
  handleOpenDeletePreview,
4227
4763
  handleRunObjectAction,
4228
4764
  handleSave,
4765
+ handleCloseObjectActionForm,
4766
+ handleSubmitObjectActionForm,
4229
4767
  initialValues,
4230
4768
  isActionsMenuOpen,
4231
4769
  isDeletePreviewLoading,
@@ -4245,9 +4783,9 @@ function useObjectPageController({
4245
4783
  }
4246
4784
 
4247
4785
  // src/components/ObjectPage.tsx
4248
- import { jsx as jsx24, jsxs as jsxs16 } from "react/jsx-runtime";
4786
+ import { jsx as jsx25, jsxs as jsxs17 } from "react/jsx-runtime";
4249
4787
  function ObjectPage({ client, slug, id, router }) {
4250
- var _a, _b;
4788
+ var _a, _b, _c;
4251
4789
  const locale = useAdminLocale();
4252
4790
  const t = useAdminTranslation();
4253
4791
  const resolvedRouter = useAdminRouter(router);
@@ -4282,223 +4820,251 @@ function ObjectPage({ client, slug, id, router }) {
4282
4820
  }, [controller.error, controller.isLoading, controller.meta, finishPendingNavigation, pathname, pendingPath, slug]);
4283
4821
  useAdminDocumentTitle(t("admin_title"), (_b = (_a = controller.meta) == null ? void 0 : _a.title) != null ? _b : slug, controller.objectTitle);
4284
4822
  if (controller.isLoading && !controller.data) {
4285
- return /* @__PURE__ */ jsx24(ObjectPageSkeleton, {});
4823
+ return /* @__PURE__ */ jsx25(ObjectPageSkeleton, {});
4286
4824
  }
4287
4825
  if (controller.error && !controller.data) {
4288
- return /* @__PURE__ */ jsx24(Alert6, { severity: "error", children: controller.error });
4826
+ return /* @__PURE__ */ jsx25(Alert7, { severity: "error", children: controller.error });
4289
4827
  }
4290
4828
  if (!controller.data || !controller.meta) {
4291
- return /* @__PURE__ */ jsx24(ObjectPageSkeleton, {});
4829
+ return /* @__PURE__ */ jsx25(ObjectPageSkeleton, {});
4292
4830
  }
4293
- return /* @__PURE__ */ jsx24(AdminRouterProvider, { router: resolvedRouter, children: /* @__PURE__ */ jsxs16(LocalizationProvider2, { dateAdapter: AdapterDayjs2, adapterLocale: locale, children: [
4294
- /* @__PURE__ */ jsxs16(Stack13, { spacing: 1.5, sx: { height: "100%", minHeight: 0 }, children: [
4295
- /* @__PURE__ */ jsx24(
4296
- MainHeader,
4297
- {
4298
- title: controller.objectTitle,
4299
- subtitle: controller.meta.slug,
4300
- beforeSubtitle: /* @__PURE__ */ jsx24(
4301
- IconButton4,
4831
+ return /* @__PURE__ */ jsx25(AdminRouterProvider, { router: resolvedRouter, children: /* @__PURE__ */ jsxs17(
4832
+ LocalizationProvider3,
4833
+ {
4834
+ dateAdapter: AdapterDayjs3,
4835
+ adapterLocale: locale,
4836
+ localeText: getMuiPickersLocaleText(locale),
4837
+ children: [
4838
+ /* @__PURE__ */ jsxs17(Stack13, { spacing: 1.5, sx: { height: "100%", minHeight: 0 }, children: [
4839
+ /* @__PURE__ */ jsx25(
4840
+ MainHeader,
4302
4841
  {
4303
- "aria-label": t("back"),
4304
- onClick: controller.handleNavigateBack,
4305
- size: "small",
4306
- sx: { ml: -0.5 },
4307
- children: /* @__PURE__ */ jsx24(ArrowBackIcon, { fontSize: "small" })
4842
+ title: controller.objectTitle,
4843
+ subtitle: controller.meta.slug,
4844
+ beforeSubtitle: /* @__PURE__ */ jsx25(
4845
+ IconButton4,
4846
+ {
4847
+ "aria-label": t("back"),
4848
+ onClick: controller.handleNavigateBack,
4849
+ size: "small",
4850
+ sx: { ml: -0.5 },
4851
+ children: /* @__PURE__ */ jsx25(ArrowBackIcon, { fontSize: "small" })
4852
+ }
4853
+ ),
4854
+ actions: isPhone ? /* @__PURE__ */ jsx25(
4855
+ IconButton4,
4856
+ {
4857
+ "aria-label": t("actions"),
4858
+ onClick: (event) => controller.setActionsAnchorEl(event.currentTarget),
4859
+ size: "small",
4860
+ sx: { mr: -0.5 },
4861
+ children: /* @__PURE__ */ jsx25(MoreVertIcon2, { fontSize: "small" })
4862
+ }
4863
+ ) : void 0,
4864
+ details: controller.meta.description ? /* @__PURE__ */ jsx25(Typography7, { color: "text.secondary", sx: { fontSize: 14, lineHeight: 1.45 }, children: controller.meta.description }) : void 0,
4865
+ error: controller.error
4308
4866
  }
4309
4867
  ),
4310
- actions: isPhone ? /* @__PURE__ */ jsx24(
4311
- IconButton4,
4868
+ /* @__PURE__ */ jsxs17(
4869
+ Stack13,
4312
4870
  {
4313
- "aria-label": t("actions"),
4314
- onClick: (event) => controller.setActionsAnchorEl(event.currentTarget),
4315
- size: "small",
4316
- sx: { mr: -0.5 },
4317
- children: /* @__PURE__ */ jsx24(MoreVertIcon2, { fontSize: "small" })
4318
- }
4319
- ) : void 0,
4320
- details: controller.meta.description ? /* @__PURE__ */ jsx24(Typography7, { color: "text.secondary", sx: { fontSize: 14, lineHeight: 1.45 }, children: controller.meta.description }) : void 0,
4321
- error: controller.error
4322
- }
4323
- ),
4324
- /* @__PURE__ */ jsxs16(
4325
- Stack13,
4326
- {
4327
- direction: { xs: "column", lg: "row" },
4328
- spacing: 1.5,
4329
- sx: { flex: 1, minHeight: 0, alignItems: "stretch" },
4330
- children: [
4331
- /* @__PURE__ */ jsx24(
4332
- Paper9,
4333
- {
4334
- sx: {
4335
- borderRadius: "10px",
4336
- flex: 1,
4337
- minHeight: 0,
4338
- overflow: "hidden"
4339
- },
4340
- children: /* @__PURE__ */ jsx24(Box13, { component: "form", autoComplete: "off", sx: { height: "100%", overflow: "auto", p: 2.5 }, children: /* @__PURE__ */ jsx24(Stack13, { spacing: 1.5, children: controller.detailFields.map((fieldName) => {
4341
- const field = controller.fieldMap.get(fieldName);
4342
- if (!field) {
4343
- return null;
4344
- }
4345
- if (controller.editableFieldNames.has(fieldName)) {
4346
- return /* @__PURE__ */ jsx24(
4347
- ObjectField,
4348
- {
4349
- field,
4350
- value: controller.values[field.name],
4351
- slug,
4352
- client,
4353
- onFieldChange: controller.handleFieldChange
4354
- },
4355
- field.name
4356
- );
4871
+ direction: { xs: "column", lg: "row" },
4872
+ spacing: 1.5,
4873
+ sx: { flex: 1, minHeight: 0, alignItems: "stretch" },
4874
+ children: [
4875
+ /* @__PURE__ */ jsx25(
4876
+ Paper9,
4877
+ {
4878
+ sx: {
4879
+ borderRadius: "10px",
4880
+ flex: 1,
4881
+ minHeight: 0,
4882
+ overflow: "hidden"
4883
+ },
4884
+ children: /* @__PURE__ */ jsx25(Box14, { component: "form", autoComplete: "off", sx: { height: "100%", overflow: "auto", p: 2.5 }, children: /* @__PURE__ */ jsx25(Stack13, { spacing: 1.5, children: controller.detailFields.map((fieldName) => {
4885
+ const field = controller.fieldMap.get(fieldName);
4886
+ if (!field) {
4887
+ return null;
4888
+ }
4889
+ if (controller.editableFieldNames.has(fieldName)) {
4890
+ return /* @__PURE__ */ jsx25(
4891
+ ObjectField,
4892
+ {
4893
+ field,
4894
+ value: controller.values[field.name],
4895
+ slug,
4896
+ client,
4897
+ onFieldChange: controller.handleFieldChange
4898
+ },
4899
+ field.name
4900
+ );
4901
+ }
4902
+ return /* @__PURE__ */ jsx25(
4903
+ ReadonlyObjectField,
4904
+ {
4905
+ field,
4906
+ value: formatAdminValue(controller.values[field.name], {
4907
+ locale,
4908
+ field,
4909
+ pretty: true
4910
+ }),
4911
+ imageUrl: field.display_kind === "image" ? resolveAdminMediaUrl(controller.values[field.name], field) : null
4912
+ },
4913
+ field.name
4914
+ );
4915
+ }) }) })
4357
4916
  }
4358
- return /* @__PURE__ */ jsx24(
4359
- ReadonlyObjectField,
4360
- {
4361
- field,
4362
- value: formatAdminValue(controller.values[field.name], {
4363
- locale,
4364
- field,
4365
- pretty: true
4366
- }),
4367
- imageUrl: field.display_kind === "image" ? resolveAdminMediaUrl(controller.values[field.name], field) : null
4917
+ ),
4918
+ /* @__PURE__ */ jsx25(
4919
+ Paper9,
4920
+ {
4921
+ sx: {
4922
+ width: { xs: "100%", lg: 280 },
4923
+ flexShrink: 0,
4924
+ borderRadius: "10px",
4925
+ p: 1.5,
4926
+ alignSelf: "flex-start",
4927
+ position: { lg: "sticky" },
4928
+ top: { lg: 0 },
4929
+ display: isPhone ? "none" : void 0
4368
4930
  },
4369
- field.name
4370
- );
4371
- }) }) })
4372
- }
4373
- ),
4374
- /* @__PURE__ */ jsx24(
4375
- Paper9,
4376
- {
4931
+ children: /* @__PURE__ */ jsxs17(Stack13, { spacing: 1, children: [
4932
+ /* @__PURE__ */ jsx25(Typography7, { variant: "subtitle2", color: "text.secondary", children: t("actions") }),
4933
+ controller.isDirty ? /* @__PURE__ */ jsx25(
4934
+ Button6,
4935
+ {
4936
+ variant: "contained",
4937
+ onClick: () => void controller.handleSave(),
4938
+ disabled: controller.isSaving,
4939
+ children: controller.isSaving ? t("saving") : t("save")
4940
+ }
4941
+ ) : null,
4942
+ /* @__PURE__ */ jsx25(
4943
+ Button6,
4944
+ {
4945
+ variant: "outlined",
4946
+ color: "error",
4947
+ onClick: () => void controller.handleOpenDeletePreview(),
4948
+ disabled: controller.isDeleting,
4949
+ children: t("delete")
4950
+ }
4951
+ ),
4952
+ controller.objectActions.map((action) => /* @__PURE__ */ jsx25(
4953
+ Button6,
4954
+ {
4955
+ variant: "outlined",
4956
+ onClick: () => void controller.handleRunObjectAction(action.slug),
4957
+ disabled: controller.activeActionSlug !== null,
4958
+ children: controller.activeActionSlug === action.slug ? t("executing") : action.label
4959
+ },
4960
+ action.slug
4961
+ ))
4962
+ ] })
4963
+ }
4964
+ )
4965
+ ]
4966
+ }
4967
+ )
4968
+ ] }),
4969
+ /* @__PURE__ */ jsxs17(
4970
+ Menu2,
4971
+ {
4972
+ anchorEl: controller.actionsAnchorEl,
4973
+ open: controller.isActionsMenuOpen,
4974
+ onClose: () => controller.setActionsAnchorEl(null),
4975
+ slotProps: {
4976
+ paper: {
4377
4977
  sx: {
4378
- width: { xs: "100%", lg: 280 },
4379
- flexShrink: 0,
4380
- borderRadius: "10px",
4381
- p: 1.5,
4382
- alignSelf: "flex-start",
4383
- position: { lg: "sticky" },
4384
- top: { lg: 0 },
4385
- display: isPhone ? "none" : void 0
4978
+ minWidth: 220
4979
+ }
4980
+ }
4981
+ },
4982
+ anchorOrigin: { vertical: "bottom", horizontal: "right" },
4983
+ transformOrigin: { vertical: "top", horizontal: "right" },
4984
+ children: [
4985
+ controller.isDirty ? /* @__PURE__ */ jsx25(
4986
+ MenuItem4,
4987
+ {
4988
+ onClick: () => {
4989
+ controller.setActionsAnchorEl(null);
4990
+ void controller.handleSave();
4991
+ },
4992
+ disabled: controller.isSaving,
4993
+ children: controller.isSaving ? t("saving") : t("save")
4994
+ }
4995
+ ) : null,
4996
+ /* @__PURE__ */ jsx25(
4997
+ MenuItem4,
4998
+ {
4999
+ onClick: () => void controller.handleOpenDeletePreview(),
5000
+ disabled: controller.isDeleting,
5001
+ sx: { color: "error.main" },
5002
+ children: t("delete")
5003
+ }
5004
+ ),
5005
+ controller.objectActions.map((action) => /* @__PURE__ */ jsx25(
5006
+ MenuItem4,
5007
+ {
5008
+ onClick: () => {
5009
+ controller.setActionsAnchorEl(null);
5010
+ void controller.handleRunObjectAction(action.slug);
5011
+ },
5012
+ disabled: controller.activeActionSlug !== null,
5013
+ children: controller.activeActionSlug === action.slug ? t("executing") : action.label
4386
5014
  },
4387
- children: /* @__PURE__ */ jsxs16(Stack13, { spacing: 1, children: [
4388
- /* @__PURE__ */ jsx24(Typography7, { variant: "subtitle2", color: "text.secondary", children: t("actions") }),
4389
- controller.isDirty ? /* @__PURE__ */ jsx24(
4390
- Button5,
4391
- {
4392
- variant: "contained",
4393
- onClick: () => void controller.handleSave(),
4394
- disabled: controller.isSaving,
4395
- children: controller.isSaving ? t("saving") : t("save")
4396
- }
4397
- ) : null,
4398
- /* @__PURE__ */ jsx24(
4399
- Button5,
4400
- {
4401
- variant: "outlined",
4402
- color: "error",
4403
- onClick: () => void controller.handleOpenDeletePreview(),
4404
- disabled: controller.isDeleting,
4405
- children: t("delete")
4406
- }
4407
- ),
4408
- controller.objectActions.map((action) => /* @__PURE__ */ jsx24(
4409
- Button5,
4410
- {
4411
- variant: "outlined",
4412
- onClick: () => void controller.handleRunObjectAction(action.slug),
4413
- disabled: controller.activeActionSlug !== null,
4414
- children: controller.activeActionSlug === action.slug ? t("executing") : action.label
4415
- },
4416
- action.slug
4417
- ))
4418
- ] })
5015
+ action.slug
5016
+ ))
5017
+ ]
5018
+ }
5019
+ ),
5020
+ /* @__PURE__ */ jsx25(
5021
+ DeletePreviewDialog,
5022
+ {
5023
+ open: controller.deleteConfirmOpen,
5024
+ title: t("delete_object_title"),
5025
+ preview: controller.deletePreview,
5026
+ error: controller.deletePreviewError,
5027
+ isLoading: controller.isDeletePreviewLoading,
5028
+ isSubmitting: controller.isDeleting,
5029
+ onClose: () => {
5030
+ if (controller.isDeleting) {
5031
+ return;
4419
5032
  }
4420
- )
4421
- ]
4422
- }
4423
- )
4424
- ] }),
4425
- /* @__PURE__ */ jsxs16(
4426
- Menu2,
4427
- {
4428
- anchorEl: controller.actionsAnchorEl,
4429
- open: controller.isActionsMenuOpen,
4430
- onClose: () => controller.setActionsAnchorEl(null),
4431
- slotProps: {
4432
- paper: {
4433
- sx: {
4434
- minWidth: 220
4435
- }
5033
+ controller.setDeleteConfirmOpen(false);
5034
+ controller.setDeletePreview(null);
5035
+ controller.setDeletePreviewError(null);
5036
+ },
5037
+ onConfirm: () => void controller.handleDelete()
4436
5038
  }
4437
- },
4438
- anchorOrigin: { vertical: "bottom", horizontal: "right" },
4439
- transformOrigin: { vertical: "top", horizontal: "right" },
4440
- children: [
4441
- controller.isDirty ? /* @__PURE__ */ jsx24(
4442
- MenuItem3,
4443
- {
4444
- onClick: () => {
4445
- controller.setActionsAnchorEl(null);
4446
- void controller.handleSave();
4447
- },
4448
- disabled: controller.isSaving,
4449
- children: controller.isSaving ? t("saving") : t("save")
4450
- }
4451
- ) : null,
4452
- /* @__PURE__ */ jsx24(
4453
- MenuItem3,
4454
- {
4455
- onClick: () => void controller.handleOpenDeletePreview(),
4456
- disabled: controller.isDeleting,
4457
- sx: { color: "error.main" },
4458
- children: t("delete")
4459
- }
4460
- ),
4461
- controller.objectActions.map((action) => /* @__PURE__ */ jsx24(
4462
- MenuItem3,
4463
- {
4464
- onClick: () => {
4465
- controller.setActionsAnchorEl(null);
4466
- void controller.handleRunObjectAction(action.slug);
4467
- },
4468
- disabled: controller.activeActionSlug !== null,
4469
- children: controller.activeActionSlug === action.slug ? t("executing") : action.label
5039
+ ),
5040
+ ((_c = controller.activeObjectAction) == null ? void 0 : _c.form) ? /* @__PURE__ */ jsx25(
5041
+ ActionFormDialog,
5042
+ {
5043
+ open: true,
5044
+ onClose: controller.handleCloseObjectActionForm,
5045
+ onSuccess: () => void 0,
5046
+ title: `${controller.activeObjectAction.label}: ${controller.objectTitle}`,
5047
+ submitLabel: controller.activeObjectAction.label,
5048
+ slug,
5049
+ locale,
5050
+ fields: controller.activeObjectAction.form,
5051
+ client,
5052
+ choiceScope: {
5053
+ kind: "object-action",
5054
+ actionSlug: controller.activeObjectAction.slug,
5055
+ itemId: id
4470
5056
  },
4471
- action.slug
4472
- ))
4473
- ]
4474
- }
4475
- ),
4476
- /* @__PURE__ */ jsx24(
4477
- DeletePreviewDialog,
4478
- {
4479
- open: controller.deleteConfirmOpen,
4480
- title: t("delete_object_title"),
4481
- preview: controller.deletePreview,
4482
- error: controller.deletePreviewError,
4483
- isLoading: controller.isDeletePreviewLoading,
4484
- isSubmitting: controller.isDeleting,
4485
- onClose: () => {
4486
- if (controller.isDeleting) {
4487
- return;
5057
+ onSubmit: controller.handleSubmitObjectActionForm
4488
5058
  }
4489
- controller.setDeleteConfirmOpen(false);
4490
- controller.setDeletePreview(null);
4491
- controller.setDeletePreviewError(null);
4492
- },
4493
- onConfirm: () => void controller.handleDelete()
4494
- }
4495
- )
4496
- ] }) });
5059
+ ) : null
5060
+ ]
5061
+ }
5062
+ ) });
4497
5063
  }
4498
5064
 
4499
5065
  // src/components/Shell.tsx
4500
- import { useEffect as useEffect11, useMemo as useMemo11, useState as useState12 } from "react";
4501
- import { Box as Box16, CssBaseline, Drawer, GlobalStyles, Stack as Stack14, useMediaQuery as useMediaQuery4 } from "@mui/material";
5066
+ import { useEffect as useEffect14, useMemo as useMemo11, useState as useState13 } from "react";
5067
+ import { Box as Box17, CssBaseline, Drawer, GlobalStyles, Stack as Stack14, useMediaQuery as useMediaQuery4 } from "@mui/material";
4502
5068
  import { ThemeProvider } from "@mui/material/styles";
4503
5069
 
4504
5070
  // src/theme/defaultAdminTheme.ts
@@ -4629,14 +5195,14 @@ var defaultAdminTheme = createTheme({
4629
5195
  });
4630
5196
 
4631
5197
  // src/components/layout/Main.tsx
4632
- import { Box as Box14 } from "@mui/material";
4633
- import { jsx as jsx25, jsxs as jsxs17 } from "react/jsx-runtime";
5198
+ import { Box as Box15 } from "@mui/material";
5199
+ import { jsx as jsx26, jsxs as jsxs18 } from "react/jsx-runtime";
4634
5200
  function Main({ children }) {
4635
5201
  useAdminLocation();
4636
5202
  const { pendingPath, pendingView } = useShellContext();
4637
5203
  const isPendingNavigation = pendingPath !== null;
4638
- return /* @__PURE__ */ jsxs17(
4639
- Box14,
5204
+ return /* @__PURE__ */ jsxs18(
5205
+ Box15,
4640
5206
  {
4641
5207
  sx: {
4642
5208
  flex: 1,
@@ -4649,8 +5215,8 @@ function Main({ children }) {
4649
5215
  },
4650
5216
  children: [
4651
5217
  children,
4652
- isPendingNavigation ? /* @__PURE__ */ jsx25(
4653
- Box14,
5218
+ isPendingNavigation ? /* @__PURE__ */ jsx26(
5219
+ Box15,
4654
5220
  {
4655
5221
  sx: {
4656
5222
  position: "absolute",
@@ -4658,7 +5224,7 @@ function Main({ children }) {
4658
5224
  zIndex: 5,
4659
5225
  backgroundColor: "background.default"
4660
5226
  },
4661
- children: pendingView === "model" || pendingView === "overview" ? /* @__PURE__ */ jsx25(ModelPageSkeleton, {}) : /* @__PURE__ */ jsx25(ModelPageSkeleton, {})
5227
+ children: pendingView === "model" || pendingView === "overview" ? /* @__PURE__ */ jsx26(ModelPageSkeleton, {}) : /* @__PURE__ */ jsx26(ModelPageSkeleton, {})
4662
5228
  }
4663
5229
  ) : null
4664
5230
  ]
@@ -4667,14 +5233,24 @@ function Main({ children }) {
4667
5233
  }
4668
5234
 
4669
5235
  // src/components/layout/Sidebar.tsx
4670
- import { memo as memo8 } from "react";
4671
- import { Box as Box15, ListItemButton as ListItemButton3, Typography as Typography8 } from "@mui/material";
4672
- import { jsx as jsx26, jsxs as jsxs18 } from "react/jsx-runtime";
5236
+ import { memo as memo8, useEffect as useEffect13, useRef as useRef7 } from "react";
5237
+ import { Box as Box16, ListItemButton as ListItemButton3, Typography as Typography8 } from "@mui/material";
5238
+ import { jsx as jsx27, jsxs as jsxs19 } from "react/jsx-runtime";
5239
+ function getOffsetTopWithinContainer(element, container) {
5240
+ let offsetTop = element.offsetTop;
5241
+ let currentParent = element.offsetParent;
5242
+ while (currentParent instanceof HTMLElement && currentParent !== container) {
5243
+ offsetTop += currentParent.offsetTop;
5244
+ currentParent = currentParent.offsetParent;
5245
+ }
5246
+ return offsetTop;
5247
+ }
4673
5248
  var Sidebar = memo8(function Sidebar2({ models, blocks, basePath }) {
4674
5249
  var _a;
4675
5250
  const t = useAdminTranslation();
4676
5251
  const { pathname } = useAdminLocation();
4677
5252
  const { pendingPath, startPendingNavigation } = useShellContext();
5253
+ const scrollContainerRef = useRef7(null);
4678
5254
  const effectivePathname = pendingPath != null ? pendingPath : pathname;
4679
5255
  const normalizedBasePath = basePath.endsWith("/") ? basePath.slice(0, -1) : basePath;
4680
5256
  const fallbackBasePath = normalizedBasePath.replace(/^\/(ru|en)(?=\/|$)/, "") || "/";
@@ -4682,9 +5258,80 @@ var Sidebar = memo8(function Sidebar2({ models, blocks, basePath }) {
4682
5258
  const relativePath = matchedBasePath ? effectivePathname.slice(matchedBasePath.length) : "";
4683
5259
  const activeModelSlug = (_a = relativePath.split("/").filter(Boolean)[0]) != null ? _a : null;
4684
5260
  const isOverviewActive = matchedBasePath !== null && (effectivePathname === matchedBasePath || effectivePathname === `${matchedBasePath}/`);
4685
- return /* @__PURE__ */ jsx26(Box15, { sx: { height: "100%", overflow: "hidden" }, children: /* @__PURE__ */ jsx26(
4686
- Box15,
5261
+ useEffect13(() => {
5262
+ if (!activeModelSlug) {
5263
+ return;
5264
+ }
5265
+ const container = scrollContainerRef.current;
5266
+ if (!container) {
5267
+ return;
5268
+ }
5269
+ let scheduledFrame = null;
5270
+ let cancelled = false;
5271
+ let startedAt = 0;
5272
+ let lastTargetScrollTop = null;
5273
+ let stableFrames = 0;
5274
+ const ensureActiveModelVisible = (timestamp) => {
5275
+ if (cancelled) {
5276
+ return;
5277
+ }
5278
+ if (startedAt === 0) {
5279
+ startedAt = timestamp;
5280
+ }
5281
+ const elapsed = timestamp - startedAt;
5282
+ const allowAllModelsFallback = elapsed >= 250;
5283
+ const blockContainer = container.querySelector(
5284
+ '[data-xladmin-active-block="true"][data-xladmin-block-origin="block"]'
5285
+ );
5286
+ const fallbackBlockContainer = container.querySelector(
5287
+ '[data-xladmin-active-block="true"][data-xladmin-block-origin="all-models"]'
5288
+ );
5289
+ const blockItem = container.querySelector(
5290
+ '[data-xladmin-active-model="true"][data-xladmin-model-origin="block"]'
5291
+ );
5292
+ const fallbackItem = container.querySelector(
5293
+ '[data-xladmin-active-model="true"][data-xladmin-model-origin="all-models"]'
5294
+ );
5295
+ const activeBlock = blockContainer != null ? blockContainer : allowAllModelsFallback ? fallbackBlockContainer : null;
5296
+ const activeItem = blockItem != null ? blockItem : allowAllModelsFallback ? fallbackItem : null;
5297
+ if (!activeBlock || !activeItem) {
5298
+ if (elapsed < 1200) {
5299
+ scheduledFrame = window.requestAnimationFrame(ensureActiveModelVisible);
5300
+ }
5301
+ return;
5302
+ }
5303
+ const rangeTop = getOffsetTopWithinContainer(activeBlock, container);
5304
+ const rangeBottom = getOffsetTopWithinContainer(activeItem, container) + activeItem.offsetHeight;
5305
+ const rangeCenter = (rangeTop + rangeBottom) / 2;
5306
+ const maxScrollTop = Math.max(0, container.scrollHeight - container.clientHeight);
5307
+ const targetScrollTop = Math.min(
5308
+ maxScrollTop,
5309
+ Math.max(0, rangeCenter - container.clientHeight / 2)
5310
+ );
5311
+ container.scrollTop = targetScrollTop;
5312
+ if (lastTargetScrollTop !== null && Math.abs(lastTargetScrollTop - targetScrollTop) < 1) {
5313
+ stableFrames += 1;
5314
+ } else {
5315
+ stableFrames = 0;
5316
+ }
5317
+ lastTargetScrollTop = targetScrollTop;
5318
+ if (stableFrames >= 3 || elapsed >= 1200) {
5319
+ return;
5320
+ }
5321
+ scheduledFrame = window.requestAnimationFrame(ensureActiveModelVisible);
5322
+ };
5323
+ scheduledFrame = window.requestAnimationFrame(ensureActiveModelVisible);
5324
+ return () => {
5325
+ cancelled = true;
5326
+ if (scheduledFrame !== null) {
5327
+ window.cancelAnimationFrame(scheduledFrame);
5328
+ }
5329
+ };
5330
+ }, [activeModelSlug, blocks]);
5331
+ return /* @__PURE__ */ jsx27(Box16, { sx: { height: "100%", overflow: "hidden" }, children: /* @__PURE__ */ jsx27(
5332
+ Box16,
4687
5333
  {
5334
+ ref: scrollContainerRef,
4688
5335
  sx: {
4689
5336
  height: "100%",
4690
5337
  overflowY: "scroll",
@@ -4694,14 +5341,14 @@ var Sidebar = memo8(function Sidebar2({ models, blocks, basePath }) {
4694
5341
  ml: 0,
4695
5342
  pl: 0
4696
5343
  },
4697
- children: /* @__PURE__ */ jsxs18(Box15, { sx: { direction: "ltr", pl: 1 }, children: [
4698
- /* @__PURE__ */ jsx26(
5344
+ children: /* @__PURE__ */ jsxs19(Box16, { sx: { direction: "ltr", pl: 1 }, children: [
5345
+ /* @__PURE__ */ jsx27(
4699
5346
  NavLink,
4700
5347
  {
4701
5348
  href: basePath,
4702
5349
  style: { textDecoration: "none", display: "block" },
4703
5350
  onClick: () => startPendingNavigation(basePath, "overview"),
4704
- children: /* @__PURE__ */ jsx26(
5351
+ children: /* @__PURE__ */ jsx27(
4705
5352
  ListItemButton3,
4706
5353
  {
4707
5354
  selected: isOverviewActive,
@@ -4714,12 +5361,12 @@ var Sidebar = memo8(function Sidebar2({ models, blocks, basePath }) {
4714
5361
  backgroundColor: isOverviewActive ? "rgba(255, 255, 255, 0.2)" : "rgba(255, 255, 255, 0.055)"
4715
5362
  }
4716
5363
  },
4717
- children: /* @__PURE__ */ jsx26(Typography8, { variant: "subtitle1", sx: { fontWeight: 700 }, children: t("overview") })
5364
+ children: /* @__PURE__ */ jsx27(Typography8, { variant: "subtitle1", sx: { fontWeight: 700 }, children: t("overview") })
4718
5365
  }
4719
5366
  )
4720
5367
  }
4721
5368
  ),
4722
- /* @__PURE__ */ jsx26(
5369
+ /* @__PURE__ */ jsx27(
4723
5370
  ModelsBlocks,
4724
5371
  {
4725
5372
  models,
@@ -4736,7 +5383,7 @@ var Sidebar = memo8(function Sidebar2({ models, blocks, basePath }) {
4736
5383
  });
4737
5384
 
4738
5385
  // src/components/Shell.tsx
4739
- import { jsx as jsx27, jsxs as jsxs19 } from "react/jsx-runtime";
5386
+ import { jsx as jsx28, jsxs as jsxs20 } from "react/jsx-runtime";
4740
5387
  function normalizeAdminPath(path) {
4741
5388
  const normalizedPath = path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
4742
5389
  return normalizedPath.replace(/^\/(ru|en)(?=\/|$)/, "") || "/";
@@ -4748,15 +5395,15 @@ function Shell({ client, models, blocks, basePath, locale, children, theme, rout
4748
5395
  const location = useAdminLocation(resolvedRouter);
4749
5396
  const pathname = location.pathname;
4750
5397
  const isDesktopSidebar = useMediaQuery4(activeTheme.breakpoints.up("lg"));
4751
- const [isMobileSidebarOpen, setIsMobileSidebarOpen] = useState12(false);
4752
- const [pendingPath, setPendingPath] = useState12(null);
4753
- const [pendingView, setPendingView] = useState12(null);
4754
- useEffect11(() => {
5398
+ const [isMobileSidebarOpen, setIsMobileSidebarOpen] = useState13(false);
5399
+ const [pendingPath, setPendingPath] = useState13(null);
5400
+ const [pendingView, setPendingView] = useState13(null);
5401
+ useEffect14(() => {
4755
5402
  if (isDesktopSidebar) {
4756
5403
  setIsMobileSidebarOpen(false);
4757
5404
  }
4758
5405
  }, [isDesktopSidebar]);
4759
- useEffect11(() => {
5406
+ useEffect14(() => {
4760
5407
  setIsMobileSidebarOpen(false);
4761
5408
  }, [pathname]);
4762
5409
  const shellContextValue = useMemo11(() => ({
@@ -4782,9 +5429,9 @@ function Shell({ client, models, blocks, basePath, locale, children, theme, rout
4782
5429
  setPendingView(null);
4783
5430
  }
4784
5431
  }), [isDesktopSidebar, pathname, pendingPath, pendingView]);
4785
- return /* @__PURE__ */ jsx27(AdminRouterProvider, { router: resolvedRouter, children: /* @__PURE__ */ jsx27(ThemeProvider, { theme: activeTheme, children: /* @__PURE__ */ jsx27(AdminLocaleProvider, { locale, children: /* @__PURE__ */ jsx27(AdminDataProvider, { value: { locale: locale === "en" ? "en" : "ru", models, blocks }, children: /* @__PURE__ */ jsx27(ShellContextProvider, { value: shellContextValue, children: /* @__PURE__ */ jsxs19(AdminMessageProvider, { children: [
4786
- /* @__PURE__ */ jsx27(CssBaseline, {}),
4787
- /* @__PURE__ */ jsx27(
5432
+ return /* @__PURE__ */ jsx28(AdminRouterProvider, { router: resolvedRouter, children: /* @__PURE__ */ jsx28(ThemeProvider, { theme: activeTheme, children: /* @__PURE__ */ jsx28(AdminLocaleProvider, { locale, children: /* @__PURE__ */ jsx28(AdminDataProvider, { value: { locale: locale === "en" ? "en" : "ru", models, blocks }, children: /* @__PURE__ */ jsx28(ShellContextProvider, { value: shellContextValue, children: /* @__PURE__ */ jsxs20(AdminMessageProvider, { children: [
5433
+ /* @__PURE__ */ jsx28(CssBaseline, {}),
5434
+ /* @__PURE__ */ jsx28(
4788
5435
  GlobalStyles,
4789
5436
  {
4790
5437
  styles: (muiTheme) => ({
@@ -4823,8 +5470,8 @@ function Shell({ client, models, blocks, basePath, locale, children, theme, rout
4823
5470
  })
4824
5471
  }
4825
5472
  ),
4826
- /* @__PURE__ */ jsx27(
4827
- Box16,
5473
+ /* @__PURE__ */ jsx28(
5474
+ Box17,
4828
5475
  {
4829
5476
  "data-xladmin-root": "true",
4830
5477
  sx: {
@@ -4834,15 +5481,15 @@ function Shell({ client, models, blocks, basePath, locale, children, theme, rout
4834
5481
  backgroundColor: "background.default",
4835
5482
  backgroundImage: "none"
4836
5483
  },
4837
- children: /* @__PURE__ */ jsxs19(
5484
+ children: /* @__PURE__ */ jsxs20(
4838
5485
  Stack14,
4839
5486
  {
4840
5487
  direction: { xs: "column", lg: "row" },
4841
5488
  spacing: 0,
4842
5489
  sx: { height: "100%", minHeight: 0, alignItems: "stretch" },
4843
5490
  children: [
4844
- /* @__PURE__ */ jsx27(
4845
- Box16,
5491
+ /* @__PURE__ */ jsx28(
5492
+ Box17,
4846
5493
  {
4847
5494
  sx: {
4848
5495
  display: { xs: "none", lg: "block" },
@@ -4853,11 +5500,11 @@ function Shell({ client, models, blocks, basePath, locale, children, theme, rout
4853
5500
  pl: 0,
4854
5501
  pr: 1
4855
5502
  },
4856
- children: /* @__PURE__ */ jsx27(Sidebar, { models, blocks, basePath })
5503
+ children: /* @__PURE__ */ jsx28(Sidebar, { models, blocks, basePath })
4857
5504
  }
4858
5505
  ),
4859
- /* @__PURE__ */ jsx27(
4860
- Box16,
5506
+ /* @__PURE__ */ jsx28(
5507
+ Box17,
4861
5508
  {
4862
5509
  sx: {
4863
5510
  flex: 1,
@@ -4870,7 +5517,7 @@ function Shell({ client, models, blocks, basePath, locale, children, theme, rout
4870
5517
  py: { xs: 1, sm: 1.5, lg: 2 },
4871
5518
  pl: { xs: 1, sm: 1.5, lg: 1 }
4872
5519
  },
4873
- children: /* @__PURE__ */ jsx27(Main, { children })
5520
+ children: /* @__PURE__ */ jsx28(Main, { children })
4874
5521
  }
4875
5522
  )
4876
5523
  ]
@@ -4878,7 +5525,7 @@ function Shell({ client, models, blocks, basePath, locale, children, theme, rout
4878
5525
  )
4879
5526
  }
4880
5527
  ),
4881
- /* @__PURE__ */ jsx27(
5528
+ /* @__PURE__ */ jsx28(
4882
5529
  Drawer,
4883
5530
  {
4884
5531
  anchor: "left",
@@ -4897,7 +5544,7 @@ function Shell({ client, models, blocks, basePath, locale, children, theme, rout
4897
5544
  }
4898
5545
  }
4899
5546
  },
4900
- children: /* @__PURE__ */ jsx27(Box16, { sx: { height: "100%", minHeight: 0, pr: 1.5 }, children: /* @__PURE__ */ jsx27(Sidebar, { models, blocks, basePath }) })
5547
+ children: /* @__PURE__ */ jsx28(Box17, { sx: { height: "100%", minHeight: 0, pr: 1.5 }, children: /* @__PURE__ */ jsx28(Sidebar, { models, blocks, basePath }) })
4901
5548
  }
4902
5549
  )
4903
5550
  ] }) }) }) }) }) });