@firecms/core 3.0.0-canary.234 → 3.0.0-canary.237

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 (37) hide show
  1. package/dist/components/EntityPreview.d.ts +4 -2
  2. package/dist/components/SelectableTable/SelectableTable.d.ts +1 -1
  3. package/dist/components/index.d.ts +1 -0
  4. package/dist/hooks/useBuildNavigationController.d.ts +2 -9
  5. package/dist/index.es.js +266 -138
  6. package/dist/index.es.js.map +1 -1
  7. package/dist/index.umd.js +266 -138
  8. package/dist/index.umd.js.map +1 -1
  9. package/dist/types/collections.d.ts +13 -0
  10. package/dist/types/plugins.d.ts +12 -0
  11. package/dist/types/side_entity_controller.d.ts +4 -0
  12. package/dist/util/callbacks.d.ts +2 -0
  13. package/dist/util/index.d.ts +1 -0
  14. package/package.json +5 -5
  15. package/src/components/ConfirmationDialog.tsx +9 -9
  16. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +1 -1
  17. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +1 -1
  18. package/src/components/EntityPreview.tsx +18 -14
  19. package/src/components/ErrorView.tsx +1 -1
  20. package/src/components/HomePage/DefaultHomePage.tsx +1 -1
  21. package/src/components/SelectableTable/SelectableTable.tsx +140 -143
  22. package/src/components/VirtualTable/VirtualTable.tsx +7 -4
  23. package/src/components/index.tsx +2 -0
  24. package/src/core/EntityEditView.tsx +25 -14
  25. package/src/core/EntitySidePanel.tsx +19 -12
  26. package/src/form/field_bindings/KeyValueFieldBinding.tsx +0 -2
  27. package/src/hooks/useBuildNavigationController.tsx +29 -16
  28. package/src/internal/useBuildSideEntityController.tsx +1 -1
  29. package/src/preview/components/ReferencePreview.tsx +1 -1
  30. package/src/preview/property_previews/ArrayOfMapsPreview.tsx +1 -1
  31. package/src/preview/property_previews/SkeletonPropertyComponent.tsx +1 -1
  32. package/src/types/collections.ts +16 -0
  33. package/src/types/firecms.tsx +0 -1
  34. package/src/types/plugins.tsx +16 -0
  35. package/src/types/side_entity_controller.tsx +5 -5
  36. package/src/util/callbacks.ts +119 -0
  37. package/src/util/index.ts +1 -0
package/dist/index.es.js CHANGED
@@ -3764,6 +3764,108 @@ function replacePlaceholders({
3764
3764
  if (!result) result = randomString() + "_" + file.name;
3765
3765
  return result;
3766
3766
  }
3767
+ const mergeCallbacks = (baseCallbacks = {}, pluginCallbacks = {}) => {
3768
+ if (!baseCallbacks && !pluginCallbacks) {
3769
+ return void 0;
3770
+ }
3771
+ const mergedCallbacks = {};
3772
+ if (baseCallbacks.onFetch || pluginCallbacks.onFetch) {
3773
+ mergedCallbacks.onFetch = async (props) => {
3774
+ let entity = props.entity;
3775
+ if (baseCallbacks.onFetch) {
3776
+ entity = await Promise.resolve(baseCallbacks.onFetch(props));
3777
+ }
3778
+ if (pluginCallbacks.onFetch) {
3779
+ entity = await Promise.resolve(pluginCallbacks.onFetch({
3780
+ ...props,
3781
+ entity
3782
+ }));
3783
+ }
3784
+ return entity;
3785
+ };
3786
+ }
3787
+ if (baseCallbacks.onSaveSuccess || pluginCallbacks.onSaveSuccess) {
3788
+ mergedCallbacks.onSaveSuccess = async (props) => {
3789
+ if (baseCallbacks.onSaveSuccess) {
3790
+ await Promise.resolve(baseCallbacks.onSaveSuccess(props));
3791
+ }
3792
+ if (pluginCallbacks.onSaveSuccess) {
3793
+ await Promise.resolve(pluginCallbacks.onSaveSuccess(props));
3794
+ }
3795
+ };
3796
+ }
3797
+ if (baseCallbacks.onSaveFailure || pluginCallbacks.onSaveFailure) {
3798
+ mergedCallbacks.onSaveFailure = async (props) => {
3799
+ if (baseCallbacks.onSaveFailure) {
3800
+ await Promise.resolve(baseCallbacks.onSaveFailure(props));
3801
+ }
3802
+ if (pluginCallbacks.onSaveFailure) {
3803
+ await Promise.resolve(pluginCallbacks.onSaveFailure(props));
3804
+ }
3805
+ };
3806
+ }
3807
+ if (baseCallbacks.onPreSave || pluginCallbacks.onPreSave) {
3808
+ mergedCallbacks.onPreSave = async (props) => {
3809
+ let values = {
3810
+ ...props.values
3811
+ };
3812
+ if (baseCallbacks.onPreSave) {
3813
+ const baseValues = await Promise.resolve(baseCallbacks.onPreSave(props));
3814
+ values = {
3815
+ ...values,
3816
+ ...baseValues
3817
+ };
3818
+ }
3819
+ if (pluginCallbacks.onPreSave) {
3820
+ const pluginValues = await Promise.resolve(pluginCallbacks.onPreSave({
3821
+ ...props,
3822
+ values
3823
+ }));
3824
+ values = {
3825
+ ...values,
3826
+ ...pluginValues
3827
+ };
3828
+ }
3829
+ return values;
3830
+ };
3831
+ }
3832
+ if (baseCallbacks.onPreDelete || pluginCallbacks.onPreDelete) {
3833
+ mergedCallbacks.onPreDelete = (props) => {
3834
+ if (baseCallbacks.onPreDelete) {
3835
+ baseCallbacks.onPreDelete(props);
3836
+ }
3837
+ if (pluginCallbacks.onPreDelete) {
3838
+ pluginCallbacks.onPreDelete(props);
3839
+ }
3840
+ };
3841
+ }
3842
+ if (baseCallbacks.onDelete || pluginCallbacks.onDelete) {
3843
+ mergedCallbacks.onDelete = (props) => {
3844
+ if (baseCallbacks.onDelete) {
3845
+ baseCallbacks.onDelete(props);
3846
+ }
3847
+ if (pluginCallbacks.onDelete) {
3848
+ pluginCallbacks.onDelete(props);
3849
+ }
3850
+ };
3851
+ }
3852
+ if (baseCallbacks.onIdUpdate || pluginCallbacks.onIdUpdate) {
3853
+ mergedCallbacks.onIdUpdate = async (props) => {
3854
+ let id = props.entityId || "";
3855
+ if (baseCallbacks.onIdUpdate) {
3856
+ id = await Promise.resolve(baseCallbacks.onIdUpdate(props));
3857
+ }
3858
+ if (pluginCallbacks.onIdUpdate) {
3859
+ id = await Promise.resolve(pluginCallbacks.onIdUpdate({
3860
+ ...props,
3861
+ entityId: id
3862
+ }));
3863
+ }
3864
+ return id;
3865
+ };
3866
+ }
3867
+ return Object.keys(mergedCallbacks).length > 0 ? mergedCallbacks : void 0;
3868
+ };
3767
3869
  const CONTAINER_FULL_WIDTH = "100vw";
3768
3870
  const ADDITIONAL_TAB_WIDTH = "55vw";
3769
3871
  const FORM_CONTAINER_WIDTH = "768px";
@@ -4656,7 +4758,6 @@ function ErrorView(t0) {
4656
4758
  tooltip
4657
4759
  } = t0;
4658
4760
  const component = error instanceof Error ? error.message : error;
4659
- console.warn("ErrorView", error);
4660
4761
  let t1;
4661
4762
  if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
4662
4763
  t1 = /* @__PURE__ */ jsx(ErrorIcon, { className: "mx-2", size: "small", color: "error" });
@@ -5194,9 +5295,9 @@ function SkeletonPropertyComponent(t0) {
5194
5295
  } else {
5195
5296
  if (arrayProperty.of.dataType === "map" && arrayProperty.of.properties) {
5196
5297
  let t1;
5197
- if ($[10] !== arrayProperty.of.previewProperties || $[11] !== arrayProperty.of.properties || $[12] !== size) {
5198
- t1 = renderArrayOfMaps(arrayProperty.of.properties, size, arrayProperty.of.previewProperties);
5199
- $[10] = arrayProperty.of.previewProperties;
5298
+ if ($[10] !== arrayProperty.of.previewKeys || $[11] !== arrayProperty.of.properties || $[12] !== size) {
5299
+ t1 = renderArrayOfMaps(arrayProperty.of.properties, size, arrayProperty.of.previewKeys);
5300
+ $[10] = arrayProperty.of.previewKeys;
5200
5301
  $[11] = arrayProperty.of.properties;
5201
5302
  $[12] = size;
5202
5303
  $[13] = t1;
@@ -5683,11 +5784,13 @@ function EntityPreview({
5683
5784
  disabled,
5684
5785
  hover,
5685
5786
  collection: collectionProp,
5686
- previewProperties,
5787
+ previewKeys,
5687
5788
  onClick,
5688
5789
  size,
5689
5790
  includeId = true,
5791
+ includeTitle = true,
5690
5792
  includeEntityLink = true,
5793
+ includeImage = true,
5691
5794
  entity
5692
5795
  }) {
5693
5796
  const authController = useAuthController();
@@ -5706,9 +5809,9 @@ function EntityPreview({
5706
5809
  propertyConfigs: customizationController.propertyConfigs,
5707
5810
  authController
5708
5811
  }), [collection]);
5709
- const listProperties = useMemo(() => getEntityPreviewKeys(authController, resolvedCollection, customizationController.propertyConfigs, previewProperties, size === "medium" || size === "large" ? 3 : 1), [previewProperties, resolvedCollection, size]);
5710
- const titleProperty = getEntityTitlePropertyKey(resolvedCollection, customizationController.propertyConfigs);
5711
- const imagePropertyKey = getEntityImagePreviewPropertyKey(resolvedCollection);
5812
+ const listProperties = useMemo(() => previewKeys ?? getEntityPreviewKeys(authController, resolvedCollection, customizationController.propertyConfigs, previewKeys, size === "medium" || size === "large" ? 3 : 1), [previewKeys, resolvedCollection, size]);
5813
+ const titleProperty = includeTitle ? getEntityTitlePropertyKey(resolvedCollection, customizationController.propertyConfigs) : void 0;
5814
+ const imagePropertyKey = includeImage ? getEntityImagePreviewPropertyKey(resolvedCollection) : void 0;
5712
5815
  const imageProperty = imagePropertyKey ? resolvedCollection.properties[imagePropertyKey] : void 0;
5713
5816
  const usedImageProperty = imageProperty && "of" in imageProperty ? imageProperty.of : imageProperty;
5714
5817
  const restProperties = listProperties.filter((p) => p !== titleProperty && p !== imagePropertyKey);
@@ -5719,18 +5822,17 @@ function EntityPreview({
5719
5822
  usedImageProperty && usedImageValue && /* @__PURE__ */ jsx(PropertyPreview, { property: usedImageProperty, propertyKey: imagePropertyKey, size: "small", value: usedImageValue }),
5720
5823
  (!usedImageProperty || !usedImageValue) && /* @__PURE__ */ jsx(IconForView, { collectionOrView: collection, color: "primary", size, className: "m-auto p-1" })
5721
5824
  ] }),
5722
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col grow-1 w-full m-1 shrink-1", style: {
5723
- "maxWidth": "calc(100% - 96px)"
5724
- }, children: [
5825
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col grow w-full m-1 shrink min-w-0", children: [
5725
5826
  size !== "small" && includeId && (entity ? /* @__PURE__ */ jsx("div", { className: "block whitespace-nowrap overflow-hidden truncate", children: /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "disabled", className: "font-mono", children: entity.id }) }) : /* @__PURE__ */ jsx(Skeleton, {})),
5726
5827
  titleProperty && /* @__PURE__ */ jsx("div", { className: "truncate my-0.5 text-sm font-medium", children: entity ? /* @__PURE__ */ jsx(PropertyPreview, { propertyKey: titleProperty, value: getValueInPath(entity.values, titleProperty), property: resolvedCollection.properties[titleProperty], size: "large" }) : /* @__PURE__ */ jsx(SkeletonPropertyComponent, { property: resolvedCollection.properties[titleProperty], size: "large" }) }),
5727
5828
  restProperties && restProperties.map((key) => {
5728
- const childProperty = resolvedCollection.properties[key];
5829
+ const childProperty = getPropertyInPath(resolvedCollection.properties, key);
5729
5830
  if (!childProperty) return null;
5730
- return /* @__PURE__ */ jsx("div", { className: cls("truncate", restProperties.length > 1 ? "my-0.5" : "my-0"), children: entity ? /* @__PURE__ */ jsx(PropertyPreview, { propertyKey: key, value: getValueInPath(entity.values, key), property: childProperty, size: "small" }) : /* @__PURE__ */ jsx(SkeletonPropertyComponent, { property: childProperty, size: "small" }) }, "ref_prev_" + key);
5831
+ const valueInPath = getValueInPath(entity.values, key);
5832
+ return /* @__PURE__ */ jsx("div", { className: cls("truncate", restProperties.length > 1 ? "my-0.5" : "my-0"), children: entity ? /* @__PURE__ */ jsx(PropertyPreview, { propertyKey: key, value: valueInPath, property: childProperty, size: "small" }) : /* @__PURE__ */ jsx(SkeletonPropertyComponent, { property: childProperty, size: "small" }) }, "ref_prev_" + key);
5731
5833
  })
5732
5834
  ] }),
5733
- entity && includeEntityLink && /* @__PURE__ */ jsx(Tooltip, { title: `See details for ${entity.id}`, className: "shrink-0", children: /* @__PURE__ */ jsx(IconButton, { color: "inherit", size: "medium", className: size !== "small" ? "self-start" : "", onClick: (e) => {
5835
+ entity && includeEntityLink && /* @__PURE__ */ jsx(Tooltip, { title: `See details for ${entity.id}`, className: "shrink-0", children: /* @__PURE__ */ jsx(IconButton, { color: "inherit", size: "small", className: size !== "small" ? "self-start" : "", onClick: (e) => {
5734
5836
  e.stopPropagation();
5735
5837
  analyticsController.onAnalyticsEvent?.("entity_click_from_reference", {
5736
5838
  path: entity.path,
@@ -5742,7 +5844,7 @@ function EntityPreview({
5742
5844
  collection,
5743
5845
  updateUrl: true
5744
5846
  });
5745
- }, children: /* @__PURE__ */ jsx(KeyboardTabIcon, { size: "medium" }) }) }),
5847
+ }, children: /* @__PURE__ */ jsx(KeyboardTabIcon, { size: "small" }) }) }),
5746
5848
  actions
5747
5849
  ] });
5748
5850
  }
@@ -6078,7 +6180,7 @@ function ReferencePreviewExisting(t0) {
6078
6180
  }
6079
6181
  let t3;
6080
6182
  if ($[25] !== collection || $[26] !== disabled || $[27] !== hover || $[28] !== includeEntityLink || $[29] !== includeId || $[30] !== onClick || $[31] !== previewProperties || $[32] !== size || $[33] !== usedEntity) {
6081
- t3 = /* @__PURE__ */ jsx(EntityPreview, { size, previewProperties, disabled, entity: usedEntity, collection, onClick, includeEntityLink, includeId, hover });
6183
+ t3 = /* @__PURE__ */ jsx(EntityPreview, { size, previewKeys: previewProperties, disabled, entity: usedEntity, collection, onClick, includeEntityLink, includeId, hover });
6082
6184
  $[25] = collection;
6083
6185
  $[26] = disabled;
6084
6186
  $[27] = hover;
@@ -6926,7 +7028,7 @@ function ArrayOfMapsPreview(t0) {
6926
7028
  throw Error(`You need to specify a 'properties' prop (or specify a custom field) in your map property ${propertyKey}`);
6927
7029
  }
6928
7030
  const values = value;
6929
- const previewProperties = mapProperty.previewProperties;
7031
+ const previewProperties = mapProperty.previewKeys;
6930
7032
  if (!values) {
6931
7033
  t4 = null;
6932
7034
  break bb0;
@@ -9246,7 +9348,7 @@ const PropertyTableCell = React__default.memo(function PropertyTableCell2({
9246
9348
  }
9247
9349
  } else if (arrayProperty.of.dataType === "reference") {
9248
9350
  if (typeof arrayProperty.of.path === "string") {
9249
- innerComponent = /* @__PURE__ */ jsx(TableReferenceField, { name: propertyKey, disabled, internalValue, updateValue, size, multiselect: true, path: arrayProperty.of.path, previewProperties: arrayProperty.of.previewProperties, title: arrayProperty.name, forceFilter: arrayProperty.of.forceFilter, includeId: arrayProperty.of.includeId, includeEntityLink: arrayProperty.of.includeEntityLink });
9351
+ innerComponent = /* @__PURE__ */ jsx(TableReferenceField, { name: propertyKey, disabled, internalValue, updateValue, size, multiselect: true, path: arrayProperty.of.path, previewProperties: arrayProperty.of.previewKeys, title: arrayProperty.name, forceFilter: arrayProperty.of.forceFilter, includeId: arrayProperty.of.includeId, includeEntityLink: arrayProperty.of.includeEntityLink });
9250
9352
  }
9251
9353
  allowScroll = false;
9252
9354
  }
@@ -9509,7 +9611,7 @@ function CollectionTableToolbar(t0) {
9509
9611
  }
9510
9612
  let t6;
9511
9613
  if ($[6] !== t3 || $[7] !== t4) {
9512
- t6 = /* @__PURE__ */ jsx(Tooltip, { title: "Table row size", side: "right", sideOffset: 4, children: /* @__PURE__ */ jsx(Select, { value: t3, className: "w-16 h-10", size: "small", onValueChange: t4, renderValue: _temp$j, children: t5 }) });
9614
+ t6 = /* @__PURE__ */ jsx(Tooltip, { title: "Table row size", side: "right", sideOffset: 4, children: /* @__PURE__ */ jsx(Select, { value: t3, className: "w-16 ml-2", size: "small", onValueChange: t4, renderValue: _temp$j, children: t5 }) });
9513
9615
  $[6] = t3;
9514
9616
  $[7] = t4;
9515
9617
  $[8] = t6;
@@ -10551,8 +10653,8 @@ const VirtualTable = React__default.memo(function VirtualTable2({
10551
10653
  });
10552
10654
  const onColumnResizeInternal = useCallback((params) => {
10553
10655
  if (debug) console.log("onColumnResizeInternal", params);
10554
- setColumns(columns.map((column) => column.key === params.column.key ? params.column : column));
10555
- }, [columns]);
10656
+ setColumns((prevColumns) => prevColumns.map((column) => column.key === params.column.key ? params.column : column));
10657
+ }, []);
10556
10658
  const onColumnResizeEndInternal = useCallback((params_0) => {
10557
10659
  if (debug) console.log("onColumnResizeEndInternal", params_0);
10558
10660
  setColumns(columns.map((column_0) => column_0.key === params_0.column.key ? params_0.column : column_0));
@@ -11310,97 +11412,94 @@ function _temp2$6(op_1) {
11310
11412
  function _temp$g(op_0) {
11311
11413
  return operationLabels[op_0];
11312
11414
  }
11313
- const SelectableTable = React__default.memo(
11314
- function SelectableTable2({
11315
- onValueChange,
11316
- cellRenderer,
11317
- onEntityClick,
11318
- onColumnResize,
11319
- hoverRow = true,
11320
- size = "m",
11321
- inlineEditing = false,
11322
- tableController: {
11323
- data,
11324
- dataLoading,
11325
- noMoreToLoad,
11326
- dataLoadingError,
11327
- filterValues,
11328
- setFilterValues,
11329
- sortBy,
11330
- setSortBy,
11331
- itemCount,
11332
- setItemCount,
11333
- pageSize = 50,
11334
- paginationEnabled,
11335
- checkFilterCombination,
11336
- setPopupCell
11337
- },
11338
- filterable = true,
11339
- onScroll,
11340
- initialScroll,
11341
- emptyComponent,
11342
- columns,
11343
- forceFilter,
11344
- highlightedRow,
11345
- endAdornment,
11346
- AddColumnComponent
11347
- }) {
11348
- const ref = useRef(null);
11349
- const [selectedCell, setSelectedCell] = React__default.useState(void 0);
11350
- const loadNextPage = () => {
11351
- if (!paginationEnabled || dataLoading || noMoreToLoad) return;
11352
- if (itemCount !== void 0) setItemCount?.(itemCount + pageSize);
11353
- };
11354
- const resetPagination = useCallback(() => {
11355
- setItemCount?.(pageSize);
11356
- }, [pageSize]);
11357
- const onRowClick = useCallback(({
11358
- rowData
11359
- }) => {
11360
- if (inlineEditing) return;
11361
- return onEntityClick && onEntityClick(rowData);
11362
- }, [onEntityClick, inlineEditing]);
11363
- useOutsideAlerter(ref, () => {
11364
- if (selectedCell) {
11415
+ const SelectableTable = function SelectableTable2({
11416
+ onValueChange,
11417
+ cellRenderer,
11418
+ onEntityClick,
11419
+ onColumnResize,
11420
+ hoverRow = true,
11421
+ size = "m",
11422
+ inlineEditing = false,
11423
+ tableController: {
11424
+ data,
11425
+ dataLoading,
11426
+ noMoreToLoad,
11427
+ dataLoadingError,
11428
+ filterValues,
11429
+ setFilterValues,
11430
+ sortBy,
11431
+ setSortBy,
11432
+ itemCount,
11433
+ setItemCount,
11434
+ pageSize = 50,
11435
+ paginationEnabled,
11436
+ checkFilterCombination,
11437
+ setPopupCell
11438
+ },
11439
+ filterable = true,
11440
+ onScroll,
11441
+ initialScroll,
11442
+ emptyComponent,
11443
+ columns,
11444
+ forceFilter,
11445
+ highlightedRow,
11446
+ endAdornment,
11447
+ AddColumnComponent
11448
+ }) {
11449
+ const ref = useRef(null);
11450
+ const [selectedCell, setSelectedCell] = React__default.useState(void 0);
11451
+ const loadNextPage = () => {
11452
+ if (!paginationEnabled || dataLoading || noMoreToLoad) return;
11453
+ if (itemCount !== void 0) setItemCount?.(itemCount + pageSize);
11454
+ };
11455
+ const resetPagination = useCallback(() => {
11456
+ setItemCount?.(pageSize);
11457
+ }, [pageSize]);
11458
+ const onRowClick = useCallback(({
11459
+ rowData
11460
+ }) => {
11461
+ if (inlineEditing) return;
11462
+ return onEntityClick && onEntityClick(rowData);
11463
+ }, [onEntityClick, inlineEditing]);
11464
+ useOutsideAlerter(ref, () => {
11465
+ if (selectedCell) {
11466
+ unselect();
11467
+ }
11468
+ }, Boolean(selectedCell));
11469
+ const select = useCallback((cell) => {
11470
+ setSelectedCell(cell);
11471
+ }, []);
11472
+ const unselect = useCallback(() => {
11473
+ setSelectedCell(void 0);
11474
+ }, []);
11475
+ useEffect(() => {
11476
+ const escFunction = (event) => {
11477
+ if (event.keyCode === 27) {
11365
11478
  unselect();
11366
11479
  }
11367
- }, Boolean(selectedCell));
11368
- useEffect(() => {
11369
- const escFunction = (event) => {
11370
- if (event.keyCode === 27) {
11371
- unselect();
11372
- }
11373
- };
11374
- document.addEventListener("keydown", escFunction, false);
11375
- return () => {
11376
- document.removeEventListener("keydown", escFunction, false);
11377
- };
11480
+ };
11481
+ document.addEventListener("keydown", escFunction, false);
11482
+ return () => {
11483
+ document.removeEventListener("keydown", escFunction, false);
11484
+ };
11485
+ }, [unselect]);
11486
+ const onFilterUpdate = useCallback((updatedFilterValues) => {
11487
+ setFilterValues?.({
11488
+ ...updatedFilterValues,
11489
+ ...forceFilter
11378
11490
  });
11379
- const select = useCallback((cell) => {
11380
- setSelectedCell(cell);
11381
- }, []);
11382
- const unselect = useCallback(() => {
11383
- setSelectedCell(void 0);
11384
- }, []);
11385
- const onFilterUpdate = useCallback((updatedFilterValues) => {
11386
- setFilterValues?.({
11387
- ...updatedFilterValues,
11388
- ...forceFilter
11389
- });
11390
- }, [forceFilter]);
11391
- return /* @__PURE__ */ jsx(SelectableTableContext.Provider, { value: {
11392
- setPopupCell,
11393
- select,
11394
- onValueChange,
11395
- size: size ?? "m",
11396
- selectedCell
11397
- }, children: /* @__PURE__ */ jsx("div", { className: "h-full w-full flex flex-col bg-white dark:bg-surface-950", ref, children: /* @__PURE__ */ jsx(VirtualTable, { data, columns, cellRenderer, onRowClick: inlineEditing ? void 0 : onEntityClick ? onRowClick : void 0, onEndReached: loadNextPage, onResetPagination: resetPagination, error: dataLoadingError, onColumnResize, rowHeight: getRowHeight(size), loading: dataLoading, filter: filterValues, onFilterUpdate: setFilterValues ? onFilterUpdate : void 0, sortBy, onSortByUpdate: setSortBy, hoverRow, initialScroll, onScroll, checkFilterCombination, createFilterField: filterable ? createFilterField : void 0, rowClassName: useCallback((entity) => {
11398
- return highlightedRow?.(entity) ? "bg-surface-100 bg-opacity-75 dark:bg-surface-800 dark:bg-opacity-75" : "";
11399
- }, [highlightedRow]), className: "flex-grow", emptyComponent, endAdornment, AddColumnComponent }) }) });
11400
- },
11401
- () => false
11402
- // equal
11403
- );
11491
+ }, [forceFilter]);
11492
+ const contextValue = useMemo(() => ({
11493
+ setPopupCell,
11494
+ select,
11495
+ onValueChange,
11496
+ size: size ?? "m",
11497
+ selectedCell
11498
+ }), [setPopupCell, select, onValueChange, size, selectedCell]);
11499
+ return /* @__PURE__ */ jsx(SelectableTableContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx("div", { className: "h-full w-full flex flex-col bg-white dark:bg-surface-950", ref, children: /* @__PURE__ */ jsx(VirtualTable, { data, columns, cellRenderer, onRowClick: inlineEditing ? void 0 : onEntityClick ? onRowClick : void 0, onEndReached: loadNextPage, onResetPagination: resetPagination, error: dataLoadingError, onColumnResize, rowHeight: getRowHeight(size), loading: dataLoading, filter: filterValues, onFilterUpdate: setFilterValues ? onFilterUpdate : void 0, sortBy, onSortByUpdate: setSortBy, hoverRow, initialScroll, onScroll, checkFilterCombination, createFilterField: filterable ? createFilterField : void 0, rowClassName: useCallback((entity) => {
11500
+ return highlightedRow?.(entity) ? "bg-surface-100 bg-opacity-75 dark:bg-surface-800 dark:bg-opacity-75" : "";
11501
+ }, [highlightedRow]), className: "flex-grow", emptyComponent, endAdornment, AddColumnComponent }) }) });
11502
+ };
11404
11503
  function createFilterField({
11405
11504
  id,
11406
11505
  filterValue,
@@ -13345,7 +13444,7 @@ function DefaultHomePage(t0) {
13345
13444
  context.analyticsController?.onAnalyticsEvent?.(event, {
13346
13445
  path: entry_1.path
13347
13446
  });
13348
- } }) }, `nav_${entry_1.group}_${entry_1.name}`)),
13447
+ } }) }, `nav_${entry_1.group}_${entry_1.path}_${entry_1.name}`)),
13349
13448
  group_0?.toLowerCase() !== "admin" && AdditionalCards && AdditionalCards.map((AdditionalCard, i_2) => /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(AdditionalCard, { ...actionProps }) }, `nav_${group_0}_add_${i_2}`))
13350
13449
  ] }) }, `plugin_section_${group_0}`);
13351
13450
  };
@@ -16657,7 +16756,6 @@ function KeyValueFieldBinding(t0) {
16657
16756
  t6 = $[15];
16658
16757
  }
16659
16758
  const title = t6;
16660
- console.log("minimalistView", propertyKey, minimalistView);
16661
16759
  let t7;
16662
16760
  if ($[16] !== expanded || $[17] !== mapFormView || $[18] !== minimalistView || $[19] !== title) {
16663
16761
  t7 = !minimalistView && /* @__PURE__ */ jsx(ExpandablePanel, { initiallyExpanded: expanded, title, innerClassName: "px-2 md:px-4 pb-2 md:pb-4 pt-1 md:pt-2", children: mapFormView });
@@ -19139,7 +19237,7 @@ function ConfirmationDialog(t0) {
19139
19237
  }
19140
19238
  let t5;
19141
19239
  if ($[8] !== loading || $[9] !== onAccept) {
19142
- t5 = /* @__PURE__ */ jsx(LoadingButton, { color: "primary", type: "submit", loading, onClick: onAccept, children: "Ok" });
19240
+ t5 = /* @__PURE__ */ jsx(LoadingButton, { color: "primary", type: "submit", loading, onClick: onAccept, autoFocus: true, children: "Ok" });
19143
19241
  $[8] = loading;
19144
19242
  $[9] = onAccept;
19145
19243
  $[10] = t5;
@@ -20143,9 +20241,9 @@ function useBuildNavigationController(props) {
20143
20241
  views: viewsProp,
20144
20242
  adminViews: adminViewsProp,
20145
20243
  viewsOrder,
20244
+ plugins,
20146
20245
  userConfigPersistence,
20147
20246
  dataSourceDelegate,
20148
- injectCollections,
20149
20247
  disabled
20150
20248
  } = props;
20151
20249
  const navigate = useNavigate();
@@ -20235,7 +20333,7 @@ function useBuildNavigationController(props) {
20235
20333
  if (disabled || authController.initialLoading) return;
20236
20334
  console.debug("Refreshing navigation");
20237
20335
  try {
20238
- const [resolvedCollections = [], resolvedViews, resolvedAdminViews = []] = await Promise.all([resolveCollections(collectionsProp, collectionPermissions, authController, dataSourceDelegate, injectCollections), resolveCMSViews(viewsProp, authController, dataSourceDelegate), resolveCMSViews(adminViewsProp, authController, dataSourceDelegate)]);
20336
+ const [resolvedCollections = [], resolvedViews, resolvedAdminViews = []] = await Promise.all([resolveCollections(collectionsProp, collectionPermissions, authController, dataSourceDelegate, plugins), resolveCMSViews(viewsProp, authController, dataSourceDelegate), resolveCMSViews(adminViewsProp, authController, dataSourceDelegate)]);
20239
20337
  let shouldUpdateTopLevelNav = false;
20240
20338
  if (!areCollectionListsEqual(collectionsRef.current ?? [], resolvedCollections)) {
20241
20339
  collectionsRef.current = resolvedCollections;
@@ -20264,7 +20362,7 @@ function useBuildNavigationController(props) {
20264
20362
  }
20265
20363
  if (navigationLoading) setNavigationLoading(false);
20266
20364
  if (!initialised) setInitialised(true);
20267
- }, [collectionsProp, collectionPermissions, authController.user, authController.initialLoading, disabled, viewsProp, adminViewsProp, computeTopNavigation, injectCollections]);
20365
+ }, [collectionsProp, collectionPermissions, authController.user, authController.initialLoading, disabled, viewsProp, adminViewsProp, computeTopNavigation]);
20268
20366
  useEffect(() => {
20269
20367
  refreshNavigation();
20270
20368
  }, [refreshNavigation]);
@@ -20406,7 +20504,19 @@ function filterOutNotAllowedCollections(resolvedCollections, authController) {
20406
20504
  };
20407
20505
  });
20408
20506
  }
20409
- async function resolveCollections(collections, collectionPermissions, authController, dataSource, injectCollections) {
20507
+ function applyPluginModifyCollection(resolvedCollections, modifyCollection) {
20508
+ return resolvedCollections.map((collection) => {
20509
+ const modifiedCollection = modifyCollection(collection);
20510
+ if (modifiedCollection.subcollections) {
20511
+ return {
20512
+ ...modifiedCollection,
20513
+ subcollections: applyPluginModifyCollection(modifiedCollection.subcollections, modifyCollection)
20514
+ };
20515
+ }
20516
+ return modifiedCollection;
20517
+ });
20518
+ }
20519
+ async function resolveCollections(collections, collectionPermissions, authController, dataSource, plugins) {
20410
20520
  let resolvedCollections = [];
20411
20521
  if (typeof collections === "function") {
20412
20522
  resolvedCollections = await collections({
@@ -20417,8 +20527,15 @@ async function resolveCollections(collections, collectionPermissions, authContro
20417
20527
  } else if (Array.isArray(collections)) {
20418
20528
  resolvedCollections = collections;
20419
20529
  }
20420
- if (injectCollections) {
20421
- resolvedCollections = injectCollections(resolvedCollections ?? []);
20530
+ if (plugins) {
20531
+ for (const plugin of plugins) {
20532
+ if (plugin.collection?.modifyCollection) {
20533
+ resolvedCollections = applyPluginModifyCollection(resolvedCollections, plugin.collection.modifyCollection);
20534
+ }
20535
+ if (plugin.collection?.injectCollections) {
20536
+ resolvedCollections = plugin.collection.injectCollections(resolvedCollections ?? []);
20537
+ }
20538
+ }
20422
20539
  }
20423
20540
  resolvedCollections = applyPermissionsFunctionIfEmpty(resolvedCollections, collectionPermissions);
20424
20541
  resolvedCollections = filterOutNotAllowedCollections(resolvedCollections, authController);
@@ -21339,10 +21456,11 @@ function EntityEditViewInner({
21339
21456
  }, [selectedTabProp]);
21340
21457
  const subcollections = (collection.subcollections ?? []).filter((c2) => !c2.hideFromNavigation);
21341
21458
  const subcollectionsCount = subcollections?.length ?? 0;
21342
- const customViews = collection.entityViews;
21459
+ const customViews = collection.entityViews ?? [];
21343
21460
  const customViewsCount = customViews?.length ?? 0;
21344
21461
  const includeJsonView = collection.includeJsonView === void 0 ? true : collection.includeJsonView;
21345
21462
  const hasAdditionalViews = customViewsCount > 0 || subcollectionsCount > 0 || includeJsonView;
21463
+ const plugins = customizationController.plugins;
21346
21464
  const {
21347
21465
  resolvedEntityViews,
21348
21466
  selectedEntityView,
@@ -21440,7 +21558,8 @@ function EntityEditViewInner({
21440
21558
  formProps?.onSaved?.(res);
21441
21559
  }, Builder: selectedSecondaryForm?.Builder });
21442
21560
  const subcollectionTabs = subcollections && subcollections.map((subcollection_0) => /* @__PURE__ */ jsx(Tab, { className: "text-sm min-w-[120px]", value: subcollection_0.id, children: subcollection_0.name }, `entity_detail_collection_tab_${subcollection_0.name}`));
21443
- const customViewTabs = resolvedEntityViews.map((view) => /* @__PURE__ */ jsx(Tab, { className: "text-sm min-w-[120px]", value: view.key, children: view.name }, `entity_detail_collection_tab_${view.name}`));
21561
+ const customViewTabsStart = resolvedEntityViews.filter((view) => view.position === "start").map((view_0) => /* @__PURE__ */ jsx(Tab, { className: !view_0.tabComponent ? "text-sm min-w-[120px]" : void 0, value: view_0.key, children: view_0.tabComponent ?? view_0.name }, `entity_detail_collection_tab_${view_0.name}`));
21562
+ const customViewTabsEnd = resolvedEntityViews.filter((view_1) => !view_1.position || view_1.position === "end").map((view_2) => /* @__PURE__ */ jsx(Tab, { className: !view_2.tabComponent ? "text-sm min-w-[120px]" : void 0, value: view_2.key, children: view_2.tabComponent ?? view_2.name }, `entity_detail_collection_tab_${view_2.name}`));
21444
21563
  const shouldShowTopBar = Boolean(barActions) || hasAdditionalViews;
21445
21564
  let result = /* @__PURE__ */ jsxs("div", { className: "relative flex flex-col h-full w-full bg-white dark:bg-surface-900", children: [
21446
21565
  shouldShowTopBar && /* @__PURE__ */ jsxs("div", { className: cls("h-14 flex overflow-visible overflow-x-scroll w-full no-scrollbar h-14 border-b pl-2 pr-2 pt-1 flex items-end bg-surface-50 dark:bg-surface-900", defaultBorderMixin), children: [
@@ -21450,9 +21569,10 @@ function EntityEditViewInner({
21450
21569
  hasAdditionalViews && /* @__PURE__ */ jsxs(Tabs, { value: selectedTab, onValueChange: (value_1) => {
21451
21570
  onSideTabClick(value_1);
21452
21571
  }, children: [
21453
- includeJsonView && /* @__PURE__ */ jsx(Tab, { disabled: !hasAdditionalViews, value: JSON_TAB_VALUE, innerClassName: "block", className: "text-sm", children: /* @__PURE__ */ jsx(CodeIcon, { size: "small" }) }),
21572
+ includeJsonView && /* @__PURE__ */ jsx(Tab, { disabled: !hasAdditionalViews, value: JSON_TAB_VALUE, className: "text-sm", children: /* @__PURE__ */ jsx(CodeIcon, { size: "small" }) }),
21573
+ customViewTabsStart,
21454
21574
  /* @__PURE__ */ jsx(Tab, { disabled: !hasAdditionalViews, value: MAIN_TAB_VALUE, className: "text-sm min-w-[120px]", children: collection.singularName ?? collection.name }),
21455
- customViewTabs,
21575
+ customViewTabsEnd,
21456
21576
  subcollectionTabs
21457
21577
  ] })
21458
21578
  ] }),
@@ -21464,7 +21584,6 @@ function EntityEditViewInner({
21464
21584
  customViewsView,
21465
21585
  subCollectionsViews
21466
21586
  ] });
21467
- const plugins = customizationController.plugins;
21468
21587
  if (plugins) {
21469
21588
  plugins.forEach((plugin) => {
21470
21589
  if (plugin.form?.provider) {
@@ -21475,6 +21594,12 @@ function EntityEditViewInner({
21475
21594
  return result;
21476
21595
  }
21477
21596
  function EntitySidePanel(props) {
21597
+ const {
21598
+ allowFullScreen = true,
21599
+ path,
21600
+ entityId,
21601
+ formProps
21602
+ } = props;
21478
21603
  const {
21479
21604
  blocked,
21480
21605
  setBlocked,
@@ -21494,8 +21619,8 @@ function EntitySidePanel(props) {
21494
21619
  close(true);
21495
21620
  };
21496
21621
  const onUpdate = (params) => {
21497
- if (props.onUpdate) {
21498
- props.onUpdate(params);
21622
+ {
21623
+ onUpdate(params);
21499
21624
  }
21500
21625
  if (params.status !== "existing") {
21501
21626
  sideEntityController.replace({
@@ -21512,18 +21637,18 @@ function EntitySidePanel(props) {
21512
21637
  }
21513
21638
  };
21514
21639
  const parentCollectionIds = useMemo(() => {
21515
- return navigationController.getParentCollectionIds(props.path);
21516
- }, [navigationController, props.path]);
21640
+ return navigationController.getParentCollectionIds(path);
21641
+ }, [navigationController, path]);
21517
21642
  const collection = useMemo(() => {
21518
21643
  if (props.collection) {
21519
21644
  return props.collection;
21520
21645
  }
21521
- const registryCollection = navigationController.getCollection(props.path);
21646
+ const registryCollection = navigationController.getCollection(path);
21522
21647
  if (registryCollection) {
21523
21648
  return registryCollection;
21524
21649
  }
21525
- console.error("ERROR: No collection found in path `", props.path, "`. Entity id: ", props.entityId);
21526
- throw Error("ERROR: No collection found in path `" + props.path + "`. Make sure you have defined a collection for this path in the root navigation.");
21650
+ console.error("ERROR: No collection found in path `", path, "`. Entity id: ", entityId);
21651
+ throw Error("ERROR: No collection found in path `" + path + "`. Make sure you have defined a collection for this path in the root navigation.");
21527
21652
  }, [navigationController, props.collection]);
21528
21653
  useEffect(() => {
21529
21654
  function beforeunload(e) {
@@ -21550,24 +21675,24 @@ function EntitySidePanel(props) {
21550
21675
  }
21551
21676
  return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(EntityEditView, { ...props, layout: "side_panel", collection, parentCollectionIds, onValuesModified, onSaved: onUpdate, barActions: /* @__PURE__ */ jsxs(Fragment, { children: [
21552
21677
  /* @__PURE__ */ jsx(IconButton, { className: "self-center", onClick: onClose, children: /* @__PURE__ */ jsx(CloseIcon, { size: "small" }) }),
21553
- /* @__PURE__ */ jsx(IconButton, { className: "self-center", onClick: () => {
21554
- if (props.entityId) navigate(location.pathname);
21678
+ allowFullScreen && /* @__PURE__ */ jsx(IconButton, { className: "self-center", onClick: () => {
21679
+ if (entityId) navigate(location.pathname);
21555
21680
  else navigate(location.pathname + "#new");
21556
21681
  }, children: /* @__PURE__ */ jsx(OpenInFullIcon, { size: "small" }) })
21557
21682
  ] }), onTabChange: ({
21558
- path,
21559
- entityId,
21683
+ path: path_0,
21684
+ entityId: entityId_0,
21560
21685
  selectedTab,
21561
21686
  collection: collection_0
21562
21687
  }) => {
21563
21688
  sideEntityController.replace({
21564
- path,
21565
- entityId,
21689
+ path: path_0,
21690
+ entityId: entityId_0,
21566
21691
  selectedTab,
21567
21692
  updateUrl: true,
21568
21693
  collection: collection_0
21569
21694
  });
21570
- }, formProps: props.formProps }) }) });
21695
+ }, formProps }) }) });
21571
21696
  }
21572
21697
  const NEW_URL_HASH = "new_side";
21573
21698
  const SIDE_URL_HASH = "side";
@@ -21576,7 +21701,7 @@ function getEntityViewWidth(props, small, customizationController, authControlle
21576
21701
  const {
21577
21702
  selectedSecondaryForm
21578
21703
  } = resolvedSelectedEntityView(props.collection?.entityViews, customizationController, props.selectedTab);
21579
- const shouldUseSmallLayout = !props.selectedTab || props.selectedTab === JSON_TAB_VALUE || Boolean(selectedSecondaryForm);
21704
+ const shouldUseSmallLayout = !props.selectedTab || props.selectedTab === JSON_TAB_VALUE || props.selectedTab === "__history" || Boolean(selectedSecondaryForm);
21580
21705
  let resolvedWidth;
21581
21706
  if (props.width) {
21582
21707
  resolvedWidth = typeof props.width === "number" ? `${props.width}px` : props.width;
@@ -24013,6 +24138,8 @@ export {
24013
24138
  EntityCollectionView,
24014
24139
  EntityCollectionViewActions,
24015
24140
  EntityForm,
24141
+ EntityPreview,
24142
+ EntityPreviewContainer,
24016
24143
  EntityReference,
24017
24144
  EntityView,
24018
24145
  EnumValuesChip,
@@ -24146,6 +24273,7 @@ export {
24146
24273
  joinCollectionLists,
24147
24274
  makePropertiesEditable,
24148
24275
  makePropertiesNonEditable,
24276
+ mergeCallbacks,
24149
24277
  mergeCollection,
24150
24278
  mergeDeep,
24151
24279
  mergeEntityActions,