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