@firecms/core 3.1.0-canary.1df3b2c → 3.1.0-canary.768c91f

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 (47) 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 +249 -210
  7. package/dist/index.es.js.map +1 -1
  8. package/dist/index.umd.js +248 -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 +9 -9
  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/join_collections.ts +10 -8
  45. package/src/util/previews.ts +2 -2
  46. package/src/util/property_utils.tsx +1 -1
  47. 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;
@@ -3824,6 +3824,8 @@
3824
3824
  return resultCollection;
3825
3825
  }
3826
3826
  function mergePropertyOrBuilder(target, source) {
3827
+ if (!source) return target;
3828
+ if (!target) return source;
3827
3829
  if (isPropertyBuilder(source)) {
3828
3830
  return source;
3829
3831
  } else if (isPropertyBuilder(target)) {
@@ -7577,7 +7579,7 @@
7577
7579
  } else {
7578
7580
  if (property.dataType === "map") {
7579
7581
  if (typeof value === "object") {
7580
- content = /* @__PURE__ */ jsxRuntime.jsx(MapPropertyPreview, { ...props, property });
7582
+ content = /* @__PURE__ */ jsxRuntime.jsx(MapPropertyPreview, { ...props, value, property });
7581
7583
  } else {
7582
7584
  content = buildWrongValueType(propertyKey, property.dataType, value);
7583
7585
  }
@@ -8461,7 +8463,7 @@
8461
8463
  const handleOpenChange = t4;
8462
8464
  let t5;
8463
8465
  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)) });
8466
+ 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
8467
  $[11] = disabled;
8466
8468
  $[12] = enumValues;
8467
8469
  $[13] = internalValue;
@@ -9021,7 +9023,7 @@
9021
9023
  openPopup(cellRect);
9022
9024
  }
9023
9025
  }, []);
9024
- const iconRef = React.useRef();
9026
+ const iconRef = React.useRef(void 0);
9025
9027
  React.useEffect(() => {
9026
9028
  if (iconRef.current && selected) {
9027
9029
  iconRef.current.focus({
@@ -12169,7 +12171,7 @@
12169
12171
  onColumnResize(params_0);
12170
12172
  }
12171
12173
  }, [columns, onColumnResize]);
12172
- const filterRef = React.useRef();
12174
+ const filterRef = React.useRef(void 0);
12173
12175
  React.useEffect(() => {
12174
12176
  filterRef.current = filterInput;
12175
12177
  }, [filterInput]);
@@ -12281,7 +12283,7 @@
12281
12283
  return tableContent;
12282
12284
  }, equal);
12283
12285
  const SortableCellWrapper = (t0) => {
12284
- const $ = reactCompilerRuntime.c(15);
12286
+ const $ = reactCompilerRuntime.c(17);
12285
12287
  const {
12286
12288
  columnKey,
12287
12289
  width,
@@ -12309,10 +12311,22 @@
12309
12311
  transform,
12310
12312
  transition
12311
12313
  } = sortable.useSortable(t2);
12314
+ let attrsWithoutTabIndex;
12315
+ if ($[3] !== attributes) {
12316
+ const {
12317
+ tabIndex: _tabIndex,
12318
+ ...t32
12319
+ } = attributes;
12320
+ attrsWithoutTabIndex = t32;
12321
+ $[3] = attributes;
12322
+ $[4] = attrsWithoutTabIndex;
12323
+ } else {
12324
+ attrsWithoutTabIndex = $[4];
12325
+ }
12312
12326
  const t3 = transform ? `translateX(${transform.x}px)` : void 0;
12313
12327
  const t4 = isDragging ? void 0 : transition;
12314
12328
  let t5;
12315
- if ($[3] !== t3 || $[4] !== t4 || $[5] !== width) {
12329
+ if ($[5] !== t3 || $[6] !== t4 || $[7] !== width) {
12316
12330
  t5 = {
12317
12331
  transform: t3,
12318
12332
  transition: t4,
@@ -12320,34 +12334,34 @@
12320
12334
  maxWidth: width,
12321
12335
  width
12322
12336
  };
12323
- $[3] = t3;
12324
- $[4] = t4;
12325
- $[5] = width;
12326
- $[6] = t5;
12337
+ $[5] = t3;
12338
+ $[6] = t4;
12339
+ $[7] = width;
12340
+ $[8] = t5;
12327
12341
  } else {
12328
- t5 = $[6];
12342
+ t5 = $[8];
12329
12343
  }
12330
12344
  const style = t5;
12331
12345
  const t6 = frozen && "sticky left-0 z-10 bg-white dark:bg-surface-950";
12332
12346
  let t7;
12333
- if ($[7] !== t6) {
12347
+ if ($[9] !== t6) {
12334
12348
  t7 = ui.cls("flex-shrink-0", t6);
12335
- $[7] = t6;
12336
- $[8] = t7;
12349
+ $[9] = t6;
12350
+ $[10] = t7;
12337
12351
  } else {
12338
- t7 = $[8];
12352
+ t7 = $[10];
12339
12353
  }
12340
12354
  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;
12355
+ if ($[11] !== attrsWithoutTabIndex || $[12] !== children || $[13] !== setNodeRef || $[14] !== style || $[15] !== t7) {
12356
+ t8 = /* @__PURE__ */ jsxRuntime.jsx("div", { ref: setNodeRef, style, className: t7, ...attrsWithoutTabIndex, children });
12357
+ $[11] = attrsWithoutTabIndex;
12358
+ $[12] = children;
12359
+ $[13] = setNodeRef;
12360
+ $[14] = style;
12361
+ $[15] = t7;
12362
+ $[16] = t8;
12349
12363
  } else {
12350
- t8 = $[14];
12364
+ t8 = $[16];
12351
12365
  }
12352
12366
  return t8;
12353
12367
  };
@@ -16250,7 +16264,7 @@
16250
16264
  size = "m"
16251
16265
  }) {
16252
16266
  const authController = useAuthController();
16253
- useAnalyticsController();
16267
+ const analyticsController = useAnalyticsController();
16254
16268
  useSideEntityController();
16255
16269
  const customizationController = useCustomizationController();
16256
16270
  useNavigationController();
@@ -16277,6 +16291,10 @@
16277
16291
  return;
16278
16292
  }
16279
16293
  if (onClick) {
16294
+ analyticsController.onAnalyticsEvent?.("card_view_entity_click", {
16295
+ path: entity.path,
16296
+ entityId: entity.id
16297
+ });
16280
16298
  onClick(entity);
16281
16299
  }
16282
16300
  };
@@ -17563,7 +17581,7 @@
17563
17581
  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
17582
  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
17583
  /* @__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 }) }),
17584
+ /* @__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
17585
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-surface-500 font-mono truncate", children: entity.id })
17568
17586
  ] }),
17569
17587
  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 +17937,7 @@
17919
17937
  const context = useFireCMSContext();
17920
17938
  const dataSource = useDataSource();
17921
17939
  const sideEntityController = useSideEntityController();
17940
+ const analyticsController = useAnalyticsController();
17922
17941
  const plugins = customizationController.plugins ?? [];
17923
17942
  const [showBackfillDialog, setShowBackfillDialog] = React.useState(false);
17924
17943
  const [backfillLoading, setBackfillLoading] = React.useState(false);
@@ -18034,6 +18053,10 @@
18034
18053
  return plugins.some((plugin) => plugin.collectionView?.onKanbanColumnsReorder);
18035
18054
  }, [plugins]);
18036
18055
  const handleColumnReorder = React.useCallback((newColumns) => {
18056
+ analyticsController.onAnalyticsEvent?.("kanban_column_reorder", {
18057
+ path: fullPath,
18058
+ columnProperty
18059
+ });
18037
18060
  setHasUserReordered(true);
18038
18061
  setLocalColumnsOrder(newColumns);
18039
18062
  plugins.filter((plugin_0) => plugin_0.collectionView?.onKanbanColumnsReorder).forEach((plugin_1) => {
@@ -18045,7 +18068,7 @@
18045
18068
  newColumnsOrder: newColumns
18046
18069
  });
18047
18070
  });
18048
- }, [plugins, fullPath, parentCollectionIds, collection, columnProperty]);
18071
+ }, [plugins, fullPath, parentCollectionIds, collection, columnProperty, analyticsController]);
18049
18072
  const [missingOrderCount, setMissingOrderCount] = React.useState(0);
18050
18073
  const dataSourceRef = React.useRef(dataSource);
18051
18074
  const collectionRef = React.useRef(collection);
@@ -18157,6 +18180,12 @@
18157
18180
  const handleItemsReorder = React.useCallback(async (items_0, moveInfo) => {
18158
18181
  const entity_2 = items_0.find((item_5) => item_5.id === moveInfo?.itemId)?.entity;
18159
18182
  if (!entity_2) return;
18183
+ analyticsController.onAnalyticsEvent?.("kanban_card_moved", {
18184
+ path: fullPath,
18185
+ entityId: entity_2.id,
18186
+ sourceColumn: moveInfo?.sourceColumn,
18187
+ targetColumn: moveInfo?.targetColumn
18188
+ });
18160
18189
  const isColumnChange = moveInfo && moveInfo.sourceColumn !== moveInfo.targetColumn;
18161
18190
  if (!orderProperty && !isColumnChange) return;
18162
18191
  if (isColumnChange) {
@@ -18194,7 +18223,7 @@
18194
18223
  } catch (e_1) {
18195
18224
  console.error("Error saving entity:", e_1);
18196
18225
  }
18197
- }, [collection, columnProperty, orderProperty, context, dataSource, calculateNewOrder, boardDataController]);
18226
+ }, [collection, columnProperty, orderProperty, context, dataSource, calculateNewOrder, boardDataController, analyticsController, fullPath]);
18198
18227
  const handleBackfill = React.useCallback(async () => {
18199
18228
  console.log("handleBackfill called", {
18200
18229
  orderProperty
@@ -18203,6 +18232,9 @@
18203
18232
  console.log("No orderProperty, returning");
18204
18233
  return;
18205
18234
  }
18235
+ analyticsController.onAnalyticsEvent?.("kanban_backfill_order", {
18236
+ path: fullPath
18237
+ });
18206
18238
  setBackfillLoading(true);
18207
18239
  try {
18208
18240
  console.log("Fetching all documents from collection...");
@@ -18256,7 +18288,7 @@
18256
18288
  } finally {
18257
18289
  setBackfillLoading(false);
18258
18290
  }
18259
- }, [orderProperty, fullPath, collection, dataSource, context, boardDataController]);
18291
+ }, [orderProperty, fullPath, collection, dataSource, context, boardDataController, analyticsController]);
18260
18292
  const handleEntityClick = React.useCallback((entity_5) => {
18261
18293
  onEntityClick?.(entity_5);
18262
18294
  }, [onEntityClick]);
@@ -18317,6 +18349,10 @@
18317
18349
  /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "text", onClick: () => setShowBackfillDialog(true), children: "Initialize Order" })
18318
18350
  ] }),
18319
18351
  /* @__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) => {
18352
+ analyticsController.onAnalyticsEvent?.("kanban_new_entity_in_column", {
18353
+ path: fullPath,
18354
+ column: column_0
18355
+ });
18320
18356
  sideEntityController.open({
18321
18357
  path: fullPath,
18322
18358
  collection,
@@ -18341,13 +18377,13 @@
18341
18377
  ] })
18342
18378
  ] });
18343
18379
  }
18380
+ const ALL_VIEW_MODES = ["table", "cards", "kanban"];
18344
18381
  function ViewModeToggle(t0) {
18345
- const $ = reactCompilerRuntime.c(42);
18382
+ const $ = reactCompilerRuntime.c(36);
18346
18383
  const {
18347
18384
  viewMode: t1,
18348
18385
  onViewModeChange,
18349
- kanbanEnabled: t2,
18350
- hasKanbanConfigPlugin: t3,
18386
+ enabledViews: t2,
18351
18387
  size,
18352
18388
  onSizeChanged,
18353
18389
  open,
@@ -18357,14 +18393,13 @@
18357
18393
  onKanbanPropertyChange
18358
18394
  } = t0;
18359
18395
  const viewMode = t1 === void 0 ? "table" : t1;
18360
- const kanbanEnabled = t2 === void 0 ? false : t2;
18361
- const hasKanbanConfigPlugin = t3 === void 0 ? false : t3;
18396
+ const enabledViews = t2 === void 0 ? ALL_VIEW_MODES : t2;
18362
18397
  if (!onViewModeChange) {
18363
18398
  return null;
18364
18399
  }
18365
- let t4;
18400
+ let t3;
18366
18401
  if ($[0] !== viewMode) {
18367
- t4 = () => {
18402
+ t3 = () => {
18368
18403
  if (viewMode === "kanban") {
18369
18404
  return /* @__PURE__ */ jsxRuntime.jsx(ui.ViewKanbanIcon, { size: "small" });
18370
18405
  }
@@ -18374,14 +18409,14 @@
18374
18409
  return /* @__PURE__ */ jsxRuntime.jsx(ui.ListIcon, { size: "small" });
18375
18410
  };
18376
18411
  $[0] = viewMode;
18377
- $[1] = t4;
18412
+ $[1] = t3;
18378
18413
  } else {
18379
- t4 = $[1];
18414
+ t3 = $[1];
18380
18415
  }
18381
- const getViewModeIcon = t4;
18382
- let t5;
18416
+ const getViewModeIcon = t3;
18417
+ let t4;
18383
18418
  if ($[2] !== viewMode) {
18384
- t5 = () => {
18419
+ t4 = () => {
18385
18420
  if (viewMode === "kanban") {
18386
18421
  return "Board";
18387
18422
  }
@@ -18391,177 +18426,151 @@
18391
18426
  return "List";
18392
18427
  };
18393
18428
  $[2] = viewMode;
18394
- $[3] = t5;
18429
+ $[3] = t4;
18395
18430
  } else {
18396
- t5 = $[3];
18431
+ t4 = $[3];
18397
18432
  }
18398
- const getViewModeName = t5;
18399
- const showKanban = kanbanEnabled || hasKanbanConfigPlugin;
18433
+ const getViewModeName = t4;
18400
18434
  const showSizeSelector = size && onSizeChanged && (viewMode === "table" || viewMode === "cards");
18401
18435
  const showKanbanPropertySelector = viewMode === "kanban" && kanbanPropertyOptions && kanbanPropertyOptions.length > 0 && onKanbanPropertyChange;
18436
+ let t5;
18402
18437
  let t6;
18403
- let t7;
18404
18438
  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;
18439
+ t6 = /* @__PURE__ */ jsxRuntime.jsx(ui.ListIcon, { size: "small" });
18440
+ $[4] = t6;
18411
18441
  } else {
18412
- t7 = $[4];
18442
+ t6 = $[4];
18413
18443
  }
18414
- let t8;
18415
- if ($[5] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
18416
- t8 = {
18444
+ let t7;
18445
+ if ($[5] !== enabledViews) {
18446
+ const allOptions = [{
18447
+ value: "table",
18448
+ label: "List",
18449
+ icon: t6
18450
+ }, {
18417
18451
  value: "cards",
18418
18452
  label: "Cards",
18419
18453
  icon: /* @__PURE__ */ jsxRuntime.jsx(ui.AppsIcon, { size: "small" })
18420
- };
18421
- $[5] = t8;
18454
+ }, {
18455
+ value: "kanban",
18456
+ label: "Board",
18457
+ icon: /* @__PURE__ */ jsxRuntime.jsx(ui.ViewKanbanIcon, { size: "small" })
18458
+ }];
18459
+ t7 = allOptions.filter((option) => enabledViews.includes(option.value));
18460
+ $[5] = enabledViews;
18461
+ $[6] = t7;
18422
18462
  } else {
18423
- t8 = $[5];
18463
+ t7 = $[6];
18424
18464
  }
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;
18465
+ t5 = t7;
18466
+ const viewModeOptions = t5;
18467
+ if (viewModeOptions.length <= 1 && !showSizeSelector) {
18468
+ return null;
18469
+ }
18470
+ let t8;
18471
+ if ($[7] !== getViewModeIcon) {
18472
+ t8 = getViewModeIcon();
18473
+ $[7] = getViewModeIcon;
18474
+ $[8] = t8;
18456
18475
  } else {
18457
- options = $[9];
18476
+ t8 = $[8];
18458
18477
  }
18459
- t6 = options;
18460
- const viewModeOptions = t6;
18461
- let t9;
18462
- if ($[13] !== getViewModeIcon) {
18463
- t9 = getViewModeIcon();
18464
- $[13] = getViewModeIcon;
18465
- $[14] = t9;
18478
+ const t9 = getViewModeName();
18479
+ let t10;
18480
+ if ($[9] !== t9) {
18481
+ t10 = /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 text-sm", children: t9 });
18482
+ $[9] = t9;
18483
+ $[10] = t10;
18466
18484
  } else {
18467
- t9 = $[14];
18485
+ t10 = $[10];
18468
18486
  }
18469
- const t10 = getViewModeName();
18470
18487
  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;
18488
+ if ($[11] !== t10 || $[12] !== t8) {
18489
+ t11 = /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { size: "small", children: [
18490
+ t8,
18491
+ t10
18492
+ ] });
18493
+ $[11] = t10;
18494
+ $[12] = t8;
18495
+ $[13] = t11;
18475
18496
  } else {
18476
- t11 = $[16];
18497
+ t11 = $[13];
18477
18498
  }
18478
18499
  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;
18500
+ if ($[14] !== onViewModeChange || $[15] !== viewMode || $[16] !== viewModeOptions) {
18501
+ t12 = viewModeOptions.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(ui.ToggleButtonGroup, { value: viewMode, onValueChange: onViewModeChange, options: viewModeOptions });
18502
+ $[14] = onViewModeChange;
18503
+ $[15] = viewMode;
18504
+ $[16] = viewModeOptions;
18505
+ $[17] = t12;
18487
18506
  } else {
18488
- t12 = $[19];
18507
+ t12 = $[17];
18489
18508
  }
18490
18509
  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: [
18510
+ if ($[18] !== onSizeChanged || $[19] !== showSizeSelector || $[20] !== size) {
18511
+ t13 = showSizeSelector && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-row items-center justify-between gap-2", children: [
18503
18512
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm text-surface-600 dark:text-surface-300", children: [
18504
18513
  /* @__PURE__ */ jsxRuntime.jsx(ui.ViewColumnIcon, { size: "small" }),
18505
18514
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Size" })
18506
18515
  ] }),
18507
18516
  /* @__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
18517
  ] });
18509
- $[24] = onSizeChanged;
18510
- $[25] = showSizeSelector;
18511
- $[26] = size;
18512
- $[27] = t14;
18518
+ $[18] = onSizeChanged;
18519
+ $[19] = showSizeSelector;
18520
+ $[20] = size;
18521
+ $[21] = t13;
18513
18522
  } else {
18514
- t14 = $[27];
18523
+ t13 = $[21];
18515
18524
  }
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: [
18525
+ let t14;
18526
+ if ($[22] !== kanbanPropertyOptions || $[23] !== onKanbanPropertyChange || $[24] !== selectedKanbanProperty || $[25] !== showKanbanPropertySelector) {
18527
+ t14 = showKanbanPropertySelector && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-row items-center justify-between gap-2", children: [
18519
18528
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm text-surface-600 dark:text-surface-300", children: [
18520
18529
  /* @__PURE__ */ jsxRuntime.jsx(ui.ViewKanbanIcon, { size: "small" }),
18521
18530
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Group by" })
18522
18531
  ] }),
18523
18532
  /* @__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 });
18533
+ const option_0 = kanbanPropertyOptions?.find((o) => o.key === v_2);
18534
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium truncate", children: option_0?.label ?? v_2 });
18526
18535
  }, children: kanbanPropertyOptions?.map(_temp3$3) })
18527
18536
  ] });
18528
- $[28] = kanbanPropertyOptions;
18529
- $[29] = onKanbanPropertyChange;
18530
- $[30] = selectedKanbanProperty;
18531
- $[31] = showKanbanPropertySelector;
18532
- $[32] = t15;
18537
+ $[22] = kanbanPropertyOptions;
18538
+ $[23] = onKanbanPropertyChange;
18539
+ $[24] = selectedKanbanProperty;
18540
+ $[25] = showKanbanPropertySelector;
18541
+ $[26] = t14;
18533
18542
  } else {
18534
- t15 = $[32];
18543
+ t14 = $[26];
18535
18544
  }
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: [
18545
+ let t15;
18546
+ if ($[27] !== t12 || $[28] !== t13 || $[29] !== t14) {
18547
+ t15 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-3 flex flex-col gap-3 min-w-[240px]", children: [
18548
+ t12,
18539
18549
  t13,
18540
- t14,
18541
- t15
18550
+ t14
18542
18551
  ] });
18543
- $[33] = t13;
18544
- $[34] = t14;
18545
- $[35] = t15;
18546
- $[36] = t16;
18552
+ $[27] = t12;
18553
+ $[28] = t13;
18554
+ $[29] = t14;
18555
+ $[30] = t15;
18547
18556
  } else {
18548
- t16 = $[36];
18557
+ t15 = $[30];
18549
18558
  }
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;
18559
+ let t16;
18560
+ if ($[31] !== onOpenChange || $[32] !== open || $[33] !== t11 || $[34] !== t15) {
18561
+ t16 = /* @__PURE__ */ jsxRuntime.jsx(ui.Popover, { open, onOpenChange, modal: true, trigger: t11, children: t15 });
18562
+ $[31] = onOpenChange;
18563
+ $[32] = open;
18564
+ $[33] = t11;
18565
+ $[34] = t15;
18566
+ $[35] = t16;
18558
18567
  } else {
18559
- t17 = $[41];
18568
+ t16 = $[35];
18560
18569
  }
18561
- return t17;
18570
+ return t16;
18562
18571
  }
18563
- function _temp3$3(option_0) {
18564
- return /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: option_0.key, children: option_0.label }, option_0.key);
18572
+ function _temp3$3(option_1) {
18573
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: option_1.key, children: option_1.label }, option_1.key);
18565
18574
  }
18566
18575
  function _temp2$5(s) {
18567
18576
  return /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: s, className: "font-medium text-center", children: s.toUpperCase() }, s);
@@ -19508,6 +19517,7 @@
19508
19517
  console.error(error);
19509
19518
  }, [snackbarController]);
19510
19519
  const pluginActions = [];
19520
+ const pluginBeforeTitle = [];
19511
19521
  const plugins = customizationController.plugins;
19512
19522
  const actionsDisabled = disabled || formex$1.isSubmitting || status === "existing" && !formex$1.dirty || Boolean(disabledProp);
19513
19523
  const parentCollectionIds = navigationController.getParentCollectionIds(path);
@@ -19524,6 +19534,7 @@
19524
19534
  disabled: actionsDisabled
19525
19535
  };
19526
19536
  pluginActions.push(...plugins.map((plugin) => plugin.form?.Actions ? /* @__PURE__ */ jsxRuntime.jsx(plugin.form.Actions, { ...actionProps }, `actions_${plugin.key}`) : null).filter(Boolean));
19537
+ 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
19538
  }
19528
19539
  const titlePropertyKey = getEntityTitlePropertyKey(resolvedCollection, customizationController.propertyConfigs);
19529
19540
  const title = (formex$1.values && titlePropertyKey ? getValueInPath(formex$1.values, titlePropertyKey) : void 0) ?? collection.singularName ?? collection.name;
@@ -19620,6 +19631,7 @@
19620
19631
  };
19621
19632
  const formRef = React.useRef(null);
19622
19633
  const formView = /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { children: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
19634
+ pluginBeforeTitle,
19623
19635
  !Builder && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full py-2 flex flex-col items-start my-4 lg:my-6", children: [
19624
19636
  /* @__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
19637
  !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 +21889,7 @@
21877
21889
  index,
21878
21890
  authController
21879
21891
  });
21880
- Component = configProperty.Field;
21892
+ Component = configProperty?.Field;
21881
21893
  }
21882
21894
  }
21883
21895
  }
@@ -24502,13 +24514,18 @@
24502
24514
  });
24503
24515
  }, [onCollectionModifiedForUser, fullPath, userConfigPersistence]);
24504
24516
  const onViewModeChange = React.useCallback((mode) => {
24517
+ analyticsController.onAnalyticsEvent?.("view_mode_changed", {
24518
+ path: fullPath,
24519
+ from: viewMode,
24520
+ to: mode
24521
+ });
24505
24522
  setViewMode(mode);
24506
24523
  if (userConfigPersistence) {
24507
24524
  onCollectionModifiedForUser(fullPath, {
24508
24525
  defaultViewMode: mode
24509
24526
  });
24510
24527
  }
24511
- }, [setViewMode, userConfigPersistence, onCollectionModifiedForUser, fullPath]);
24528
+ }, [setViewMode, userConfigPersistence, onCollectionModifiedForUser, fullPath, analyticsController, viewMode]);
24512
24529
  const createEnabled = canCreateEntity(collection, authController, fullPath, null);
24513
24530
  const uniqueFieldValidator = React.useCallback(({
24514
24531
  name,
@@ -24562,24 +24579,26 @@
24562
24579
  propertyConfigs: customizationController.propertyConfigs,
24563
24580
  authController
24564
24581
  }), [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]);
24582
+ const hasEnumProperty = React.useMemo(() => {
24583
+ const properties = resolvedCollection.properties;
24584
+ return Object.values(properties).some((prop) => prop && prop.dataType === "string" && prop.enumValues);
24585
+ }, [resolvedCollection.properties]);
24586
+ const enabledViews = React.useMemo(() => {
24587
+ const configured = collection.enabledViews ?? ["table", "cards", "kanban"];
24588
+ if (!hasEnumProperty) {
24589
+ return configured.filter((v) => v !== "kanban");
24590
+ }
24591
+ return configured;
24592
+ }, [collection.enabledViews, hasEnumProperty]);
24574
24593
  const kanbanPropertyOptions = React.useMemo(() => {
24575
24594
  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) {
24595
+ const properties_0 = resolvedCollection.properties;
24596
+ for (const [key_0, property_0] of Object.entries(properties_0)) {
24597
+ const prop_0 = property_0;
24598
+ if (prop_0 && prop_0.dataType === "string" && prop_0.enumValues) {
24580
24599
  options.push({
24581
24600
  key: key_0,
24582
- label: prop.name || key_0
24601
+ label: prop_0.name || key_0
24583
24602
  });
24584
24603
  }
24585
24604
  }
@@ -24607,14 +24626,18 @@
24607
24626
  }
24608
24627
  }
24609
24628
  }, [kanbanPropertyOptions, selectedKanbanProperty, getSavedKanbanProperty, collection.kanban?.columnProperty]);
24610
- const onKanbanPropertyChange = React.useCallback((property_2) => {
24611
- setSelectedKanbanProperty(property_2);
24629
+ const onKanbanPropertyChange = React.useCallback((property_1) => {
24630
+ analyticsController.onAnalyticsEvent?.("kanban_property_changed", {
24631
+ path: fullPath,
24632
+ property: property_1
24633
+ });
24634
+ setSelectedKanbanProperty(property_1);
24612
24635
  if (userConfigPersistence) {
24613
24636
  onCollectionModifiedForUser(fullPath, {
24614
- kanbanColumnProperty: property_2
24637
+ kanbanColumnProperty: property_1
24615
24638
  });
24616
24639
  }
24617
- }, [userConfigPersistence, onCollectionModifiedForUser, fullPath]);
24640
+ }, [userConfigPersistence, onCollectionModifiedForUser, fullPath, analyticsController]);
24618
24641
  const getPropertyFor = React.useCallback(({
24619
24642
  propertyKey: propertyKey_0,
24620
24643
  entity: entity_2
@@ -24726,15 +24749,15 @@
24726
24749
  }, [docsCount, fullPath, breadcrumbs.updateCount]);
24727
24750
  const countFetcher = /* @__PURE__ */ jsxRuntime.jsx(EntitiesCount, { fullPath, collection, filter: tableController.filterValues, sortBy: tableController.sortBy, onCountChange: setDocsCount });
24728
24751
  const buildAdditionalHeaderWidget = React.useCallback(({
24729
- property: property_3,
24752
+ property: property_2,
24730
24753
  propertyKey: propertyKey_1,
24731
24754
  onHover
24732
24755
  }) => {
24733
24756
  const collection_4 = collectionRef.current;
24734
24757
  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}`);
24758
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: customizationController.plugins.filter((plugin_0) => plugin_0.collectionView?.HeaderAction).map((plugin_1, i) => {
24759
+ const HeaderAction = plugin_1.collectionView.HeaderAction;
24760
+ return /* @__PURE__ */ jsxRuntime.jsx(HeaderAction, { onHover, propertyKey: propertyKey_1, property: property_2, fullPath, collection: collection_4, tableController, parentCollectionIds: parentCollectionIds ?? [] }, `plugin_header_action_${i}`);
24738
24761
  }) });
24739
24762
  }, [customizationController.plugins, fullPath, parentCollectionIds]);
24740
24763
  const addColumnComponentInternal = AddColumnComponent ? function() {
@@ -24752,11 +24775,22 @@
24752
24775
  parentCollectionIds
24753
24776
  });
24754
24777
  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 });
24778
+ 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 });
24779
+ const pluginErrorView = React.useMemo(() => {
24780
+ const error = tableController.dataLoadingError;
24781
+ if (!error || !customizationController.plugins) return null;
24782
+ for (const plugin_2 of customizationController.plugins) {
24783
+ if (plugin_2.collectionView?.CollectionError) {
24784
+ const CollectionError = plugin_2.collectionView.CollectionError;
24785
+ return /* @__PURE__ */ jsxRuntime.jsx(CollectionError, { path: fullPath, collection, parentCollectionIds, error });
24786
+ }
24787
+ }
24788
+ return null;
24789
+ }, [tableController.dataLoadingError, customizationController.plugins, fullPath, collection, parentCollectionIds]);
24756
24790
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.cls("overflow-hidden h-full w-full rounded-md flex flex-col", className), ref: containerRef, children: [
24757
24791
  countFetcher,
24758
24792
  /* @__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: [
24793
+ 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
24794
  /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "subtitle2", children: "So empty..." }),
24761
24795
  /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { onClick: onNewClick, className: "mt-4", children: [
24762
24796
  /* @__PURE__ */ jsxRuntime.jsx(ui.AddIcon, {}),
@@ -26148,10 +26182,10 @@
26148
26182
  navigationGroupMappings
26149
26183
  } = props;
26150
26184
  const navigate = reactRouterDom.useNavigate();
26151
- const collectionsRef = React.useRef();
26152
- const viewsRef = React.useRef();
26153
- const adminViewsRef = React.useRef();
26154
- const navigationEntriesOrderRef = React.useRef();
26185
+ const collectionsRef = React.useRef(void 0);
26186
+ const viewsRef = React.useRef(void 0);
26187
+ const adminViewsRef = React.useRef(void 0);
26188
+ const navigationEntriesOrderRef = React.useRef(void 0);
26155
26189
  const [initialised, setInitialised] = React.useState(false);
26156
26190
  const [topLevelNavigation, setTopLevelNavigation] = React.useState(void 0);
26157
26191
  const [navigationLoading, setNavigationLoading] = React.useState(true);
@@ -26856,7 +26890,7 @@
26856
26890
  t2 = $[2];
26857
26891
  }
26858
26892
  React.useEffect(t1, t2);
26859
- const checkedUserRef = React.useRef();
26893
+ const checkedUserRef = React.useRef(void 0);
26860
26894
  let t3;
26861
26895
  if ($[3] !== authController || $[4] !== authenticator || $[5] !== dataSourceDelegate || $[6] !== disabled || $[7] !== storageSource) {
26862
26896
  t3 = async () => {
@@ -27185,13 +27219,13 @@
27185
27219
  status,
27186
27220
  values
27187
27221
  }) => /* @__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: () => {
27222
+ /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { className: "self-center", size: "smallest", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(ui.CloseIcon, { size: "smallest" }) }),
27223
+ allowFullScreen && /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { className: "self-center", size: "smallest", onClick: () => {
27190
27224
  const key = status === "new" || status === "copy" ? path + "#new" : path + "/" + entityId;
27191
27225
  saveEntityToMemoryCache(key, values);
27192
27226
  if (entityId) navigate(location.pathname);
27193
27227
  else navigate(location.pathname + "#new");
27194
- }, children: /* @__PURE__ */ jsxRuntime.jsx(ui.OpenInFullIcon, { size: "small" }) })
27228
+ }, children: /* @__PURE__ */ jsxRuntime.jsx(ui.OpenInFullIcon, { size: "smallest" }) })
27195
27229
  ] }), onTabChange: ({
27196
27230
  entityId: entityId_0,
27197
27231
  selectedTab,
@@ -28467,7 +28501,7 @@
28467
28501
  const orderProperty = collection_3?.orderProperty;
28468
28502
  if (orderProperty && (status === "new" || status === "copy")) {
28469
28503
  const orderProp = properties?.[orderProperty];
28470
- if (orderProp?.disabled === true) {
28504
+ if (orderProp) {
28471
28505
  const currentValue = updatedValues[orderProperty];
28472
28506
  if (currentValue === void 0 || currentValue === null) {
28473
28507
  try {
@@ -29688,14 +29722,19 @@
29688
29722
  return "custom_array";
29689
29723
  } else if (isPropertyBuilder(of)) {
29690
29724
  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";
29725
+ } else if (of) {
29726
+ const ofProperty = of;
29727
+ if (ofProperty.dataType === "string" && ofProperty.enumValues) {
29728
+ return "multi_select";
29729
+ } else if (ofProperty.dataType === "number" && ofProperty.enumValues) {
29730
+ return "multi_number_select";
29731
+ } else if (ofProperty.dataType === "string" && ofProperty.storage) {
29732
+ return "multi_file_upload";
29733
+ } else if (ofProperty.dataType === "reference") {
29734
+ return "multi_references";
29735
+ } else {
29736
+ return "repeat";
29737
+ }
29699
29738
  } else {
29700
29739
  return "repeat";
29701
29740
  }