@firecms/core 3.0.0-canary.112 → 3.0.0-canary.114

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 (40) hide show
  1. package/dist/components/ArrayContainer.d.ts +2 -1
  2. package/dist/components/EntityCollectionTable/fields/TableReferenceField.d.ts +1 -1
  3. package/dist/components/EntityPreview.d.ts +1 -1
  4. package/dist/form/components/FormikArrayContainer.d.ts +2 -1
  5. package/dist/index.es.js +167 -117
  6. package/dist/index.es.js.map +1 -1
  7. package/dist/index.umd.js +166 -116
  8. package/dist/index.umd.js.map +1 -1
  9. package/dist/preview/components/ReferencePreview.d.ts +1 -1
  10. package/dist/types/datasource.d.ts +8 -6
  11. package/dist/types/entity_overrides.d.ts +2 -2
  12. package/dist/types/side_dialogs_controller.d.ts +10 -0
  13. package/dist/util/icons.d.ts +1 -0
  14. package/package.json +5 -5
  15. package/src/components/ArrayContainer.tsx +7 -4
  16. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +13 -8
  17. package/src/components/EntityCollectionView/EntityCollectionView.tsx +1 -1
  18. package/src/components/EntityPreview.tsx +20 -22
  19. package/src/components/HomePage/DefaultHomePage.tsx +7 -9
  20. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +7 -2
  21. package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +3 -3
  22. package/src/components/VirtualTable/fields/VirtualTableInput.tsx +2 -1
  23. package/src/components/VirtualTable/fields/VirtualTableNumberInput.tsx +2 -1
  24. package/src/core/EntityEditView.tsx +20 -18
  25. package/src/core/SideDialogs.tsx +0 -2
  26. package/src/form/components/FormikArrayContainer.tsx +4 -1
  27. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +4 -4
  28. package/src/form/field_bindings/BlockFieldBinding.tsx +2 -1
  29. package/src/form/field_bindings/ReferenceFieldBinding.tsx +5 -4
  30. package/src/hooks/data/delete.ts +2 -1
  31. package/src/hooks/data/useDataSource.tsx +10 -2
  32. package/src/hooks/useBuildNavigationController.tsx +2 -4
  33. package/src/internal/useBuildDataSource.ts +41 -67
  34. package/src/internal/useBuildSideDialogsController.tsx +1 -0
  35. package/src/internal/useBuildSideEntityController.tsx +13 -2
  36. package/src/preview/components/ReferencePreview.tsx +2 -13
  37. package/src/types/datasource.ts +9 -6
  38. package/src/types/entity_overrides.tsx +2 -2
  39. package/src/types/side_dialogs_controller.tsx +13 -0
  40. package/src/util/icons.tsx +8 -2
package/dist/index.es.js CHANGED
@@ -4,7 +4,7 @@ import React__default, { useRef, useEffect, useContext, useCallback, useMemo, us
4
4
  import { SnackbarProvider as SnackbarProvider$1, useSnackbar } from "notistack";
5
5
  import hash from "object-hash";
6
6
  import { useCreateFormex, Formex, setIn, Field, getIn, useFormex } from "@firecms/formex";
7
- import { getColorSchemeForSeed, CHIP_COLORS, Tooltip, ErrorIcon, Typography, CircleIcon, FunctionsIcon, iconKeys, coolIconKeys, Icon, IconButton, ContentCopyIcon, OpenInNewIcon, DescriptionIcon, cls, Skeleton, Chip, defaultBorderMixin, KeyboardTabIcon, Checkbox, Markdown, TextareaAutosize, MultiSelect, MultiSelectItem, Select, SelectItem, BooleanSwitch, DateTimeField, paperMixin, ErrorOutlineIcon, EditIcon, RemoveCircleIcon, Menu, MoreVertIcon, MenuItem, CircularProgress, SearchBar, Badge, ArrowUpwardIcon, Popover, FilterListIcon, Button, AssignmentIcon, CenteredView, Label, TextField, ClearIcon, BooleanSwitchWithLabel, useOutsideAlerter, Dialog, DialogContent, DialogActions, FileCopyIcon, ArchiveIcon, DeleteIcon, AddIcon, ExpandablePanel, Card, ArrowForwardIcon, cardMixin, cardClickableMixin, StarIcon, StarBorderIcon, Collapse, Container, FilterListOffIcon, SearchIcon, LoadingButton, Avatar, DarkModeIcon, LightModeIcon, LogoutIcon, fieldBackgroundHoverMixin, HandleIcon, RemoveIcon, debounce, InfoIcon, CloseIcon, fieldBackgroundMixin, fieldBackgroundDisabledMixin, ArrowDropDownIcon, ShortTextIcon, SubjectIcon, FormatQuoteIcon, HttpIcon, EmailIcon, FlagIcon, ListIcon, ListAltIcon, NumbersIcon, FormatListNumberedIcon, UploadFileIcon, DriveFolderUploadIcon, LinkIcon, AddLinkIcon, ScheduleIcon, BallotIcon, RepeatIcon, ViewStreamIcon, NotesIcon, Tab, Tabs, Alert, Sheet, useLocaleConfig, MenuIcon, ChevronLeftIcon } from "@firecms/ui";
7
+ import { getColorSchemeForSeed, CHIP_COLORS, Tooltip, ErrorIcon, Typography, CircleIcon, FunctionsIcon, iconKeys, coolIconKeys, Icon, IconButton, ContentCopyIcon, OpenInNewIcon, DescriptionIcon, cls, Skeleton, Chip, defaultBorderMixin, KeyboardTabIcon, Checkbox, Markdown, TextareaAutosize, focusedDisabled, MultiSelect, MultiSelectItem, Select, SelectItem, BooleanSwitch, DateTimeField, paperMixin, ErrorOutlineIcon, EditIcon, RemoveCircleIcon, Menu, MoreVertIcon, MenuItem, CircularProgress, SearchBar, Badge, ArrowUpwardIcon, Popover, FilterListIcon, Button, AssignmentIcon, CenteredView, Label, TextField, ClearIcon, BooleanSwitchWithLabel, useOutsideAlerter, Dialog, DialogContent, DialogActions, FileCopyIcon, ArchiveIcon, DeleteIcon, AddIcon, ExpandablePanel, Card, ArrowForwardIcon, cardMixin, cardClickableMixin, StarIcon, StarBorderIcon, Collapse, Container, FilterListOffIcon, SearchIcon, LoadingButton, Avatar, DarkModeIcon, LightModeIcon, LogoutIcon, HandleIcon, RemoveIcon, debounce, InfoIcon, CloseIcon, fieldBackgroundMixin, fieldBackgroundDisabledMixin, fieldBackgroundHoverMixin, ArrowDropDownIcon, ShortTextIcon, SubjectIcon, FormatQuoteIcon, HttpIcon, EmailIcon, FlagIcon, ListIcon, ListAltIcon, NumbersIcon, FormatListNumberedIcon, UploadFileIcon, DriveFolderUploadIcon, LinkIcon, AddLinkIcon, ScheduleIcon, BallotIcon, RepeatIcon, ViewStreamIcon, NotesIcon, Tab, Tabs, Alert, Sheet, useLocaleConfig, MenuIcon, ChevronLeftIcon } from "@firecms/ui";
8
8
  import equal from "react-fast-compare";
9
9
  import { Link, useNavigate, useLocation, UNSAFE_NavigationContext, NavLink, Route, Routes } from "react-router-dom";
10
10
  import { format } from "date-fns";
@@ -2684,7 +2684,11 @@ function getIcon(iconKey, className) {
2684
2684
  return iconKey in iconKeysMap ? /* @__PURE__ */ jsx(Icon, { iconKey, size: "medium", className }) : void 0;
2685
2685
  }
2686
2686
  const IconForView = React__default.memo(
2687
- function IconForView2({ collectionOrView, className }) {
2687
+ function IconForView2({
2688
+ collectionOrView,
2689
+ className,
2690
+ size = "medium"
2691
+ }) {
2688
2692
  if (!collectionOrView) return /* @__PURE__ */ jsx(Fragment, {});
2689
2693
  const icon = getIcon(collectionOrView.icon, className);
2690
2694
  if (collectionOrView?.icon && icon)
@@ -2701,7 +2705,7 @@ const IconForView = React__default.memo(
2701
2705
  const iconsCount = coolIconKeys.length;
2702
2706
  if (!key)
2703
2707
  key = coolIconKeys[hashString(collectionOrView.path) % iconsCount];
2704
- return /* @__PURE__ */ jsx(Icon, { iconKey: key, size: "medium", className });
2708
+ return /* @__PURE__ */ jsx(Icon, { iconKey: key, size, className });
2705
2709
  },
2706
2710
  (prevProps, nextProps) => {
2707
2711
  return equal(prevProps.collectionOrView?.icon, nextProps.collectionOrView?.icon);
@@ -3248,8 +3252,6 @@ function replacePlaceholders({
3248
3252
  const DataSourceContext = React__default.createContext({});
3249
3253
  const useDataSource = (collection) => {
3250
3254
  const defaultDataSource = useContext(DataSourceContext);
3251
- if (collection?.overrides?.dataSource)
3252
- return collection?.overrides.dataSource;
3253
3255
  return defaultDataSource;
3254
3256
  };
3255
3257
  const NavigationContext = React__default.createContext({});
@@ -3387,7 +3389,7 @@ function useCollectionFetch({
3387
3389
  itemCount,
3388
3390
  searchString
3389
3391
  }) {
3390
- const dataSource = useDataSource(collection);
3392
+ const dataSource = useDataSource();
3391
3393
  const navigationController = useNavigationController();
3392
3394
  const path = navigationController.resolveAliasesFrom(inputPath);
3393
3395
  const sortByProperty = sortBy ? sortBy[0] : void 0;
@@ -3470,7 +3472,7 @@ function useEntityFetch({
3470
3472
  collection,
3471
3473
  useCache = false
3472
3474
  }) {
3473
- const dataSource = useDataSource(collection);
3475
+ const dataSource = useDataSource();
3474
3476
  const navigationController = useNavigationController();
3475
3477
  const path = navigationController.resolveAliasesFrom(inputPath);
3476
3478
  const context = useFireCMSContext();
@@ -3681,7 +3683,8 @@ async function deleteEntityWithCallbacks({
3681
3683
  }
3682
3684
  }
3683
3685
  return dataSource.deleteEntity({
3684
- entity
3686
+ entity,
3687
+ collection
3685
3688
  }).then(() => {
3686
3689
  onDeleteSuccess && onDeleteSuccess(entity);
3687
3690
  try {
@@ -4081,7 +4084,6 @@ function useBuildNavigationController(props) {
4081
4084
  );
4082
4085
  let shouldUpdateTopLevelNav = false;
4083
4086
  if (!areCollectionListsEqual(collectionsRef.current ?? [], resolvedCollections)) {
4084
- console.log("Collections need to be updated");
4085
4087
  collectionsRef.current = resolvedCollections;
4086
4088
  shouldUpdateTopLevelNav = true;
4087
4089
  }
@@ -4090,12 +4092,10 @@ function useBuildNavigationController(props) {
4090
4092
  shouldUpdateTopLevelNav = true;
4091
4093
  }
4092
4094
  if (!equal(viewsRef.current, resolvedViews)) {
4093
- console.log("Views need to be updated");
4094
4095
  viewsRef.current = resolvedViews;
4095
4096
  shouldUpdateTopLevelNav = true;
4096
4097
  }
4097
4098
  if (!equal(adminViewsRef.current, resolvedAdminViews)) {
4098
- console.log("Admin views need to be updated");
4099
4099
  adminViewsRef.current = resolvedAdminViews;
4100
4100
  shouldUpdateTopLevelNav = true;
4101
4101
  }
@@ -4965,8 +4965,8 @@ function renderSkeletonCaptionText(index) {
4965
4965
  function renderSkeletonIcon() {
4966
4966
  return /* @__PURE__ */ jsx(Skeleton, { width: 24, height: 24 });
4967
4967
  }
4968
- const StorageThumbnail = React__default.memo(StorageThumbnailInternal, areEqual$2);
4969
- function areEqual$2(prevProps, nextProps) {
4968
+ const StorageThumbnail = React__default.memo(StorageThumbnailInternal, areEqual$1);
4969
+ function areEqual$1(prevProps, nextProps) {
4970
4970
  return prevProps.size === nextProps.size && prevProps.storagePathOrDownloadUrl === nextProps.storagePathOrDownloadUrl && prevProps.storeUrl === nextProps.storeUrl && prevProps.interactive === nextProps.interactive;
4971
4971
  }
4972
4972
  const URL_CACHE = {};
@@ -5173,15 +5173,18 @@ function EntityPreview({
5173
5173
  hover: disabled ? void 0 : hover,
5174
5174
  size,
5175
5175
  children: [
5176
- imageProperty && /* @__PURE__ */ jsx("div", { className: cls("w-10 h-10 mr-2 shrink-0 grow-0", size === "smallest" ? "my-0.5" : "m-2 self-start"), children: /* @__PURE__ */ jsx(
5177
- PropertyPreview,
5178
- {
5179
- property: imageProperty,
5180
- propertyKey: imagePropertyKey,
5181
- size: "smallest",
5182
- value: getValueInPath(entity.values, imagePropertyKey)
5183
- }
5184
- ) }),
5176
+ /* @__PURE__ */ jsxs("div", { className: cls("w-10 h-10 mr-2 shrink-0 grow-0", size === "smallest" ? "my-0.5" : "m-2 self-start"), children: [
5177
+ imageProperty && /* @__PURE__ */ jsx(
5178
+ PropertyPreview,
5179
+ {
5180
+ property: imageProperty,
5181
+ propertyKey: imagePropertyKey,
5182
+ size: "smallest",
5183
+ value: getValueInPath(entity.values, imagePropertyKey)
5184
+ }
5185
+ ),
5186
+ !imageProperty && /* @__PURE__ */ jsx(IconForView, { collectionOrView: collection, size, className: "mr-2" })
5187
+ ] }),
5185
5188
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col flex-grow w-full m-1", children: [
5186
5189
  size !== "smallest" && includeId && (entity ? /* @__PURE__ */ jsx("div", { className: `${size !== "medium" ? "block whitespace-nowrap overflow-hidden truncate" : ""}`, children: /* @__PURE__ */ jsx(
5187
5190
  Typography,
@@ -5261,7 +5264,7 @@ function EntityPreview({
5261
5264
  }
5262
5265
  );
5263
5266
  }
5264
- const EntityPreviewContainerInner = React.forwardRef(({
5267
+ const EntityPreviewContainer = React.forwardRef(({
5265
5268
  children,
5266
5269
  hover,
5267
5270
  onClick,
@@ -5303,9 +5306,7 @@ const EntityPreviewContainerInner = React.forwardRef(({
5303
5306
  }
5304
5307
  );
5305
5308
  });
5306
- EntityPreviewContainerInner.displayName = "EntityPreviewContainer";
5307
- const EntityPreviewContainer = React.memo(EntityPreviewContainerInner);
5308
- const ReferencePreview = React.memo(function ReferencePreview2(props) {
5309
+ const ReferencePreview = function ReferencePreview2(props) {
5309
5310
  const reference = props.reference;
5310
5311
  if (!(typeof reference === "object" && "isEntityReference" in reference && reference.isEntityReference())) {
5311
5312
  console.warn("Reference preview received value of type", typeof reference);
@@ -5325,10 +5326,7 @@ const ReferencePreview = React.memo(function ReferencePreview2(props) {
5325
5326
  );
5326
5327
  }
5327
5328
  return /* @__PURE__ */ jsx(ReferencePreviewInternal, { ...props });
5328
- }, areEqual$1);
5329
- function areEqual$1(prevProps, nextProps) {
5330
- return prevProps.disabled === nextProps.disabled && prevProps.size === nextProps.size && prevProps.hover === nextProps.hover && prevProps.reference?.id === nextProps.reference?.id && prevProps.reference?.path === nextProps.reference?.path && prevProps.includeEntityLink === nextProps.includeEntityLink && prevProps.onClick === nextProps.onClick;
5331
- }
5329
+ };
5332
5330
  function ReferencePreviewInternal({
5333
5331
  disabled,
5334
5332
  reference,
@@ -6289,6 +6287,7 @@ function VirtualTableInput(props) {
6289
6287
  return /* @__PURE__ */ jsx(
6290
6288
  TextareaAutosize,
6291
6289
  {
6290
+ className: focusedDisabled,
6292
6291
  ref,
6293
6292
  style: {
6294
6293
  padding: 0,
@@ -6489,7 +6488,7 @@ function VirtualTableNumberInput(props) {
6489
6488
  "input",
6490
6489
  {
6491
6490
  ref,
6492
- className: "w-full text-right p-0 m-0 bg-transparent border-none resize-none outline-none font-normal leading-normal text-unset",
6491
+ className: cls("w-full text-right p-0 m-0 bg-transparent border-none resize-none outline-none font-normal leading-normal text-unset", focusedDisabled),
6493
6492
  style: {
6494
6493
  textAlign: align
6495
6494
  },
@@ -6542,8 +6541,8 @@ function VirtualTableDateField(props) {
6542
6541
  onChange: (dateValue) => updateValue(dateValue ?? null),
6543
6542
  size: "medium",
6544
6543
  invisible: true,
6545
- className: "w-full h-full",
6546
- inputClassName: "w-full h-full",
6544
+ inputClassName: cls("w-full h-full", focusedDisabled),
6545
+ className: cls("w-full h-full", focusedDisabled),
6547
6546
  mode,
6548
6547
  locale
6549
6548
  }
@@ -7154,10 +7153,10 @@ function TableReferenceField(props) {
7154
7153
  throw Error(`Couldn't find the corresponding collection view for the path: ${path}`);
7155
7154
  }
7156
7155
  }
7157
- return /* @__PURE__ */ jsx(TableReferenceFieldSuccess, { ...props, collection });
7156
+ return /* @__PURE__ */ jsx(TableReferenceFieldInternal, { ...props, collection });
7158
7157
  }
7159
- const TableReferenceFieldSuccess = React__default.memo(
7160
- function TableReferenceFieldSuccess2(props) {
7158
+ const TableReferenceFieldInternal = React__default.memo(
7159
+ function TableReferenceFieldInternal2(props) {
7161
7160
  const {
7162
7161
  name,
7163
7162
  internalValue,
@@ -7192,11 +7191,11 @@ const TableReferenceFieldSuccess = React__default.memo(
7192
7191
  forceFilter
7193
7192
  }
7194
7193
  );
7195
- const handleOpen = useCallback(() => {
7194
+ const handleOpen = () => {
7196
7195
  if (disabled)
7197
7196
  return;
7198
7197
  referenceDialogController.open();
7199
- }, [disabled, referenceDialogController]);
7198
+ };
7200
7199
  const valueNotSet = !internalValue || Array.isArray(internalValue) && internalValue.length === 0;
7201
7200
  const buildSingleReferenceField = () => {
7202
7201
  if (internalValue && !Array.isArray(internalValue) && internalValue.isEntityReference && internalValue.isEntityReference())
@@ -7259,12 +7258,21 @@ const TableReferenceFieldSuccess = React__default.memo(
7259
7258
  EntityPreviewContainer,
7260
7259
  {
7261
7260
  className: cls(
7262
- "p-4 text-sm font-medium flex items-center gap-4 uppercase",
7261
+ "p-4 text-sm font-medium flex items-center uppercase",
7262
+ multiselect ? "gap-4" : "gap-6",
7263
7263
  disabled ? "text-slate-500" : "cursor-pointer text-slate-700 dark:text-slate-300 hover:bg-slate-50 dark:hover:bg-gray-800 group-hover:bg-slate-50 dark:group-hover:bg-gray-800"
7264
7264
  ),
7265
7265
  onClick: handleOpen,
7266
7266
  size: "medium",
7267
7267
  children: [
7268
+ /* @__PURE__ */ jsx(
7269
+ IconForView,
7270
+ {
7271
+ size: "small",
7272
+ collectionOrView: collection,
7273
+ className: "text-gray-300 dark:text-gray-600"
7274
+ }
7275
+ ),
7268
7276
  "Edit ",
7269
7277
  title
7270
7278
  ]
@@ -10348,7 +10356,7 @@ function useDataSourceEntityCollectionTableController({
10348
10356
  } = collection;
10349
10357
  const [popupCell, setPopupCell] = React__default.useState(void 0);
10350
10358
  const navigation = useNavigationController();
10351
- const dataSource = useDataSource(collection);
10359
+ const dataSource = useDataSource();
10352
10360
  const resolvedPath = useMemo(() => navigation.resolveAliasesFrom(fullPath), [fullPath, navigation.resolveAliasesFrom]);
10353
10361
  const forceFilter = forceFilterFromProps ?? forceFilterFromCollection;
10354
10362
  const paginationEnabled = collection.pagination === void 0 || Boolean(collection.pagination);
@@ -10596,7 +10604,7 @@ function DeleteEntityDialog({
10596
10604
  onMultipleEntitiesDelete,
10597
10605
  path
10598
10606
  }) {
10599
- const dataSource = useDataSource(collection);
10607
+ const dataSource = useDataSource();
10600
10608
  const customizationController = useCustomizationController();
10601
10609
  const snackbarController = useSnackbarController();
10602
10610
  const [loading, setLoading] = useState(false);
@@ -10891,7 +10899,8 @@ function ReferenceSelectionTable({
10891
10899
  const analyticsController = useAnalyticsController();
10892
10900
  const customizationController = useCustomizationController();
10893
10901
  const fullPath = navigation.resolveAliasesFrom(pathInput);
10894
- const dataSource = useDataSource(collection);
10902
+ console.trace("Opening reference dialog for path " + fullPath);
10903
+ const dataSource = useDataSource();
10895
10904
  const [entitiesDisplayedFirst, setEntitiesDisplayedFirst] = useState([]);
10896
10905
  const toggleEntitySelection = (entity) => {
10897
10906
  let newValue;
@@ -11046,7 +11055,17 @@ function ReferenceSelectionTable({
11046
11055
  tableController,
11047
11056
  enablePopupIcon: false,
11048
11057
  tableRowActionsBuilder,
11049
- title: /* @__PURE__ */ jsx(Typography, { variant: "subtitle2", children: collection.singularName ? `Select ${collection.singularName}` : `Select from ${collection.name}` }),
11058
+ title: /* @__PURE__ */ jsxs(Typography, { variant: "subtitle2", className: "flex flex-row gap-2", children: [
11059
+ /* @__PURE__ */ jsx(
11060
+ IconForView,
11061
+ {
11062
+ size: "small",
11063
+ collectionOrView: collection,
11064
+ className: "text-gray-300 dark:text-gray-600"
11065
+ }
11066
+ ),
11067
+ collection.singularName ? `Select ${collection.singularName}` : `Select from ${collection.name}`
11068
+ ] }),
11050
11069
  defaultSize: collection.defaultSize,
11051
11070
  properties: resolvedCollection.properties,
11052
11071
  forceFilter,
@@ -11478,15 +11497,11 @@ function DefaultHomePage({
11478
11497
  groups
11479
11498
  } = navigationController.topLevelNavigation;
11480
11499
  const [filteredUrls, setFilteredUrls] = useState(null);
11481
- const filteredNavigationEntries = filteredUrls ? navigationEntries.filter((entry) => filteredUrls.includes(entry.url)) : navigationEntries;
11500
+ const performingSearch = Boolean(filteredUrls);
11501
+ const filteredNavigationEntries = filteredUrls ? filteredUrls.map((url) => navigationEntries.find((e) => e.url === url)).filter(Boolean) : navigationEntries;
11482
11502
  useEffect(() => {
11483
11503
  fuse.current = new Fuse(navigationEntries, {
11484
- keys: [
11485
- "name",
11486
- "description",
11487
- "group",
11488
- "path"
11489
- ]
11504
+ keys: ["name", "description", "group", "path"]
11490
11505
  });
11491
11506
  }, [navigationEntries]);
11492
11507
  const updateSearchResults = useCallback(
@@ -11503,7 +11518,8 @@ function DefaultHomePage({
11503
11518
  },
11504
11519
  []
11505
11520
  );
11506
- const allGroups = [...groups];
11521
+ const filteredGroups = filteredUrls ? filteredNavigationEntries.map((entry) => entry.group) : [];
11522
+ const allGroups = filteredUrls ? filteredGroups.filter((group, index) => filteredGroups.indexOf(group) === index) : [...groups];
11507
11523
  if (filteredNavigationEntries.filter((e) => !e.group).length > 0 || filteredNavigationEntries.length === 0) {
11508
11524
  allGroups.push(void 0);
11509
11525
  }
@@ -11559,7 +11575,7 @@ function DefaultHomePage({
11559
11575
  ]
11560
11576
  }
11561
11577
  ),
11562
- /* @__PURE__ */ jsx(FavouritesView, { hidden: Boolean(filteredUrls) }),
11578
+ /* @__PURE__ */ jsx(FavouritesView, { hidden: performingSearch }),
11563
11579
  additionalChildrenStart,
11564
11580
  additionalPluginChildrenStart,
11565
11581
  allGroups.map((group, index) => {
@@ -11576,7 +11592,7 @@ function DefaultHomePage({
11576
11592
  });
11577
11593
  }
11578
11594
  const thisGroupCollections = filteredNavigationEntries.filter((entry) => entry.group === group || !entry.group && group === void 0);
11579
- if (thisGroupCollections.length === 0 && AdditionalCards.length === 0)
11595
+ if (thisGroupCollections.length === 0 && (AdditionalCards.length === 0 || performingSearch))
11580
11596
  return null;
11581
11597
  return /* @__PURE__ */ jsx(
11582
11598
  NavigationGroup,
@@ -12240,7 +12256,7 @@ const EntityCollectionView = React__default.memo(
12240
12256
  }) {
12241
12257
  const context = useFireCMSContext();
12242
12258
  const fullPath = fullPathProp ?? collectionProp.path;
12243
- const dataSource = useDataSource(collectionProp);
12259
+ const dataSource = useDataSource();
12244
12260
  const navigation = useNavigationController();
12245
12261
  const sideEntityController = useSideEntityController();
12246
12262
  const authController = useAuthController();
@@ -12374,7 +12390,7 @@ const EntityCollectionView = React__default.memo(
12374
12390
  value,
12375
12391
  property,
12376
12392
  entityId
12377
- }) => dataSource.checkUniqueField(fullPath, name, value, entityId, collection.databaseId),
12393
+ }) => dataSource.checkUniqueField(fullPath, name, value, entityId, collection),
12378
12394
  [fullPath]
12379
12395
  );
12380
12396
  const onValueChange = ({
@@ -12754,7 +12770,7 @@ function EntitiesCount({
12754
12770
  sortBy,
12755
12771
  onCountChange
12756
12772
  }) {
12757
- const dataSource = useDataSource(collection);
12773
+ const dataSource = useDataSource();
12758
12774
  const navigation = useNavigationController();
12759
12775
  const [count, setCount] = useState(void 0);
12760
12776
  const [error, setError] = useState(void 0);
@@ -13275,7 +13291,8 @@ function ArrayContainer({
13275
13291
  onInternalIdAdded,
13276
13292
  includeAddButton,
13277
13293
  newDefaultEntry,
13278
- onValueChange
13294
+ onValueChange,
13295
+ className
13279
13296
  }) {
13280
13297
  const hasValue = value && Array.isArray(value) && value.length > 0;
13281
13298
  const internalIdsRef = useRef(buildIdsMap(value));
@@ -13364,6 +13381,7 @@ function ArrayContainer({
13364
13381
  children: (droppableProvided, droppableSnapshot) => /* @__PURE__ */ jsxs(
13365
13382
  "div",
13366
13383
  {
13384
+ className,
13367
13385
  ...droppableProvided.droppableProps,
13368
13386
  ref: droppableProvided.innerRef,
13369
13387
  children: [
@@ -13434,7 +13452,7 @@ function ArrayContainerItem({
13434
13452
  ref: provided.innerRef,
13435
13453
  ...provided.draggableProps,
13436
13454
  style: provided.draggableProps.style,
13437
- className: `${isDragging || onHover ? fieldBackgroundHoverMixin : ""} mb-1 rounded-md opacity-100`,
13455
+ className: `${isDragging || onHover ? "hover:bg-slate-50 dark:hover:bg-gray-800 dark:hover:bg-opacity-20" : ""} mb-1 rounded-md opacity-100`,
13438
13456
  children: /* @__PURE__ */ jsxs(
13439
13457
  "div",
13440
13458
  {
@@ -13443,7 +13461,7 @@ function ArrayContainerItem({
13443
13461
  /* @__PURE__ */ jsx(
13444
13462
  "div",
13445
13463
  {
13446
- className: "flex-grow w-[calc(100%-48px)] text-text-primary dark:text-text-primary-dark bg-white dark:bg-gray-900 bg-opacity-80 dark:bg-opacity-80",
13464
+ className: "flex-grow w-[calc(100%-48px)] text-text-primary dark:text-text-primary-dark",
13447
13465
  children: buildEntry(index, internalId)
13448
13466
  }
13449
13467
  ),
@@ -13753,7 +13771,8 @@ function FormikArrayContainer({
13753
13771
  onInternalIdAdded,
13754
13772
  includeAddButton,
13755
13773
  newDefaultEntry = null,
13756
- setFieldValue
13774
+ setFieldValue,
13775
+ className
13757
13776
  }) {
13758
13777
  return /* @__PURE__ */ jsx(
13759
13778
  ArrayContainer,
@@ -13767,6 +13786,7 @@ function FormikArrayContainer({
13767
13786
  onInternalIdAdded,
13768
13787
  includeAddButton,
13769
13788
  newDefaultEntry,
13789
+ className,
13770
13790
  onValueChange: (value2) => setFieldValue(name, value2)
13771
13791
  }
13772
13792
  );
@@ -14106,10 +14126,10 @@ function ArrayOfReferencesFieldBinding({
14106
14126
  forceFilter: ofProperty.forceFilter
14107
14127
  }
14108
14128
  );
14109
- const onEntryClick = useCallback((e) => {
14129
+ const onEntryClick = (e) => {
14110
14130
  e.preventDefault();
14111
14131
  referenceDialogController.open();
14112
- }, [referenceDialogController]);
14132
+ };
14113
14133
  const buildEntry = useCallback((index, internalId) => {
14114
14134
  const entryValue = value && value.length > index ? value[index] : void 0;
14115
14135
  if (!entryValue)
@@ -14137,7 +14157,7 @@ function ArrayOfReferencesFieldBinding({
14137
14157
  icon: getIconForProperty(property, "small"),
14138
14158
  required: property.validation?.required,
14139
14159
  title: property.name,
14140
- className: "flex-grow text-text-secondary dark:text-text-secondary-dark"
14160
+ className: "flex flex-grow text-text-secondary dark:text-text-secondary-dark"
14141
14161
  }
14142
14162
  ),
14143
14163
  Array.isArray(value) && /* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "px-4", children: [
@@ -14170,7 +14190,7 @@ function ArrayOfReferencesFieldBinding({
14170
14190
  Button,
14171
14191
  {
14172
14192
  className: "my-4 justify-center text-left",
14173
- variant: "outlined",
14193
+ variant: "text",
14174
14194
  color: "primary",
14175
14195
  disabled: isSubmitting,
14176
14196
  onClick: onEntryClick,
@@ -14929,10 +14949,10 @@ function ReferenceFieldBindingInternal({
14929
14949
  forceFilter: property.forceFilter
14930
14950
  }
14931
14951
  );
14932
- const onEntryClick = useCallback((e) => {
14952
+ const onEntryClick = (e) => {
14933
14953
  e.preventDefault();
14934
14954
  referenceDialogController.open();
14935
- }, [referenceDialogController]);
14955
+ };
14936
14956
  return /* @__PURE__ */ jsxs(Fragment, { children: [
14937
14957
  !minimalistView && /* @__PURE__ */ jsx(
14938
14958
  LabelWithIconAndTooltip,
@@ -14974,7 +14994,13 @@ function ReferenceFieldBindingInternal({
14974
14994
  onClick: onEntryClick,
14975
14995
  size: "medium",
14976
14996
  children: [
14977
- /* @__PURE__ */ jsx(EmptyValue, {}),
14997
+ /* @__PURE__ */ jsx(
14998
+ IconForView,
14999
+ {
15000
+ collectionOrView: collection,
15001
+ className: "text-gray-300 dark:text-gray-600"
15002
+ }
15003
+ ),
14978
15004
  `Edit ${property.name}`.toUpperCase()
14979
15005
  ]
14980
15006
  }
@@ -16079,6 +16105,7 @@ function BlockFieldBinding({
16079
16105
  FormikArrayContainer,
16080
16106
  {
16081
16107
  value,
16108
+ className: "flex flex-col gap-3",
16082
16109
  name: propertyKey,
16083
16110
  addLabel: property.name ? "Add entry to " + property.name : "Add entry",
16084
16111
  buildEntry,
@@ -16160,7 +16187,7 @@ function BlockEntry({
16160
16187
  formex.setFieldValue(typeFieldName, newType);
16161
16188
  formex.setFieldValue(valueFieldName, newSelectedProperty ? getDefaultValueFor(newSelectedProperty) : null);
16162
16189
  };
16163
- return /* @__PURE__ */ jsxs("div", { className: cls(paperMixin, "bg-transparent p-2 mb-4"), children: [
16190
+ return /* @__PURE__ */ jsxs("div", { className: cls(paperMixin, "bg-transparent p-2"), children: [
16164
16191
  /* @__PURE__ */ jsx(
16165
16192
  Field,
16166
16193
  {
@@ -17311,7 +17338,7 @@ function EntityEditViewInner({
17311
17338
  }, false, 2e3);
17312
17339
  const inputCollection = collection;
17313
17340
  const authController = useAuthController();
17314
- const dataSource = useDataSource(collection);
17341
+ const dataSource = useDataSource();
17315
17342
  const sideDialogContext = useSideDialogContext();
17316
17343
  const sideEntityController = useSideEntityController();
17317
17344
  const snackbarController = useSnackbarController();
@@ -17333,7 +17360,7 @@ function EntityEditViewInner({
17333
17360
  if (mustSetCustomId) {
17334
17361
  return void 0;
17335
17362
  } else {
17336
- return dataSource.generateEntityId(path);
17363
+ return dataSource.generateEntityId(path, collection);
17337
17364
  }
17338
17365
  } else {
17339
17366
  return entityIdProp;
@@ -17350,8 +17377,8 @@ function EntityEditViewInner({
17350
17377
  entityId
17351
17378
  }
17352
17379
  );
17353
- const selectedTabRef = useRef(defaultSelectedView ?? MAIN_TAB_VALUE);
17354
- const mainViewVisible = selectedTabRef.current === MAIN_TAB_VALUE;
17380
+ const [selectedTab, setSelectedTab] = useState(defaultSelectedView ?? MAIN_TAB_VALUE);
17381
+ const mainViewVisible = selectedTab === MAIN_TAB_VALUE;
17355
17382
  const subcollections = (collection.subcollections ?? []).filter((c) => !c.hideFromNavigation);
17356
17383
  const subcollectionsCount = subcollections?.length ?? 0;
17357
17384
  const customViews = collection.entityViews;
@@ -17411,7 +17438,7 @@ function EntityEditViewInner({
17411
17438
  sideEntityController.replace({
17412
17439
  path,
17413
17440
  entityId: updatedEntity.id,
17414
- selectedSubPath: MAIN_TAB_VALUE === selectedTabRef.current ? void 0 : selectedTabRef.current,
17441
+ selectedSubPath: MAIN_TAB_VALUE === selectedTab ? void 0 : selectedTab,
17415
17442
  updateUrl: true,
17416
17443
  collection
17417
17444
  });
@@ -17559,13 +17586,13 @@ function EntityEditViewInner({
17559
17586
  formex
17560
17587
  };
17561
17588
  const resolvedEntityViews = customViews ? customViews.map((e) => resolveEntityView(e, customizationController.entityViews)).filter(Boolean) : [];
17562
- const selectedEntityView = resolvedEntityViews.find((e) => e.key === selectedTabRef.current);
17563
- const shouldShowEntityActions = !autoSave && (selectedTabRef.current === MAIN_TAB_VALUE || selectedEntityView?.includeActions);
17589
+ const selectedEntityView = resolvedEntityViews.find((e) => e.key === selectedTab);
17590
+ const shouldShowEntityActions = !autoSave && (selectedTab === MAIN_TAB_VALUE || selectedEntityView?.includeActions);
17564
17591
  const customViewsView = customViews && resolvedEntityViews.map(
17565
17592
  (customView, colIndex) => {
17566
17593
  if (!customView)
17567
17594
  return null;
17568
- if (selectedTabRef.current !== customView.key)
17595
+ if (selectedTab !== customView.key)
17569
17596
  return null;
17570
17597
  const Builder = customView.Builder;
17571
17598
  if (!Builder) {
@@ -17600,7 +17627,7 @@ function EntityEditViewInner({
17600
17627
  (subcollection, colIndex) => {
17601
17628
  const subcollectionId = subcollection.id ?? subcollection.path;
17602
17629
  const fullPath = usedEntity ? `${path}/${usedEntity?.id}/${removeInitialAndTrailingSlashes(subcollectionId)}` : void 0;
17603
- if (selectedTabRef.current !== subcollectionId)
17630
+ if (selectedTab !== subcollectionId)
17604
17631
  return null;
17605
17632
  return /* @__PURE__ */ jsxs(
17606
17633
  "div",
@@ -17634,14 +17661,16 @@ function EntityEditViewInner({
17634
17661
  onValuesAreModified(false);
17635
17662
  }, []);
17636
17663
  const onSideTabClick = (value) => {
17637
- selectedTabRef.current = value;
17638
- sideEntityController.replace({
17639
- path,
17640
- entityId,
17641
- selectedSubPath: value === MAIN_TAB_VALUE ? void 0 : value,
17642
- updateUrl: true,
17643
- collection
17644
- });
17664
+ setSelectedTab(value);
17665
+ if (status === "existing") {
17666
+ sideEntityController.replace({
17667
+ path,
17668
+ entityId,
17669
+ selectedSubPath: value === MAIN_TAB_VALUE ? void 0 : value,
17670
+ updateUrl: true,
17671
+ collection
17672
+ });
17673
+ }
17645
17674
  };
17646
17675
  const onIdUpdateError = useCallback((error) => {
17647
17676
  snackbarController.open({
@@ -17706,7 +17735,7 @@ function EntityEditViewInner({
17706
17735
  name,
17707
17736
  value,
17708
17737
  property
17709
- }) => dataSource.checkUniqueField(path, name, value, entityId, collection.databaseId),
17738
+ }) => dataSource.checkUniqueField(path, name, value, entityId, collection),
17710
17739
  [dataSource, path, entityId]
17711
17740
  );
17712
17741
  const validationSchema = useMemo(
@@ -18044,7 +18073,7 @@ function EntityEditViewInner({
18044
18073
  /* @__PURE__ */ jsxs(
18045
18074
  Tabs,
18046
18075
  {
18047
- value: selectedTabRef.current,
18076
+ value: selectedTab,
18048
18077
  onValueChange: (value) => {
18049
18078
  onSideTabClick(value);
18050
18079
  },
@@ -18259,11 +18288,9 @@ function SideDialogView({
18259
18288
  setDrawerCloseRequested(false);
18260
18289
  };
18261
18290
  const onCloseRequest = (force) => {
18262
- console.log("onCloseRequest", blocked, force);
18263
18291
  if (blocked && !force) {
18264
18292
  setDrawerCloseRequested(true);
18265
18293
  } else {
18266
- console.log("onCloseRequest closing");
18267
18294
  sideDialogsController.close();
18268
18295
  panel?.onClose?.();
18269
18296
  }
@@ -18457,6 +18484,15 @@ const useBuildSideEntityController = (navigation, sideDialogsController) => {
18457
18484
  initialised.current = true;
18458
18485
  }
18459
18486
  }, [location, navigation.loading, navigation.isUrlCollectionPath, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, sideDialogsController, smallLayout, navigation]);
18487
+ useEffect(() => {
18488
+ const updatedSidePanels = sideDialogsController.sidePanels.map((sidePanelProps) => {
18489
+ if (sidePanelProps.additional) {
18490
+ return propsToSidePanel(sidePanelProps.additional, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, smallLayout);
18491
+ }
18492
+ return sidePanelProps;
18493
+ });
18494
+ sideDialogsController.setSidePanels(updatedSidePanels);
18495
+ }, [smallLayout]);
18460
18496
  const close = useCallback(() => {
18461
18497
  sideDialogsController.close();
18462
18498
  }, [sideDialogsController]);
@@ -18549,7 +18585,8 @@ const propsToSidePanel = (props, buildUrlCollectionPath, resolveAliasesFrom, sma
18549
18585
  urlPath: newPath,
18550
18586
  parentUrlPath: buildUrlCollectionPath(collectionPath),
18551
18587
  width: entityViewWidth,
18552
- onClose: props.onClose
18588
+ onClose: props.onClose,
18589
+ additional: props
18553
18590
  };
18554
18591
  };
18555
18592
  function useBuildSideDialogsController() {
@@ -18642,6 +18679,7 @@ function useBuildSideDialogsController() {
18642
18679
  }, [location, navigate, sidePanels]);
18643
18680
  return {
18644
18681
  sidePanels,
18682
+ setSidePanels: updateSidePanels,
18645
18683
  close,
18646
18684
  open,
18647
18685
  replace
@@ -18677,7 +18715,8 @@ function useBuildDataSource({
18677
18715
  orderBy,
18678
18716
  order
18679
18717
  }) => {
18680
- return delegate.fetchCollection({
18718
+ const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
18719
+ return usedDelegate.fetchCollection({
18681
18720
  path,
18682
18721
  filter,
18683
18722
  limit,
@@ -18717,10 +18756,10 @@ function useBuildDataSource({
18717
18756
  onError
18718
18757
  }) => {
18719
18758
  const collection = collectionProp ?? navigationController.getCollection(path);
18720
- Boolean(collection?.collectionGroup);
18721
- if (!delegate.listenCollection)
18759
+ const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
18760
+ if (!usedDelegate.listenCollection)
18722
18761
  throw Error("useBuildDataSource delegate not initialised");
18723
- return delegate.listenCollection({
18762
+ return usedDelegate.listenCollection({
18724
18763
  path,
18725
18764
  filter,
18726
18765
  limit,
@@ -18744,11 +18783,14 @@ function useBuildDataSource({
18744
18783
  path,
18745
18784
  entityId,
18746
18785
  collection
18747
- }) => delegate.fetchEntity({
18748
- path,
18749
- entityId,
18750
- collection
18751
- }), [delegate]),
18786
+ }) => {
18787
+ const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
18788
+ return usedDelegate.fetchEntity({
18789
+ path,
18790
+ entityId,
18791
+ collection
18792
+ });
18793
+ }, [delegate.fetchEntity]),
18752
18794
  /**
18753
18795
  *
18754
18796
  * @param path
@@ -18766,9 +18808,10 @@ function useBuildDataSource({
18766
18808
  onUpdate,
18767
18809
  onError
18768
18810
  }) => {
18769
- if (!delegate.listenEntity)
18811
+ const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
18812
+ if (!usedDelegate.listenEntity)
18770
18813
  throw Error("useBuildDataSource delegate not initialised");
18771
- return delegate.listenEntity({
18814
+ return usedDelegate.listenEntity({
18772
18815
  path,
18773
18816
  entityId,
18774
18817
  onUpdate,
@@ -18795,6 +18838,7 @@ function useBuildDataSource({
18795
18838
  status
18796
18839
  }) => {
18797
18840
  const collection = collectionProp ?? navigationController.getCollection(path);
18841
+ const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
18798
18842
  console.log("useBuildDatasource save", {
18799
18843
  path,
18800
18844
  entityId,
@@ -18810,29 +18854,29 @@ function useBuildDataSource({
18810
18854
  fields: propertyConfigs
18811
18855
  }) : void 0;
18812
18856
  const properties = resolvedCollection?.properties;
18813
- const firestoreValues = delegate.cmsToDelegateModel(
18857
+ const firestoreValues = usedDelegate.cmsToDelegateModel(
18814
18858
  values
18815
18859
  );
18816
- const updatedFirestoreValues = properties ? updateDateAutoValues(
18860
+ const updatedValues = properties ? updateDateAutoValues(
18817
18861
  {
18818
18862
  inputValues: firestoreValues,
18819
18863
  properties,
18820
18864
  status,
18821
- timestampNowValue: delegate.currentTime?.() ?? /* @__PURE__ */ new Date(),
18822
- setDateToMidnight: delegate.setDateToMidnight
18865
+ timestampNowValue: usedDelegate.currentTime?.() ?? /* @__PURE__ */ new Date(),
18866
+ setDateToMidnight: usedDelegate.setDateToMidnight
18823
18867
  }
18824
18868
  ) : firestoreValues;
18825
- return delegate.saveEntity({
18869
+ return usedDelegate.saveEntity({
18826
18870
  path,
18827
18871
  collection,
18828
18872
  entityId,
18829
- values: updatedFirestoreValues,
18873
+ values: updatedValues,
18830
18874
  status
18831
18875
  }).then((res) => {
18832
18876
  return {
18833
18877
  id: res.id,
18834
18878
  path: res.path,
18835
- values: delegate.delegateToCMSModel(updatedFirestoreValues)
18879
+ values: usedDelegate.delegateToCMSModel(updatedValues)
18836
18880
  };
18837
18881
  });
18838
18882
  }, [delegate.saveEntity, navigationController.getCollection]),
@@ -18843,9 +18887,11 @@ function useBuildDataSource({
18843
18887
  * @group Firestore
18844
18888
  */
18845
18889
  deleteEntity: useCallback(({
18846
- entity
18890
+ entity,
18891
+ collection
18847
18892
  }) => {
18848
- return delegate.deleteEntity({ entity });
18893
+ const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
18894
+ return usedDelegate.deleteEntity({ entity, collection });
18849
18895
  }, [delegate.deleteEntity]),
18850
18896
  /**
18851
18897
  * Check if the given property is unique in the given collection
@@ -18857,11 +18903,13 @@ function useBuildDataSource({
18857
18903
  * @return `true` if there are no other fields besides the given entity
18858
18904
  * @group Firestore
18859
18905
  */
18860
- checkUniqueField: useCallback((path, name, value, entityId, databaseId) => {
18861
- return delegate.checkUniqueField(path, name, value, entityId, databaseId);
18906
+ checkUniqueField: useCallback((path, name, value, entityId, collection) => {
18907
+ const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
18908
+ return usedDelegate.checkUniqueField(path, name, value, entityId, collection);
18862
18909
  }, [delegate.checkUniqueField]),
18863
- generateEntityId: useCallback((path) => {
18864
- return delegate.generateEntityId(path);
18910
+ generateEntityId: useCallback((path, collection) => {
18911
+ const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
18912
+ return usedDelegate.generateEntityId(path, collection);
18865
18913
  }, [delegate.generateEntityId]),
18866
18914
  countEntities: delegate.countEntities ? async ({
18867
18915
  path,
@@ -18870,7 +18918,8 @@ function useBuildDataSource({
18870
18918
  order,
18871
18919
  orderBy
18872
18920
  }) => {
18873
- return delegate.countEntities({
18921
+ const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
18922
+ return usedDelegate.countEntities({
18874
18923
  path,
18875
18924
  filter,
18876
18925
  orderBy,
@@ -18896,9 +18945,10 @@ function useBuildDataSource({
18896
18945
  );
18897
18946
  }, [delegate.isFilterCombinationValid]),
18898
18947
  initTextSearch: useCallback(async (props) => {
18899
- if (!delegate.initTextSearch)
18948
+ const usedDelegate = props.collection?.overrides?.dataSourceDelegate ?? delegate;
18949
+ if (!usedDelegate.initTextSearch)
18900
18950
  return false;
18901
- return delegate.initTextSearch(props);
18951
+ return usedDelegate.initTextSearch(props);
18902
18952
  }, [delegate.initTextSearch])
18903
18953
  };
18904
18954
  }