@firecms/core 3.1.0-canary.1df3b2c → 3.1.0-canary.8958c1b

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.
Files changed (46) hide show
  1. package/dist/components/EntityCollectionTable/internal/popup_field/useDraggable.d.ts +2 -2
  2. package/dist/components/EntityCollectionView/ViewModeToggle.d.ts +5 -10
  3. package/dist/components/ErrorBoundary.d.ts +1 -1
  4. package/dist/components/VirtualTable/VirtualTableHeader.d.ts +1 -1
  5. package/dist/form/components/ErrorFocus.d.ts +1 -1
  6. package/dist/index.es.js +247 -210
  7. package/dist/index.es.js.map +1 -1
  8. package/dist/index.umd.js +246 -209
  9. package/dist/index.umd.js.map +1 -1
  10. package/dist/internal/useRestoreScroll.d.ts +1 -1
  11. package/dist/types/analytics.d.ts +1 -1
  12. package/dist/types/collections.d.ts +8 -0
  13. package/dist/types/plugins.d.ts +16 -0
  14. package/dist/util/entities.d.ts +1 -1
  15. package/dist/util/resolutions.d.ts +2 -2
  16. package/package.json +7 -7
  17. package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +1 -1
  18. package/src/components/EntityCollectionTable/internal/popup_field/useDraggable.tsx +11 -11
  19. package/src/components/EntityCollectionView/EntityBoardCard.tsx +1 -1
  20. package/src/components/EntityCollectionView/EntityCard.tsx +4 -0
  21. package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +23 -3
  22. package/src/components/EntityCollectionView/EntityCollectionView.tsx +50 -16
  23. package/src/components/EntityCollectionView/ViewModeToggle.tsx +27 -30
  24. package/src/components/VirtualTable/VirtualTable.tsx +116 -113
  25. package/src/components/VirtualTable/VirtualTableHeader.tsx +42 -42
  26. package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +1 -1
  27. package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +3 -3
  28. package/src/core/DefaultAppBar.tsx +1 -1
  29. package/src/core/EntitySidePanel.tsx +28 -26
  30. package/src/core/field_configs.tsx +14 -9
  31. package/src/form/EntityForm.tsx +69 -60
  32. package/src/form/PropertyFieldBinding.tsx +3 -3
  33. package/src/form/components/ErrorFocus.tsx +3 -3
  34. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +1 -1
  35. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +83 -83
  36. package/src/hooks/useBuildNavigationController.tsx +4 -4
  37. package/src/hooks/useValidateAuthenticator.tsx +1 -1
  38. package/src/internal/useBuildDataSource.ts +1 -2
  39. package/src/preview/PropertyPreview.tsx +1 -0
  40. package/src/types/analytics.ts +10 -0
  41. package/src/types/collections.ts +9 -0
  42. package/src/types/plugins.tsx +18 -0
  43. package/src/util/entities.ts +1 -1
  44. package/src/util/previews.ts +2 -2
  45. package/src/util/property_utils.tsx +1 -1
  46. package/src/util/resolutions.ts +5 -3
package/dist/index.umd.js CHANGED
@@ -785,7 +785,7 @@
785
785
  const defaultValues = getDefaultValuesFor(collection.properties);
786
786
  const usedValues = values ?? defaultValues;
787
787
  const usedPreviousValues = previousValues ?? values ?? defaultValues;
788
- const resolvedProperties = Object.entries(collection.properties).map(([key, propertyOrBuilder]) => {
788
+ const resolvedProperties = Object.entries(collection.properties).filter(([, propertyOrBuilder]) => propertyOrBuilder != null).map(([key, propertyOrBuilder]) => {
789
789
  const childResolvedProperty = resolveProperty({
790
790
  propertyKey: key,
791
791
  propertyOrBuilder,
@@ -824,7 +824,7 @@
824
824
  ignoreMissingFields = false,
825
825
  ...props
826
826
  }) {
827
- if (typeof propertyOrBuilder === "object" && "resolved" in propertyOrBuilder) {
827
+ if (propertyOrBuilder !== null && typeof propertyOrBuilder === "object" && "resolved" in propertyOrBuilder) {
828
828
  return propertyOrBuilder;
829
829
  }
830
830
  let resolvedProperty = null;
@@ -7577,7 +7577,7 @@
7577
7577
  } else {
7578
7578
  if (property.dataType === "map") {
7579
7579
  if (typeof value === "object") {
7580
- content = /* @__PURE__ */ jsxRuntime.jsx(MapPropertyPreview, { ...props, property });
7580
+ content = /* @__PURE__ */ jsxRuntime.jsx(MapPropertyPreview, { ...props, value, property });
7581
7581
  } else {
7582
7582
  content = buildWrongValueType(propertyKey, property.dataType, value);
7583
7583
  }
@@ -8461,7 +8461,7 @@
8461
8461
  const handleOpenChange = t4;
8462
8462
  let t5;
8463
8463
  if ($[11] !== disabled || $[12] !== enumValues || $[13] !== internalValue || $[14] !== multiple || $[15] !== onChange || $[16] !== renderValue || $[17] !== small || $[18] !== validValue) {
8464
- t5 = multiple ? /* @__PURE__ */ jsxRuntime.jsx(ui.MultiSelect, { inputRef: ref, className: "w-full h-full p-0 bg-transparent", position: "item-aligned", disabled, includeClear: false, useChips: false, value: validValue ? internalValue.map(_temp2$b) : [], onValueChange: onChange, onOpenChange: handleOpenChange, children: enumValues?.map((enumConfig) => /* @__PURE__ */ jsxRuntime.jsx(ui.MultiSelectItem, { value: String(enumConfig.id), children: /* @__PURE__ */ jsxRuntime.jsx(EnumValuesChip, { enumKey: enumConfig.id, enumValues, size: small ? "small" : "medium" }) }, enumConfig.id)) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Select, { inputRef: ref, size: "large", fullWidth: true, className: "w-full h-full p-0 bg-transparent", inputClassName: "focus:ring-0 focus-visible:ring-0 outline-none focus:outline-none focus-visible:outline-none", position: "item-aligned", disabled, padding: false, value: validValue ? internalValue?.toString() : "", onValueChange: onChange, onOpenChange: handleOpenChange, renderValue, children: enumValues?.map((enumConfig_0) => /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: String(enumConfig_0.id), children: /* @__PURE__ */ jsxRuntime.jsx(EnumValuesChip, { enumKey: enumConfig_0.id, enumValues, size: small ? "small" : "medium" }) }, enumConfig_0.id)) });
8464
+ t5 = multiple ? /* @__PURE__ */ jsxRuntime.jsx(ui.MultiSelect, { inputRef: ref, className: "w-full h-full p-0 bg-transparent outline-none", position: "item-aligned", disabled, includeClear: false, useChips: false, value: validValue ? internalValue.map(_temp2$b) : [], onValueChange: onChange, onOpenChange: handleOpenChange, children: enumValues?.map((enumConfig) => /* @__PURE__ */ jsxRuntime.jsx(ui.MultiSelectItem, { value: String(enumConfig.id), children: /* @__PURE__ */ jsxRuntime.jsx(EnumValuesChip, { enumKey: enumConfig.id, enumValues, size: small ? "small" : "medium" }) }, enumConfig.id)) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Select, { inputRef: ref, size: "large", fullWidth: true, className: "w-full h-full p-0 bg-transparent outline-none [&_button]:ring-0 [&_button]:ring-offset-0", inputClassName: "ring-0 ring-offset-0 focus:ring-0 focus-visible:ring-0 outline-none focus:outline-none focus-visible:outline-none focus-visible:ring-offset-0", position: "item-aligned", disabled, padding: false, value: validValue ? internalValue?.toString() : "", onValueChange: onChange, onOpenChange: handleOpenChange, renderValue, children: enumValues?.map((enumConfig_0) => /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: String(enumConfig_0.id), children: /* @__PURE__ */ jsxRuntime.jsx(EnumValuesChip, { enumKey: enumConfig_0.id, enumValues, size: small ? "small" : "medium" }) }, enumConfig_0.id)) });
8465
8465
  $[11] = disabled;
8466
8466
  $[12] = enumValues;
8467
8467
  $[13] = internalValue;
@@ -9021,7 +9021,7 @@
9021
9021
  openPopup(cellRect);
9022
9022
  }
9023
9023
  }, []);
9024
- const iconRef = React.useRef();
9024
+ const iconRef = React.useRef(void 0);
9025
9025
  React.useEffect(() => {
9026
9026
  if (iconRef.current && selected) {
9027
9027
  iconRef.current.focus({
@@ -12169,7 +12169,7 @@
12169
12169
  onColumnResize(params_0);
12170
12170
  }
12171
12171
  }, [columns, onColumnResize]);
12172
- const filterRef = React.useRef();
12172
+ const filterRef = React.useRef(void 0);
12173
12173
  React.useEffect(() => {
12174
12174
  filterRef.current = filterInput;
12175
12175
  }, [filterInput]);
@@ -12281,7 +12281,7 @@
12281
12281
  return tableContent;
12282
12282
  }, equal);
12283
12283
  const SortableCellWrapper = (t0) => {
12284
- const $ = reactCompilerRuntime.c(15);
12284
+ const $ = reactCompilerRuntime.c(17);
12285
12285
  const {
12286
12286
  columnKey,
12287
12287
  width,
@@ -12309,10 +12309,22 @@
12309
12309
  transform,
12310
12310
  transition
12311
12311
  } = sortable.useSortable(t2);
12312
+ let attrsWithoutTabIndex;
12313
+ if ($[3] !== attributes) {
12314
+ const {
12315
+ tabIndex: _tabIndex,
12316
+ ...t32
12317
+ } = attributes;
12318
+ attrsWithoutTabIndex = t32;
12319
+ $[3] = attributes;
12320
+ $[4] = attrsWithoutTabIndex;
12321
+ } else {
12322
+ attrsWithoutTabIndex = $[4];
12323
+ }
12312
12324
  const t3 = transform ? `translateX(${transform.x}px)` : void 0;
12313
12325
  const t4 = isDragging ? void 0 : transition;
12314
12326
  let t5;
12315
- if ($[3] !== t3 || $[4] !== t4 || $[5] !== width) {
12327
+ if ($[5] !== t3 || $[6] !== t4 || $[7] !== width) {
12316
12328
  t5 = {
12317
12329
  transform: t3,
12318
12330
  transition: t4,
@@ -12320,34 +12332,34 @@
12320
12332
  maxWidth: width,
12321
12333
  width
12322
12334
  };
12323
- $[3] = t3;
12324
- $[4] = t4;
12325
- $[5] = width;
12326
- $[6] = t5;
12335
+ $[5] = t3;
12336
+ $[6] = t4;
12337
+ $[7] = width;
12338
+ $[8] = t5;
12327
12339
  } else {
12328
- t5 = $[6];
12340
+ t5 = $[8];
12329
12341
  }
12330
12342
  const style = t5;
12331
12343
  const t6 = frozen && "sticky left-0 z-10 bg-white dark:bg-surface-950";
12332
12344
  let t7;
12333
- if ($[7] !== t6) {
12345
+ if ($[9] !== t6) {
12334
12346
  t7 = ui.cls("flex-shrink-0", t6);
12335
- $[7] = t6;
12336
- $[8] = t7;
12347
+ $[9] = t6;
12348
+ $[10] = t7;
12337
12349
  } else {
12338
- t7 = $[8];
12350
+ t7 = $[10];
12339
12351
  }
12340
12352
  let t8;
12341
- if ($[9] !== attributes || $[10] !== children || $[11] !== setNodeRef || $[12] !== style || $[13] !== t7) {
12342
- t8 = /* @__PURE__ */ jsxRuntime.jsx("div", { ref: setNodeRef, style, className: t7, ...attributes, children });
12343
- $[9] = attributes;
12344
- $[10] = children;
12345
- $[11] = setNodeRef;
12346
- $[12] = style;
12347
- $[13] = t7;
12348
- $[14] = t8;
12353
+ if ($[11] !== attrsWithoutTabIndex || $[12] !== children || $[13] !== setNodeRef || $[14] !== style || $[15] !== t7) {
12354
+ t8 = /* @__PURE__ */ jsxRuntime.jsx("div", { ref: setNodeRef, style, className: t7, ...attrsWithoutTabIndex, children });
12355
+ $[11] = attrsWithoutTabIndex;
12356
+ $[12] = children;
12357
+ $[13] = setNodeRef;
12358
+ $[14] = style;
12359
+ $[15] = t7;
12360
+ $[16] = t8;
12349
12361
  } else {
12350
- t8 = $[14];
12362
+ t8 = $[16];
12351
12363
  }
12352
12364
  return t8;
12353
12365
  };
@@ -16250,7 +16262,7 @@
16250
16262
  size = "m"
16251
16263
  }) {
16252
16264
  const authController = useAuthController();
16253
- useAnalyticsController();
16265
+ const analyticsController = useAnalyticsController();
16254
16266
  useSideEntityController();
16255
16267
  const customizationController = useCustomizationController();
16256
16268
  useNavigationController();
@@ -16277,6 +16289,10 @@
16277
16289
  return;
16278
16290
  }
16279
16291
  if (onClick) {
16292
+ analyticsController.onAnalyticsEvent?.("card_view_entity_click", {
16293
+ path: entity.path,
16294
+ entityId: entity.id
16295
+ });
16280
16296
  onClick(entity);
16281
16297
  }
16282
16298
  };
@@ -17563,7 +17579,7 @@
17563
17579
  return /* @__PURE__ */ jsxRuntime.jsx("div", { style, className: "py-1", "data-is-dragging": isDragging, "data-testid": item.id, onClick: handleClick, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cardClassName, children: [
17564
17580
  usedImageProperty && usedImageValue ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-10 h-10 rounded-md overflow-hidden shrink-0 mr-2", children: /* @__PURE__ */ jsxRuntime.jsx(PropertyPreview, { property: usedImageProperty, propertyKey: imagePropertyKey, size: "small", value: usedImageValue, fill: true }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-10 h-10 rounded-md bg-surface-100 dark:bg-surface-800 shrink-0 mr-2 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(IconForView, { collectionOrView: collection, color: "disabled", size: "small" }) }),
17565
17581
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
17566
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate text-sm font-medium", children: titleProperty && titleValue ? /* @__PURE__ */ jsxRuntime.jsx(PropertyPreview, { propertyKey: titlePropertyKey, value: titleValue, property: titleProperty, size: "small" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-surface-500", children: entity.id }) }),
17582
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "line-clamp-2 text-sm font-medium", children: titleProperty && titleValue ? /* @__PURE__ */ jsxRuntime.jsx(PropertyPreview, { propertyKey: titlePropertyKey, value: titleValue, property: titleProperty, size: "small" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-surface-500", children: entity.id }) }),
17567
17583
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-surface-500 font-mono truncate", children: entity.id })
17568
17584
  ] }),
17569
17585
  selectionEnabled && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-2 shrink-0", onClick: handleCheckboxClick, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Checkbox, { checked: selected ?? false, onCheckedChange: handleSelectionChange, size: "smallest" }) })
@@ -17919,6 +17935,7 @@
17919
17935
  const context = useFireCMSContext();
17920
17936
  const dataSource = useDataSource();
17921
17937
  const sideEntityController = useSideEntityController();
17938
+ const analyticsController = useAnalyticsController();
17922
17939
  const plugins = customizationController.plugins ?? [];
17923
17940
  const [showBackfillDialog, setShowBackfillDialog] = React.useState(false);
17924
17941
  const [backfillLoading, setBackfillLoading] = React.useState(false);
@@ -18034,6 +18051,10 @@
18034
18051
  return plugins.some((plugin) => plugin.collectionView?.onKanbanColumnsReorder);
18035
18052
  }, [plugins]);
18036
18053
  const handleColumnReorder = React.useCallback((newColumns) => {
18054
+ analyticsController.onAnalyticsEvent?.("kanban_column_reorder", {
18055
+ path: fullPath,
18056
+ columnProperty
18057
+ });
18037
18058
  setHasUserReordered(true);
18038
18059
  setLocalColumnsOrder(newColumns);
18039
18060
  plugins.filter((plugin_0) => plugin_0.collectionView?.onKanbanColumnsReorder).forEach((plugin_1) => {
@@ -18045,7 +18066,7 @@
18045
18066
  newColumnsOrder: newColumns
18046
18067
  });
18047
18068
  });
18048
- }, [plugins, fullPath, parentCollectionIds, collection, columnProperty]);
18069
+ }, [plugins, fullPath, parentCollectionIds, collection, columnProperty, analyticsController]);
18049
18070
  const [missingOrderCount, setMissingOrderCount] = React.useState(0);
18050
18071
  const dataSourceRef = React.useRef(dataSource);
18051
18072
  const collectionRef = React.useRef(collection);
@@ -18157,6 +18178,12 @@
18157
18178
  const handleItemsReorder = React.useCallback(async (items_0, moveInfo) => {
18158
18179
  const entity_2 = items_0.find((item_5) => item_5.id === moveInfo?.itemId)?.entity;
18159
18180
  if (!entity_2) return;
18181
+ analyticsController.onAnalyticsEvent?.("kanban_card_moved", {
18182
+ path: fullPath,
18183
+ entityId: entity_2.id,
18184
+ sourceColumn: moveInfo?.sourceColumn,
18185
+ targetColumn: moveInfo?.targetColumn
18186
+ });
18160
18187
  const isColumnChange = moveInfo && moveInfo.sourceColumn !== moveInfo.targetColumn;
18161
18188
  if (!orderProperty && !isColumnChange) return;
18162
18189
  if (isColumnChange) {
@@ -18194,7 +18221,7 @@
18194
18221
  } catch (e_1) {
18195
18222
  console.error("Error saving entity:", e_1);
18196
18223
  }
18197
- }, [collection, columnProperty, orderProperty, context, dataSource, calculateNewOrder, boardDataController]);
18224
+ }, [collection, columnProperty, orderProperty, context, dataSource, calculateNewOrder, boardDataController, analyticsController, fullPath]);
18198
18225
  const handleBackfill = React.useCallback(async () => {
18199
18226
  console.log("handleBackfill called", {
18200
18227
  orderProperty
@@ -18203,6 +18230,9 @@
18203
18230
  console.log("No orderProperty, returning");
18204
18231
  return;
18205
18232
  }
18233
+ analyticsController.onAnalyticsEvent?.("kanban_backfill_order", {
18234
+ path: fullPath
18235
+ });
18206
18236
  setBackfillLoading(true);
18207
18237
  try {
18208
18238
  console.log("Fetching all documents from collection...");
@@ -18256,7 +18286,7 @@
18256
18286
  } finally {
18257
18287
  setBackfillLoading(false);
18258
18288
  }
18259
- }, [orderProperty, fullPath, collection, dataSource, context, boardDataController]);
18289
+ }, [orderProperty, fullPath, collection, dataSource, context, boardDataController, analyticsController]);
18260
18290
  const handleEntityClick = React.useCallback((entity_5) => {
18261
18291
  onEntityClick?.(entity_5);
18262
18292
  }, [onEntityClick]);
@@ -18317,6 +18347,10 @@
18317
18347
  /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "text", onClick: () => setShowBackfillDialog(true), children: "Initialize Order" })
18318
18348
  ] }),
18319
18349
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-auto no-scrollbar", children: /* @__PURE__ */ jsxRuntime.jsx(Board, { data: boardItems, columns, columnLabels, columnColors, assignColumn, allowColumnReorder, onColumnReorder: handleColumnReorder, onItemsReorder: handleItemsReorder, ItemComponent, columnLoadingState, onLoadMoreColumn: (column) => boardDataController.loadMoreColumn(column), onAddItemToColumn: (column_0) => {
18350
+ analyticsController.onAnalyticsEvent?.("kanban_new_entity_in_column", {
18351
+ path: fullPath,
18352
+ column: column_0
18353
+ });
18320
18354
  sideEntityController.open({
18321
18355
  path: fullPath,
18322
18356
  collection,
@@ -18341,13 +18375,13 @@
18341
18375
  ] })
18342
18376
  ] });
18343
18377
  }
18378
+ const ALL_VIEW_MODES = ["table", "cards", "kanban"];
18344
18379
  function ViewModeToggle(t0) {
18345
- const $ = reactCompilerRuntime.c(42);
18380
+ const $ = reactCompilerRuntime.c(36);
18346
18381
  const {
18347
18382
  viewMode: t1,
18348
18383
  onViewModeChange,
18349
- kanbanEnabled: t2,
18350
- hasKanbanConfigPlugin: t3,
18384
+ enabledViews: t2,
18351
18385
  size,
18352
18386
  onSizeChanged,
18353
18387
  open,
@@ -18357,14 +18391,13 @@
18357
18391
  onKanbanPropertyChange
18358
18392
  } = t0;
18359
18393
  const viewMode = t1 === void 0 ? "table" : t1;
18360
- const kanbanEnabled = t2 === void 0 ? false : t2;
18361
- const hasKanbanConfigPlugin = t3 === void 0 ? false : t3;
18394
+ const enabledViews = t2 === void 0 ? ALL_VIEW_MODES : t2;
18362
18395
  if (!onViewModeChange) {
18363
18396
  return null;
18364
18397
  }
18365
- let t4;
18398
+ let t3;
18366
18399
  if ($[0] !== viewMode) {
18367
- t4 = () => {
18400
+ t3 = () => {
18368
18401
  if (viewMode === "kanban") {
18369
18402
  return /* @__PURE__ */ jsxRuntime.jsx(ui.ViewKanbanIcon, { size: "small" });
18370
18403
  }
@@ -18374,14 +18407,14 @@
18374
18407
  return /* @__PURE__ */ jsxRuntime.jsx(ui.ListIcon, { size: "small" });
18375
18408
  };
18376
18409
  $[0] = viewMode;
18377
- $[1] = t4;
18410
+ $[1] = t3;
18378
18411
  } else {
18379
- t4 = $[1];
18412
+ t3 = $[1];
18380
18413
  }
18381
- const getViewModeIcon = t4;
18382
- let t5;
18414
+ const getViewModeIcon = t3;
18415
+ let t4;
18383
18416
  if ($[2] !== viewMode) {
18384
- t5 = () => {
18417
+ t4 = () => {
18385
18418
  if (viewMode === "kanban") {
18386
18419
  return "Board";
18387
18420
  }
@@ -18391,177 +18424,151 @@
18391
18424
  return "List";
18392
18425
  };
18393
18426
  $[2] = viewMode;
18394
- $[3] = t5;
18427
+ $[3] = t4;
18395
18428
  } else {
18396
- t5 = $[3];
18429
+ t4 = $[3];
18397
18430
  }
18398
- const getViewModeName = t5;
18399
- const showKanban = kanbanEnabled || hasKanbanConfigPlugin;
18431
+ const getViewModeName = t4;
18400
18432
  const showSizeSelector = size && onSizeChanged && (viewMode === "table" || viewMode === "cards");
18401
18433
  const showKanbanPropertySelector = viewMode === "kanban" && kanbanPropertyOptions && kanbanPropertyOptions.length > 0 && onKanbanPropertyChange;
18434
+ let t5;
18402
18435
  let t6;
18403
- let t7;
18404
18436
  if ($[4] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
18405
- t7 = {
18406
- value: "table",
18407
- label: "List",
18408
- icon: /* @__PURE__ */ jsxRuntime.jsx(ui.ListIcon, { size: "small" })
18409
- };
18410
- $[4] = t7;
18437
+ t6 = /* @__PURE__ */ jsxRuntime.jsx(ui.ListIcon, { size: "small" });
18438
+ $[4] = t6;
18411
18439
  } else {
18412
- t7 = $[4];
18440
+ t6 = $[4];
18413
18441
  }
18414
- let t8;
18415
- if ($[5] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
18416
- t8 = {
18442
+ let t7;
18443
+ if ($[5] !== enabledViews) {
18444
+ const allOptions = [{
18445
+ value: "table",
18446
+ label: "List",
18447
+ icon: t6
18448
+ }, {
18417
18449
  value: "cards",
18418
18450
  label: "Cards",
18419
18451
  icon: /* @__PURE__ */ jsxRuntime.jsx(ui.AppsIcon, { size: "small" })
18420
- };
18421
- $[5] = t8;
18452
+ }, {
18453
+ value: "kanban",
18454
+ label: "Board",
18455
+ icon: /* @__PURE__ */ jsxRuntime.jsx(ui.ViewKanbanIcon, { size: "small" })
18456
+ }];
18457
+ t7 = allOptions.filter((option) => enabledViews.includes(option.value));
18458
+ $[5] = enabledViews;
18459
+ $[6] = t7;
18422
18460
  } else {
18423
- t8 = $[5];
18461
+ t7 = $[6];
18424
18462
  }
18425
- let options;
18426
- if ($[6] !== hasKanbanConfigPlugin || $[7] !== kanbanEnabled || $[8] !== showKanban) {
18427
- options = [t7, t8];
18428
- if (showKanban) {
18429
- let t92;
18430
- if ($[10] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
18431
- t92 = /* @__PURE__ */ jsxRuntime.jsx(ui.ViewKanbanIcon, { size: "small" });
18432
- $[10] = t92;
18433
- } else {
18434
- t92 = $[10];
18435
- }
18436
- const t102 = !kanbanEnabled && !hasKanbanConfigPlugin;
18437
- let t112;
18438
- if ($[11] !== t102) {
18439
- t112 = {
18440
- value: "kanban",
18441
- label: "Board",
18442
- icon: t92,
18443
- disabled: t102
18444
- };
18445
- $[11] = t102;
18446
- $[12] = t112;
18447
- } else {
18448
- t112 = $[12];
18449
- }
18450
- options.push(t112);
18451
- }
18452
- $[6] = hasKanbanConfigPlugin;
18453
- $[7] = kanbanEnabled;
18454
- $[8] = showKanban;
18455
- $[9] = options;
18463
+ t5 = t7;
18464
+ const viewModeOptions = t5;
18465
+ if (viewModeOptions.length <= 1 && !showSizeSelector) {
18466
+ return null;
18467
+ }
18468
+ let t8;
18469
+ if ($[7] !== getViewModeIcon) {
18470
+ t8 = getViewModeIcon();
18471
+ $[7] = getViewModeIcon;
18472
+ $[8] = t8;
18456
18473
  } else {
18457
- options = $[9];
18474
+ t8 = $[8];
18458
18475
  }
18459
- t6 = options;
18460
- const viewModeOptions = t6;
18461
- let t9;
18462
- if ($[13] !== getViewModeIcon) {
18463
- t9 = getViewModeIcon();
18464
- $[13] = getViewModeIcon;
18465
- $[14] = t9;
18476
+ const t9 = getViewModeName();
18477
+ let t10;
18478
+ if ($[9] !== t9) {
18479
+ t10 = /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 text-sm", children: t9 });
18480
+ $[9] = t9;
18481
+ $[10] = t10;
18466
18482
  } else {
18467
- t9 = $[14];
18483
+ t10 = $[10];
18468
18484
  }
18469
- const t10 = getViewModeName();
18470
18485
  let t11;
18471
- if ($[15] !== t10) {
18472
- t11 = /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 text-sm", children: t10 });
18473
- $[15] = t10;
18474
- $[16] = t11;
18486
+ if ($[11] !== t10 || $[12] !== t8) {
18487
+ t11 = /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { size: "small", children: [
18488
+ t8,
18489
+ t10
18490
+ ] });
18491
+ $[11] = t10;
18492
+ $[12] = t8;
18493
+ $[13] = t11;
18475
18494
  } else {
18476
- t11 = $[16];
18495
+ t11 = $[13];
18477
18496
  }
18478
18497
  let t12;
18479
- if ($[17] !== t11 || $[18] !== t9) {
18480
- t12 = /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { size: "small", children: [
18481
- t9,
18482
- t11
18483
- ] });
18484
- $[17] = t11;
18485
- $[18] = t9;
18486
- $[19] = t12;
18498
+ if ($[14] !== onViewModeChange || $[15] !== viewMode || $[16] !== viewModeOptions) {
18499
+ t12 = viewModeOptions.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(ui.ToggleButtonGroup, { value: viewMode, onValueChange: onViewModeChange, options: viewModeOptions });
18500
+ $[14] = onViewModeChange;
18501
+ $[15] = viewMode;
18502
+ $[16] = viewModeOptions;
18503
+ $[17] = t12;
18487
18504
  } else {
18488
- t12 = $[19];
18505
+ t12 = $[17];
18489
18506
  }
18490
18507
  let t13;
18491
- if ($[20] !== onViewModeChange || $[21] !== viewMode || $[22] !== viewModeOptions) {
18492
- t13 = /* @__PURE__ */ jsxRuntime.jsx(ui.ToggleButtonGroup, { value: viewMode, onValueChange: onViewModeChange, options: viewModeOptions });
18493
- $[20] = onViewModeChange;
18494
- $[21] = viewMode;
18495
- $[22] = viewModeOptions;
18496
- $[23] = t13;
18497
- } else {
18498
- t13 = $[23];
18499
- }
18500
- let t14;
18501
- if ($[24] !== onSizeChanged || $[25] !== showSizeSelector || $[26] !== size) {
18502
- t14 = showSizeSelector && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-row items-center justify-between gap-2", children: [
18508
+ if ($[18] !== onSizeChanged || $[19] !== showSizeSelector || $[20] !== size) {
18509
+ t13 = showSizeSelector && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-row items-center justify-between gap-2", children: [
18503
18510
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm text-surface-600 dark:text-surface-300", children: [
18504
18511
  /* @__PURE__ */ jsxRuntime.jsx(ui.ViewColumnIcon, { size: "small" }),
18505
18512
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Size" })
18506
18513
  ] }),
18507
18514
  /* @__PURE__ */ jsxRuntime.jsx(ui.Select, { value: size, size: "small", className: "w-20", onValueChange: (v) => onSizeChanged?.(v), renderValue: _temp$e, children: ["xs", "s", "m", "l", "xl"].map(_temp2$5) })
18508
18515
  ] });
18509
- $[24] = onSizeChanged;
18510
- $[25] = showSizeSelector;
18511
- $[26] = size;
18512
- $[27] = t14;
18516
+ $[18] = onSizeChanged;
18517
+ $[19] = showSizeSelector;
18518
+ $[20] = size;
18519
+ $[21] = t13;
18513
18520
  } else {
18514
- t14 = $[27];
18521
+ t13 = $[21];
18515
18522
  }
18516
- let t15;
18517
- if ($[28] !== kanbanPropertyOptions || $[29] !== onKanbanPropertyChange || $[30] !== selectedKanbanProperty || $[31] !== showKanbanPropertySelector) {
18518
- t15 = showKanbanPropertySelector && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-row items-center justify-between gap-2", children: [
18523
+ let t14;
18524
+ if ($[22] !== kanbanPropertyOptions || $[23] !== onKanbanPropertyChange || $[24] !== selectedKanbanProperty || $[25] !== showKanbanPropertySelector) {
18525
+ t14 = showKanbanPropertySelector && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-row items-center justify-between gap-2", children: [
18519
18526
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm text-surface-600 dark:text-surface-300", children: [
18520
18527
  /* @__PURE__ */ jsxRuntime.jsx(ui.ViewKanbanIcon, { size: "small" }),
18521
18528
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Group by" })
18522
18529
  ] }),
18523
18530
  /* @__PURE__ */ jsxRuntime.jsx(ui.Select, { value: selectedKanbanProperty, size: "small", className: "w-32", onValueChange: (v_1) => onKanbanPropertyChange?.(v_1), renderValue: (v_2) => {
18524
- const option = kanbanPropertyOptions?.find((o) => o.key === v_2);
18525
- return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium truncate", children: option?.label ?? v_2 });
18531
+ const option_0 = kanbanPropertyOptions?.find((o) => o.key === v_2);
18532
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium truncate", children: option_0?.label ?? v_2 });
18526
18533
  }, children: kanbanPropertyOptions?.map(_temp3$3) })
18527
18534
  ] });
18528
- $[28] = kanbanPropertyOptions;
18529
- $[29] = onKanbanPropertyChange;
18530
- $[30] = selectedKanbanProperty;
18531
- $[31] = showKanbanPropertySelector;
18532
- $[32] = t15;
18535
+ $[22] = kanbanPropertyOptions;
18536
+ $[23] = onKanbanPropertyChange;
18537
+ $[24] = selectedKanbanProperty;
18538
+ $[25] = showKanbanPropertySelector;
18539
+ $[26] = t14;
18533
18540
  } else {
18534
- t15 = $[32];
18541
+ t14 = $[26];
18535
18542
  }
18536
- let t16;
18537
- if ($[33] !== t13 || $[34] !== t14 || $[35] !== t15) {
18538
- t16 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-3 flex flex-col gap-3 min-w-[240px]", children: [
18543
+ let t15;
18544
+ if ($[27] !== t12 || $[28] !== t13 || $[29] !== t14) {
18545
+ t15 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-3 flex flex-col gap-3 min-w-[240px]", children: [
18546
+ t12,
18539
18547
  t13,
18540
- t14,
18541
- t15
18548
+ t14
18542
18549
  ] });
18543
- $[33] = t13;
18544
- $[34] = t14;
18545
- $[35] = t15;
18546
- $[36] = t16;
18550
+ $[27] = t12;
18551
+ $[28] = t13;
18552
+ $[29] = t14;
18553
+ $[30] = t15;
18547
18554
  } else {
18548
- t16 = $[36];
18555
+ t15 = $[30];
18549
18556
  }
18550
- let t17;
18551
- if ($[37] !== onOpenChange || $[38] !== open || $[39] !== t12 || $[40] !== t16) {
18552
- t17 = /* @__PURE__ */ jsxRuntime.jsx(ui.Popover, { open, onOpenChange, modal: true, trigger: t12, children: t16 });
18553
- $[37] = onOpenChange;
18554
- $[38] = open;
18555
- $[39] = t12;
18556
- $[40] = t16;
18557
- $[41] = t17;
18557
+ let t16;
18558
+ if ($[31] !== onOpenChange || $[32] !== open || $[33] !== t11 || $[34] !== t15) {
18559
+ t16 = /* @__PURE__ */ jsxRuntime.jsx(ui.Popover, { open, onOpenChange, modal: true, trigger: t11, children: t15 });
18560
+ $[31] = onOpenChange;
18561
+ $[32] = open;
18562
+ $[33] = t11;
18563
+ $[34] = t15;
18564
+ $[35] = t16;
18558
18565
  } else {
18559
- t17 = $[41];
18566
+ t16 = $[35];
18560
18567
  }
18561
- return t17;
18568
+ return t16;
18562
18569
  }
18563
- function _temp3$3(option_0) {
18564
- return /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: option_0.key, children: option_0.label }, option_0.key);
18570
+ function _temp3$3(option_1) {
18571
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: option_1.key, children: option_1.label }, option_1.key);
18565
18572
  }
18566
18573
  function _temp2$5(s) {
18567
18574
  return /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: s, className: "font-medium text-center", children: s.toUpperCase() }, s);
@@ -19508,6 +19515,7 @@
19508
19515
  console.error(error);
19509
19516
  }, [snackbarController]);
19510
19517
  const pluginActions = [];
19518
+ const pluginBeforeTitle = [];
19511
19519
  const plugins = customizationController.plugins;
19512
19520
  const actionsDisabled = disabled || formex$1.isSubmitting || status === "existing" && !formex$1.dirty || Boolean(disabledProp);
19513
19521
  const parentCollectionIds = navigationController.getParentCollectionIds(path);
@@ -19524,6 +19532,7 @@
19524
19532
  disabled: actionsDisabled
19525
19533
  };
19526
19534
  pluginActions.push(...plugins.map((plugin) => plugin.form?.Actions ? /* @__PURE__ */ jsxRuntime.jsx(plugin.form.Actions, { ...actionProps }, `actions_${plugin.key}`) : null).filter(Boolean));
19535
+ pluginBeforeTitle.push(...plugins.map((plugin_0) => plugin_0.form?.BeforeTitle ? /* @__PURE__ */ jsxRuntime.jsx(plugin_0.form.BeforeTitle, { ...actionProps }, `before_title_${plugin_0.key}`) : null).filter(Boolean));
19527
19536
  }
19528
19537
  const titlePropertyKey = getEntityTitlePropertyKey(resolvedCollection, customizationController.propertyConfigs);
19529
19538
  const title = (formex$1.values && titlePropertyKey ? getValueInPath(formex$1.values, titlePropertyKey) : void 0) ?? collection.singularName ?? collection.name;
@@ -19620,6 +19629,7 @@
19620
19629
  };
19621
19630
  const formRef = React.useRef(null);
19622
19631
  const formView = /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { children: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
19632
+ pluginBeforeTitle,
19623
19633
  !Builder && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full py-2 flex flex-col items-start my-4 lg:my-6", children: [
19624
19634
  /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { className: "my-4 flex-grow line-clamp-1 " + (collection.hideIdFromForm ? "mb-6" : ""), variant: "h4", children: title ?? collection.singularName ?? collection.name }),
19625
19635
  !entity?.values && initialStatus === "existing" && /* @__PURE__ */ jsxRuntime.jsx(ui.Alert, { color: "warning", size: "small", outerClassName: "w-full mb-4 text-xs", children: "This entity does not exist in the database" }),
@@ -21877,7 +21887,7 @@
21877
21887
  index,
21878
21888
  authController
21879
21889
  });
21880
- Component = configProperty.Field;
21890
+ Component = configProperty?.Field;
21881
21891
  }
21882
21892
  }
21883
21893
  }
@@ -24502,13 +24512,18 @@
24502
24512
  });
24503
24513
  }, [onCollectionModifiedForUser, fullPath, userConfigPersistence]);
24504
24514
  const onViewModeChange = React.useCallback((mode) => {
24515
+ analyticsController.onAnalyticsEvent?.("view_mode_changed", {
24516
+ path: fullPath,
24517
+ from: viewMode,
24518
+ to: mode
24519
+ });
24505
24520
  setViewMode(mode);
24506
24521
  if (userConfigPersistence) {
24507
24522
  onCollectionModifiedForUser(fullPath, {
24508
24523
  defaultViewMode: mode
24509
24524
  });
24510
24525
  }
24511
- }, [setViewMode, userConfigPersistence, onCollectionModifiedForUser, fullPath]);
24526
+ }, [setViewMode, userConfigPersistence, onCollectionModifiedForUser, fullPath, analyticsController, viewMode]);
24512
24527
  const createEnabled = canCreateEntity(collection, authController, fullPath, null);
24513
24528
  const uniqueFieldValidator = React.useCallback(({
24514
24529
  name,
@@ -24562,24 +24577,26 @@
24562
24577
  propertyConfigs: customizationController.propertyConfigs,
24563
24578
  authController
24564
24579
  }), [collection, fullPath]);
24565
- const kanbanEnabled = React.useMemo(() => {
24566
- if (!collection.kanban?.columnProperty) return false;
24567
- const property_0 = getPropertyInPath(resolvedCollection.properties, collection.kanban.columnProperty);
24568
- if (!property_0 || !("dataType" in property_0) || property_0.dataType !== "string") return false;
24569
- return Boolean(property_0.enumValues);
24570
- }, [collection.kanban?.columnProperty, resolvedCollection.properties]);
24571
- const hasKanbanConfigPlugin = React.useMemo(() => {
24572
- return customizationController.plugins?.some((plugin_0) => plugin_0.collectionView?.KanbanSetupComponent) ?? false;
24573
- }, [customizationController.plugins]);
24580
+ const hasEnumProperty = React.useMemo(() => {
24581
+ const properties = resolvedCollection.properties;
24582
+ return Object.values(properties).some((prop) => prop && prop.dataType === "string" && prop.enumValues);
24583
+ }, [resolvedCollection.properties]);
24584
+ const enabledViews = React.useMemo(() => {
24585
+ const configured = collection.enabledViews ?? ["table", "cards", "kanban"];
24586
+ if (!hasEnumProperty) {
24587
+ return configured.filter((v) => v !== "kanban");
24588
+ }
24589
+ return configured;
24590
+ }, [collection.enabledViews, hasEnumProperty]);
24574
24591
  const kanbanPropertyOptions = React.useMemo(() => {
24575
24592
  const options = [];
24576
- const properties = resolvedCollection.properties;
24577
- for (const [key_0, property_1] of Object.entries(properties)) {
24578
- const prop = property_1;
24579
- if (prop && prop.dataType === "string" && prop.enumValues) {
24593
+ const properties_0 = resolvedCollection.properties;
24594
+ for (const [key_0, property_0] of Object.entries(properties_0)) {
24595
+ const prop_0 = property_0;
24596
+ if (prop_0 && prop_0.dataType === "string" && prop_0.enumValues) {
24580
24597
  options.push({
24581
24598
  key: key_0,
24582
- label: prop.name || key_0
24599
+ label: prop_0.name || key_0
24583
24600
  });
24584
24601
  }
24585
24602
  }
@@ -24607,14 +24624,18 @@
24607
24624
  }
24608
24625
  }
24609
24626
  }, [kanbanPropertyOptions, selectedKanbanProperty, getSavedKanbanProperty, collection.kanban?.columnProperty]);
24610
- const onKanbanPropertyChange = React.useCallback((property_2) => {
24611
- setSelectedKanbanProperty(property_2);
24627
+ const onKanbanPropertyChange = React.useCallback((property_1) => {
24628
+ analyticsController.onAnalyticsEvent?.("kanban_property_changed", {
24629
+ path: fullPath,
24630
+ property: property_1
24631
+ });
24632
+ setSelectedKanbanProperty(property_1);
24612
24633
  if (userConfigPersistence) {
24613
24634
  onCollectionModifiedForUser(fullPath, {
24614
- kanbanColumnProperty: property_2
24635
+ kanbanColumnProperty: property_1
24615
24636
  });
24616
24637
  }
24617
- }, [userConfigPersistence, onCollectionModifiedForUser, fullPath]);
24638
+ }, [userConfigPersistence, onCollectionModifiedForUser, fullPath, analyticsController]);
24618
24639
  const getPropertyFor = React.useCallback(({
24619
24640
  propertyKey: propertyKey_0,
24620
24641
  entity: entity_2
@@ -24726,15 +24747,15 @@
24726
24747
  }, [docsCount, fullPath, breadcrumbs.updateCount]);
24727
24748
  const countFetcher = /* @__PURE__ */ jsxRuntime.jsx(EntitiesCount, { fullPath, collection, filter: tableController.filterValues, sortBy: tableController.sortBy, onCountChange: setDocsCount });
24728
24749
  const buildAdditionalHeaderWidget = React.useCallback(({
24729
- property: property_3,
24750
+ property: property_2,
24730
24751
  propertyKey: propertyKey_1,
24731
24752
  onHover
24732
24753
  }) => {
24733
24754
  const collection_4 = collectionRef.current;
24734
24755
  if (!customizationController.plugins) return null;
24735
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: customizationController.plugins.filter((plugin_1) => plugin_1.collectionView?.HeaderAction).map((plugin_2, i) => {
24736
- const HeaderAction = plugin_2.collectionView.HeaderAction;
24737
- return /* @__PURE__ */ jsxRuntime.jsx(HeaderAction, { onHover, propertyKey: propertyKey_1, property: property_3, fullPath, collection: collection_4, tableController, parentCollectionIds: parentCollectionIds ?? [] }, `plugin_header_action_${i}`);
24756
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: customizationController.plugins.filter((plugin_0) => plugin_0.collectionView?.HeaderAction).map((plugin_1, i) => {
24757
+ const HeaderAction = plugin_1.collectionView.HeaderAction;
24758
+ return /* @__PURE__ */ jsxRuntime.jsx(HeaderAction, { onHover, propertyKey: propertyKey_1, property: property_2, fullPath, collection: collection_4, tableController, parentCollectionIds: parentCollectionIds ?? [] }, `plugin_header_action_${i}`);
24738
24759
  }) });
24739
24760
  }, [customizationController.plugins, fullPath, parentCollectionIds]);
24740
24761
  const addColumnComponentInternal = AddColumnComponent ? function() {
@@ -24752,11 +24773,22 @@
24752
24773
  parentCollectionIds
24753
24774
  });
24754
24775
  const [viewModePopoverOpen, setViewModePopoverOpen] = React.useState(false);
24755
- const viewModeToggleElement = /* @__PURE__ */ jsxRuntime.jsx(ViewModeToggle, { viewMode, onViewModeChange, kanbanEnabled, hasKanbanConfigPlugin, size: viewMode === "table" ? tableSize : viewMode === "cards" ? cardSize : void 0, onSizeChanged: viewMode === "table" ? onTableSizeChanged : viewMode === "cards" ? setCardSize : void 0, open: viewModePopoverOpen, onOpenChange: setViewModePopoverOpen, kanbanPropertyOptions, selectedKanbanProperty, onKanbanPropertyChange });
24776
+ const viewModeToggleElement = /* @__PURE__ */ jsxRuntime.jsx(ViewModeToggle, { viewMode, onViewModeChange, enabledViews, size: viewMode === "table" ? tableSize : viewMode === "cards" ? cardSize : void 0, onSizeChanged: viewMode === "table" ? onTableSizeChanged : viewMode === "cards" ? setCardSize : void 0, open: viewModePopoverOpen, onOpenChange: setViewModePopoverOpen, kanbanPropertyOptions, selectedKanbanProperty, onKanbanPropertyChange });
24777
+ const pluginErrorView = React.useMemo(() => {
24778
+ const error = tableController.dataLoadingError;
24779
+ if (!error || !customizationController.plugins) return null;
24780
+ for (const plugin_2 of customizationController.plugins) {
24781
+ if (plugin_2.collectionView?.CollectionError) {
24782
+ const CollectionError = plugin_2.collectionView.CollectionError;
24783
+ return /* @__PURE__ */ jsxRuntime.jsx(CollectionError, { path: fullPath, collection, parentCollectionIds, error });
24784
+ }
24785
+ }
24786
+ return null;
24787
+ }, [tableController.dataLoadingError, customizationController.plugins, fullPath, collection, parentCollectionIds]);
24756
24788
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.cls("overflow-hidden h-full w-full rounded-md flex flex-col", className), ref: containerRef, children: [
24757
24789
  countFetcher,
24758
24790
  /* @__PURE__ */ jsxRuntime.jsx(CollectionTableToolbar, { loading: tableController.dataLoading, onTextSearch: textSearchEnabled && textSearchInitialised ? tableController.setSearchString : void 0, onTextSearchClick: textSearchEnabled && !textSearchInitialised ? onTextSearchClick : void 0, textSearchLoading, viewModeToggle: viewModeToggleElement, actionsStart: /* @__PURE__ */ jsxRuntime.jsx(EntityCollectionViewStartActions, { parentCollectionIds: parentCollectionIds ?? [], collection, tableController, path: fullPath, relativePath: collection.path, selectionController: usedSelectionController, collectionEntitiesCount: docsCount, resolvedProperties: resolvedCollection.properties }), actions: /* @__PURE__ */ jsxRuntime.jsx(EntityCollectionViewActions, { parentCollectionIds: parentCollectionIds ?? [], collection, tableController, onMultipleDeleteClick, onNewClick, path: fullPath, relativePath: collection.path, selectionController: usedSelectionController, selectionEnabled, collectionEntitiesCount: docsCount }) }),
24759
- viewMode === "kanban" && (kanbanEnabled || hasKanbanConfigPlugin) ? /* @__PURE__ */ jsxRuntime.jsx(EntityCollectionBoardView, { collection, tableController, fullPath, parentCollectionIds, columnProperty: selectedKanbanProperty, onEntityClick, selectionController: usedSelectionController, selectionEnabled, highlightedEntities: highlightedEntity ? [highlightedEntity] : [], deletedEntities, emptyComponent: canCreateEntities && tableController.filterValues === void 0 && tableController.sortBy === void 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center", children: [
24791
+ tableController.dataLoadingError && pluginErrorView ? pluginErrorView : viewMode === "kanban" && enabledViews.includes("kanban") ? /* @__PURE__ */ jsxRuntime.jsx(EntityCollectionBoardView, { collection, tableController, fullPath, parentCollectionIds, columnProperty: selectedKanbanProperty, onEntityClick, selectionController: usedSelectionController, selectionEnabled, highlightedEntities: highlightedEntity ? [highlightedEntity] : [], deletedEntities, emptyComponent: canCreateEntities && tableController.filterValues === void 0 && tableController.sortBy === void 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center", children: [
24760
24792
  /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "subtitle2", children: "So empty..." }),
24761
24793
  /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { onClick: onNewClick, className: "mt-4", children: [
24762
24794
  /* @__PURE__ */ jsxRuntime.jsx(ui.AddIcon, {}),
@@ -26148,10 +26180,10 @@
26148
26180
  navigationGroupMappings
26149
26181
  } = props;
26150
26182
  const navigate = reactRouterDom.useNavigate();
26151
- const collectionsRef = React.useRef();
26152
- const viewsRef = React.useRef();
26153
- const adminViewsRef = React.useRef();
26154
- const navigationEntriesOrderRef = React.useRef();
26183
+ const collectionsRef = React.useRef(void 0);
26184
+ const viewsRef = React.useRef(void 0);
26185
+ const adminViewsRef = React.useRef(void 0);
26186
+ const navigationEntriesOrderRef = React.useRef(void 0);
26155
26187
  const [initialised, setInitialised] = React.useState(false);
26156
26188
  const [topLevelNavigation, setTopLevelNavigation] = React.useState(void 0);
26157
26189
  const [navigationLoading, setNavigationLoading] = React.useState(true);
@@ -26856,7 +26888,7 @@
26856
26888
  t2 = $[2];
26857
26889
  }
26858
26890
  React.useEffect(t1, t2);
26859
- const checkedUserRef = React.useRef();
26891
+ const checkedUserRef = React.useRef(void 0);
26860
26892
  let t3;
26861
26893
  if ($[3] !== authController || $[4] !== authenticator || $[5] !== dataSourceDelegate || $[6] !== disabled || $[7] !== storageSource) {
26862
26894
  t3 = async () => {
@@ -27185,13 +27217,13 @@
27185
27217
  status,
27186
27218
  values
27187
27219
  }) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
27188
- /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { className: "self-center", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(ui.CloseIcon, { size: "small" }) }),
27189
- allowFullScreen && /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { className: "self-center", onClick: () => {
27220
+ /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { className: "self-center", size: "smallest", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(ui.CloseIcon, { size: "smallest" }) }),
27221
+ allowFullScreen && /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { className: "self-center", size: "smallest", onClick: () => {
27190
27222
  const key = status === "new" || status === "copy" ? path + "#new" : path + "/" + entityId;
27191
27223
  saveEntityToMemoryCache(key, values);
27192
27224
  if (entityId) navigate(location.pathname);
27193
27225
  else navigate(location.pathname + "#new");
27194
- }, children: /* @__PURE__ */ jsxRuntime.jsx(ui.OpenInFullIcon, { size: "small" }) })
27226
+ }, children: /* @__PURE__ */ jsxRuntime.jsx(ui.OpenInFullIcon, { size: "smallest" }) })
27195
27227
  ] }), onTabChange: ({
27196
27228
  entityId: entityId_0,
27197
27229
  selectedTab,
@@ -28467,7 +28499,7 @@
28467
28499
  const orderProperty = collection_3?.orderProperty;
28468
28500
  if (orderProperty && (status === "new" || status === "copy")) {
28469
28501
  const orderProp = properties?.[orderProperty];
28470
- if (orderProp?.disabled === true) {
28502
+ if (orderProp) {
28471
28503
  const currentValue = updatedValues[orderProperty];
28472
28504
  if (currentValue === void 0 || currentValue === null) {
28473
28505
  try {
@@ -29688,14 +29720,19 @@
29688
29720
  return "custom_array";
29689
29721
  } else if (isPropertyBuilder(of)) {
29690
29722
  return "repeat";
29691
- } else if (of?.dataType === "string" && of.enumValues) {
29692
- return "multi_select";
29693
- } else if (of?.dataType === "number" && of.enumValues) {
29694
- return "multi_number_select";
29695
- } else if (of?.dataType === "string" && of.storage) {
29696
- return "multi_file_upload";
29697
- } else if (of?.dataType === "reference") {
29698
- return "multi_references";
29723
+ } else if (of) {
29724
+ const ofProperty = of;
29725
+ if (ofProperty.dataType === "string" && ofProperty.enumValues) {
29726
+ return "multi_select";
29727
+ } else if (ofProperty.dataType === "number" && ofProperty.enumValues) {
29728
+ return "multi_number_select";
29729
+ } else if (ofProperty.dataType === "string" && ofProperty.storage) {
29730
+ return "multi_file_upload";
29731
+ } else if (ofProperty.dataType === "reference") {
29732
+ return "multi_references";
29733
+ } else {
29734
+ return "repeat";
29735
+ }
29699
29736
  } else {
29700
29737
  return "repeat";
29701
29738
  }