@firecms/core 3.0.0-alpha.27 → 3.0.0-alpha.29

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 (91) hide show
  1. package/dist/components/Popover.d.ts +3 -1
  2. package/dist/core/FireCMS.d.ts +2 -2
  3. package/dist/core/builders.d.ts +5 -5
  4. package/dist/core/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +4 -2
  5. package/dist/core/components/EntityCollectionTable/filters/ReferenceFilterField.d.ts +3 -3
  6. package/dist/core/components/EntityCollectionTable/internal/EntityCollectionRowActions.d.ts +15 -11
  7. package/dist/core/components/EntityCollectionTable/internal/default_entity_actions.d.ts +5 -0
  8. package/dist/core/components/EntityCollectionTable/types.d.ts +1 -37
  9. package/dist/core/components/FieldConfigBadge.d.ts +3 -3
  10. package/dist/core/components/VirtualTable/VirtualTableHeader.d.ts +2 -2
  11. package/dist/core/components/VirtualTable/VirtualTableProps.d.ts +1 -1
  12. package/dist/core/contexts/DialogsProvider.d.ts +4 -0
  13. package/dist/core/form_field_configs.d.ts +3 -3
  14. package/dist/core/index.d.ts +1 -1
  15. package/dist/core/internal/useBuildNavigationContext.d.ts +3 -3
  16. package/dist/core/util/property_utils.d.ts +5 -5
  17. package/dist/core/util/references.d.ts +2 -2
  18. package/dist/core/util/resolutions.d.ts +6 -6
  19. package/dist/hooks/index.d.ts +1 -0
  20. package/dist/hooks/useBuildDataSource.d.ts +23 -0
  21. package/dist/hooks/useDialogsController.d.ts +11 -0
  22. package/dist/index.es.js +8996 -8583
  23. package/dist/index.es.js.map +1 -1
  24. package/dist/index.umd.js +67 -67
  25. package/dist/index.umd.js.map +1 -1
  26. package/dist/styles.d.ts +1 -1
  27. package/dist/types/collections.d.ts +36 -13
  28. package/dist/types/datasource.d.ts +120 -11
  29. package/dist/types/dialogs_controller.d.ts +30 -0
  30. package/dist/types/entity_actions.d.ts +33 -0
  31. package/dist/types/fields.d.ts +1 -1
  32. package/dist/types/firecms.d.ts +8 -8
  33. package/dist/types/firecms_context.d.ts +10 -3
  34. package/dist/types/index.d.ts +2 -1
  35. package/dist/types/navigation.d.ts +3 -3
  36. package/dist/types/plugins.d.ts +11 -10
  37. package/dist/types/properties.d.ts +1 -1
  38. package/dist/types/{field_config.d.ts → property_config.d.ts} +3 -4
  39. package/package.json +3 -3
  40. package/src/components/Popover.tsx +10 -3
  41. package/src/components/Sheet.tsx +1 -0
  42. package/src/components/TextareaAutosize.tsx +2 -1
  43. package/src/core/FireCMS.tsx +9 -6
  44. package/src/core/builders.ts +11 -11
  45. package/src/core/components/ArrayContainer.tsx +1 -1
  46. package/src/core/components/EntityCollectionTable/EntityCollectionTable.tsx +20 -13
  47. package/src/core/components/EntityCollectionTable/EntityCollectionTableProps.tsx +5 -2
  48. package/src/core/components/EntityCollectionTable/filters/ReferenceFilterField.tsx +11 -6
  49. package/src/core/components/EntityCollectionTable/internal/EntityCollectionRowActions.tsx +96 -79
  50. package/src/core/components/EntityCollectionTable/internal/PropertyTableCell.tsx +2 -2
  51. package/src/core/components/EntityCollectionTable/internal/default_entity_actions.tsx +107 -0
  52. package/src/core/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +6 -2
  53. package/src/core/components/EntityCollectionTable/types.tsx +1 -56
  54. package/src/core/components/EntityCollectionView/EntityCollectionView.tsx +67 -43
  55. package/src/core/components/FieldConfigBadge.tsx +4 -4
  56. package/src/core/components/ReferenceSelectionInner.tsx +2 -2
  57. package/src/core/components/VirtualTable/VirtualTable.tsx +4 -6
  58. package/src/core/components/VirtualTable/VirtualTableHeader.tsx +21 -18
  59. package/src/core/components/VirtualTable/VirtualTableProps.tsx +1 -1
  60. package/src/core/contexts/DialogsProvider.tsx +50 -0
  61. package/src/core/form_field_configs.tsx +5 -5
  62. package/src/core/index.tsx +1 -1
  63. package/src/core/internal/useBuildNavigationContext.tsx +13 -13
  64. package/src/core/internal/useBuildSideEntityController.tsx +9 -1
  65. package/src/core/util/property_utils.tsx +5 -5
  66. package/src/core/util/references.ts +2 -2
  67. package/src/core/util/resolutions.ts +16 -11
  68. package/src/form/EntityForm.tsx +64 -7
  69. package/src/form/PropertyFieldBinding.tsx +4 -4
  70. package/src/form/field_bindings/KeyValueFieldBinding.tsx +1 -1
  71. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +4 -6
  72. package/src/hooks/index.tsx +1 -0
  73. package/src/hooks/useBuildDataSource.ts +351 -0
  74. package/src/hooks/useDialogsController.tsx +14 -0
  75. package/src/hooks/useFireCMSContext.tsx +5 -11
  76. package/src/preview/property_previews/StringPropertyPreview.tsx +4 -2
  77. package/src/styles.ts +1 -1
  78. package/src/types/collections.ts +36 -17
  79. package/src/types/datasource.ts +174 -10
  80. package/src/types/dialogs_controller.tsx +31 -0
  81. package/src/types/entity_actions.tsx +36 -0
  82. package/src/types/fields.tsx +1 -1
  83. package/src/types/firecms.tsx +8 -8
  84. package/src/types/firecms_context.tsx +11 -3
  85. package/src/types/index.ts +2 -1
  86. package/src/types/navigation.ts +3 -3
  87. package/src/types/plugins.tsx +11 -10
  88. package/src/types/properties.ts +1 -1
  89. package/src/types/{field_config.tsx → property_config.tsx} +3 -4
  90. /package/dist/core/contexts/{SnackbarContext.d.ts → SnackbarProvider.d.ts} +0 -0
  91. /package/src/core/contexts/{SnackbarContext.tsx → SnackbarProvider.tsx} +0 -0
@@ -55,6 +55,7 @@ export const TextareaAutosize = React.forwardRef(function TextareaAutosize(
55
55
  onFocus,
56
56
  onBlur,
57
57
  sizeRef,
58
+ ignoreBoxSizing,
58
59
  ...other
59
60
  } = props;
60
61
 
@@ -124,7 +125,7 @@ export const TextareaAutosize = React.forwardRef(function TextareaAutosize(
124
125
  outerHeight = Math.max(outerHeight, singleRowHeight, minHeight);
125
126
 
126
127
  // Take the box sizing into account for applying this value as a style.
127
- const outerHeightStyle = outerHeight + (!props.ignoreBoxSizing && boxSizing === "border-box" ? padding + border : 0);
128
+ const outerHeightStyle = outerHeight + (!ignoreBoxSizing && boxSizing === "border-box" ? padding + border : 0);
128
129
 
129
130
  const overflow = Math.abs(outerHeight - innerHeight) <= 1;
130
131
 
@@ -1,6 +1,6 @@
1
1
  import React, { useMemo } from "react";
2
2
 
3
- import { FireCMSContext, FireCMSPlugin, FireCMSProps, User } from "../types";
3
+ import { EntityCollection, FireCMSContext, FireCMSPlugin, FireCMSProps, User } from "../types";
4
4
  import { BreadcrumbsProvider } from "./contexts/BreacrumbsContext";
5
5
  import { ModeControllerContext } from "./contexts/ModeController";
6
6
  import { useBuildSideEntityController } from "./internal/useBuildSideEntityController";
@@ -17,6 +17,7 @@ import { AuthControllerContext } from "./contexts/AuthControllerContext";
17
17
  import { SideDialogsControllerContext } from "./contexts/SideDialogsControllerContext";
18
18
  import { useLocaleConfig } from "./internal/useLocaleConfig";
19
19
  import { CenteredView } from "../components";
20
+ import { DialogsProvider } from "./contexts/DialogsProvider";
20
21
 
21
22
  const DEFAULT_BASE_PATH = "/";
22
23
  const DEFAULT_COLLECTION_PATH = "/c";
@@ -34,7 +35,7 @@ const DEFAULT_COLLECTION_PATH = "/c";
34
35
  * @constructor
35
36
  * @category Core
36
37
  */
37
- export function FireCMS<UserType extends User>(props: FireCMSProps<UserType>) {
38
+ export function FireCMS<UserType extends User, EC extends EntityCollection>(props: FireCMSProps<UserType, EC>) {
38
39
 
39
40
  const modeController = useModeController();
40
41
  const {
@@ -124,10 +125,12 @@ export function FireCMS<UserType extends User>(props: FireCMSProps<UserType>) {
124
125
  <NavigationContextInstance.Provider
125
126
  value={navigation}>
126
127
  <BreadcrumbsProvider>
127
- <FireCMSInternal
128
- loading={loading}>
129
- {children}
130
- </FireCMSInternal>
128
+ <DialogsProvider>
129
+ <FireCMSInternal
130
+ loading={loading}>
131
+ {children}
132
+ </FireCMSInternal>
133
+ </DialogsProvider>
131
134
  </BreadcrumbsProvider>
132
135
  </NavigationContextInstance.Provider>
133
136
  </SideEntityControllerContext.Provider>
@@ -8,7 +8,7 @@ import {
8
8
  EntityCollection,
9
9
  EnumValueConfig,
10
10
  EnumValues,
11
- FieldConfig,
11
+ PropertyConfig,
12
12
  GeopointProperty,
13
13
  MapProperty,
14
14
  NumberProperty,
@@ -27,10 +27,10 @@ import {
27
27
  * @category Builder
28
28
  */
29
29
  export function buildCollection<M extends Record<string, any> = any,
30
- AdditionalKey extends string = string,
30
+
31
31
  UserType extends User = User>(
32
- collection: EntityCollection<M, AdditionalKey, UserType>
33
- ): EntityCollection<M, AdditionalKey, UserType> {
32
+ collection: EntityCollection<M, UserType>
33
+ ): EntityCollection<M, UserType> {
34
34
  return collection;
35
35
  }
36
36
 
@@ -121,20 +121,20 @@ export function buildEntityCallbacks<M extends Record<string, any> = any>(
121
121
  * @param additionalFieldDelegate
122
122
  * @category Builder
123
123
  */
124
- export function buildAdditionalFieldDelegate<M extends Record<string, any>, AdditionalKey extends string = string, UserType extends User = User>(
125
- additionalFieldDelegate: AdditionalFieldDelegate<M, AdditionalKey, UserType>
126
- ): AdditionalFieldDelegate<M, AdditionalKey, UserType> {
124
+ export function buildAdditionalFieldDelegate<M extends Record<string, any>, UserType extends User = User>(
125
+ additionalFieldDelegate: AdditionalFieldDelegate<M, UserType>
126
+ ): AdditionalFieldDelegate<M, UserType> {
127
127
  return additionalFieldDelegate;
128
128
  }
129
129
 
130
130
  /**
131
131
  * Identity function we use to defeat the type system of Typescript and build
132
132
  * additional field delegates views with all its properties
133
- * @param fieldConfig
133
+ * @param propertyConfig
134
134
  * @category Builder
135
135
  */
136
136
  export function buildFieldConfig<T extends CMSType = CMSType>(
137
- fieldConfig: FieldConfig<T>
138
- ): FieldConfig<T> {
139
- return fieldConfig;
137
+ propertyConfig: PropertyConfig<T>
138
+ ): PropertyConfig<T> {
139
+ return propertyConfig;
140
140
  }
@@ -175,7 +175,7 @@ export function ArrayContainer<T>({
175
175
 
176
176
  {droppableProvided.placeholder}
177
177
 
178
- {includeAddButton && <div className="p-4 justify-center text-left">
178
+ {includeAddButton && <div className="py-4 justify-center text-left">
179
179
  <Button
180
180
  variant={size === "small" ? "text" : "outlined"}
181
181
  size={size === "small" ? "small" : "medium"}
@@ -63,7 +63,7 @@ export const useEntityCollectionTableController = () => useContext<EntityCollect
63
63
  * @category Components
64
64
  */
65
65
  export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>(
66
- function EntityCollectionTable<M extends Record<string, any>, AdditionalKey extends string, UserType extends User>
66
+ function EntityCollectionTable<M extends Record<string, any>, UserType extends User>
67
67
  ({
68
68
  forceFilter,
69
69
  actionsStart,
@@ -110,7 +110,9 @@ export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>
110
110
  endAdornment,
111
111
  AddColumnComponent,
112
112
  AdditionalHeaderWidget,
113
- additionalIDHeaderWidget
113
+ additionalIDHeaderWidget,
114
+ emptyComponent,
115
+ getIdColumnWidth
114
116
  }: EntityCollectionTableProps<M>) {
115
117
 
116
118
  const largeLayout = useLargeLayout();
@@ -154,12 +156,12 @@ export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>
154
156
 
155
157
  const onTextSearch = useCallback((newSearchString?: string) => setSearchString?.(newSearchString), []);
156
158
 
157
- const additionalFieldsMap: Record<string, AdditionalFieldDelegate<M, string, UserType>> = useMemo(() => {
159
+ const additionalFieldsMap: Record<string, AdditionalFieldDelegate<M, UserType>> = useMemo(() => {
158
160
  return (additionalFields
159
161
  ? additionalFields
160
- .map((aC) => ({ [aC.id]: aC as AdditionalFieldDelegate<M, string, any> }))
162
+ .map((aC) => ({ [aC.id]: aC as AdditionalFieldDelegate<M, any> }))
161
163
  .reduce((a, b) => ({ ...a, ...b }), {})
162
- : {}) as Record<string, AdditionalFieldDelegate<M, string, UserType>>;
164
+ : {}) as Record<string, AdditionalFieldDelegate<M, UserType>>;
163
165
  }, [additionalFields]);
164
166
 
165
167
  // on ESC key press
@@ -198,7 +200,11 @@ export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>
198
200
 
199
201
  let disabled = column.custom?.disabled;
200
202
  const propertyValue = entity.values ? getValueInPath(entity.values, propertyKey) : undefined;
201
- const property = getPropertyFor?.({ propertyKey, propertyValue, entity }) ?? column.custom.resolvedProperty;
203
+ const property = getPropertyFor?.({
204
+ propertyKey,
205
+ propertyValue,
206
+ entity
207
+ }) ?? column.custom.resolvedProperty;
202
208
  if (!property?.disabled) {
203
209
  disabled = false;
204
210
  }
@@ -238,7 +244,7 @@ export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>
238
244
 
239
245
  const entity: Entity<M> = rowData;
240
246
 
241
- const additionalField = additionalFieldsMap[column.key as AdditionalKey];
247
+ const additionalField = additionalFieldsMap[column.key as string];
242
248
  const value = additionalField.dependencies
243
249
  ? Object.entries(entity.values)
244
250
  .filter(([key, value]) => additionalField.dependencies!.includes(key as Extract<keyof M, string>))
@@ -318,14 +324,14 @@ export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>
318
324
 
319
325
  const idColumn: VirtualTableColumn = useMemo(() => ({
320
326
  key: "id_ewcfedcswdf3",
321
- width: largeLayout ? 160 : 130,
327
+ width: getIdColumnWidth?.() ?? (largeLayout ? 160 : 130),
322
328
  title: "ID",
323
329
  resizable: false,
324
330
  frozen: largeLayout,
325
331
  headerAlign: "center",
326
332
  align: "center",
327
333
  AdditionalHeaderWidget: () => additionalIDHeaderWidget
328
- }), [largeLayout])
334
+ }), [getIdColumnWidth, largeLayout])
329
335
 
330
336
  const columns: VirtualTableColumn[] = useMemo(() => [
331
337
  idColumn,
@@ -410,6 +416,7 @@ export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>
410
416
  sortBy={sortBy}
411
417
  onSortByUpdate={setSortBy as ((sortBy?: [string, "asc" | "desc"]) => void)}
412
418
  hoverRow={hoverRow}
419
+ emptyComponent={emptyComponent}
413
420
  checkFilterCombination={checkFilterCombination}
414
421
  createFilterField={filterable ? createFilterField : undefined}
415
422
  rowClassName={useCallback((entity: Entity<M>) => {
@@ -433,8 +440,8 @@ function createFilterField({
433
440
  filterValue,
434
441
  setFilterValue,
435
442
  column,
436
- popupOpen,
437
- setPopupOpen
443
+ hidden,
444
+ setHidden
438
445
  }: FilterFormFieldProps<{
439
446
  resolvedProperty: ResolvedProperty,
440
447
  disabled: boolean,
@@ -459,8 +466,8 @@ function createFilterField({
459
466
  path={baseProperty.path}
460
467
  title={resolvedProperty?.name}
461
468
  previewProperties={baseProperty?.previewProperties}
462
- popupOpen={popupOpen}
463
- setPopupOpen={setPopupOpen}/>;
469
+ hidden={hidden}
470
+ setHidden={setHidden}/>;
464
471
  } else if (baseProperty.dataType === "number" || baseProperty.dataType === "string") {
465
472
  const name = baseProperty.name;
466
473
  const enumValues = baseProperty.enumValues ? enumToObjectEntries(baseProperty.enumValues) : undefined;
@@ -21,7 +21,7 @@ export type OnColumnResizeParams = { width: number, key: string };
21
21
  * @category Collection components
22
22
  */
23
23
  export type EntityCollectionTableProps<M extends Record<string, any>,
24
- AdditionalKey extends string = string,
24
+
25
25
  UserType extends User = User> = {
26
26
 
27
27
  /**
@@ -105,7 +105,7 @@ export type EntityCollectionTableProps<M extends Record<string, any>,
105
105
 
106
106
  inlineEditing?: boolean | ((entity: Entity<M>) => boolean);
107
107
 
108
- additionalFields?: AdditionalFieldDelegate<M, AdditionalKey, UserType>[];
108
+ additionalFields?: AdditionalFieldDelegate<M, UserType>[];
109
109
 
110
110
  defaultSize?: CollectionSize;
111
111
 
@@ -129,6 +129,9 @@ export type EntityCollectionTableProps<M extends Record<string, any>,
129
129
 
130
130
  additionalIDHeaderWidget?: React.ReactNode;
131
131
 
132
+ emptyComponent?: React.ReactNode;
133
+
134
+ getIdColumnWidth?: () => number;
132
135
  }
133
136
 
134
137
  export type GetPropertyForProps<M extends Record<string, any>> = {
@@ -15,8 +15,8 @@ interface ReferenceFilterFieldProps {
15
15
  path?: string;
16
16
  title?: string;
17
17
  previewProperties?: string[];
18
- popupOpen: boolean;
19
- setPopupOpen: (open: boolean) => void;
18
+ hidden: boolean;
19
+ setHidden: (hidden: boolean) => void;
20
20
  }
21
21
 
22
22
  const operationLabels = {
@@ -42,7 +42,7 @@ export function ReferenceFilterField({
42
42
  path,
43
43
  title,
44
44
  previewProperties,
45
- setPopupOpen
45
+ setHidden
46
46
  }: ReferenceFilterFieldProps) {
47
47
 
48
48
  const possibleOperations: (keyof typeof operationLabels) [] = isArray
@@ -118,13 +118,13 @@ export function ReferenceFilterField({
118
118
  onMultipleEntitiesSelected,
119
119
  selectedEntityIds,
120
120
  onClose: () => {
121
- setPopupOpen(true);
121
+ setHidden(false);
122
122
  }
123
123
  }
124
124
  );
125
125
 
126
126
  const doOpenDialog = () => {
127
- setPopupOpen(false);
127
+ setHidden(true);
128
128
  referenceDialogController.open();
129
129
  };
130
130
 
@@ -148,6 +148,10 @@ export function ReferenceFilterField({
148
148
  );
149
149
  };
150
150
 
151
+ console.log("ReferenceFilterField", {
152
+ internalValue
153
+
154
+ })
151
155
  return (
152
156
 
153
157
  <div className="flex w-[440px] flex-row">
@@ -175,7 +179,8 @@ export function ReferenceFilterField({
175
179
  </div>}
176
180
  {(!internalValue || (Array.isArray(internalValue) && internalValue.length === 0)) &&
177
181
  <Button onClick={doOpenDialog}
178
- className="h-full">
182
+ variant={"outlined"}
183
+ className="h-full w-full">
179
184
  {multiple ? "Select references" : "Select reference"}
180
185
  </Button>
181
186
  }
@@ -1,12 +1,11 @@
1
1
  import React, { MouseEvent, useCallback } from "react";
2
+ import equal from "react-fast-compare"
2
3
 
3
- import { CollectionSize, Entity } from "../../../../types";
4
- import { Checkbox, IconButton, Tooltip, Typography } from "../../../../components";
5
- import { useLargeLayout } from "../../../../hooks/useLargeLayout";
6
- import { DeleteIcon, FileCopyIcon, KeyboardTabIcon, MoreVertIcon } from "../../../../icons";
7
- import { Menu, MenuItem } from "../../../../components/Menu";
4
+ import { CollectionSize, Entity, EntityAction, EntityCollection, SelectionController } from "../../../../types";
5
+ import { Checkbox, cn, IconButton, Menu, MenuItem, Tooltip, Typography } from "../../../../components";
6
+ import { useFireCMSContext, useLargeLayout } from "../../../../hooks";
7
+ import { MoreVertIcon } from "../../../../icons";
8
8
  import { Skeleton } from "../../../../components/Skeleton";
9
- import { cn } from "../../../../components/util/cn";
10
9
 
11
10
  /**
12
11
  *
@@ -25,62 +24,57 @@ import { cn } from "../../../../components/util/cn";
25
24
  *
26
25
  * @category Collection components
27
26
  */
28
- export function EntityCollectionRowActions<M extends Record<string, any>>({
29
- entity,
30
- width,
31
- frozen,
32
- isSelected,
33
- selectionEnabled,
34
- size,
35
- toggleEntitySelection,
36
- onCopyClicked,
37
- onEditClicked,
38
- onDeleteClicked,
39
- hideId
40
- }:
41
- {
42
- entity: Entity<M>,
43
- width: number,
44
- frozen?: boolean,
45
- size: CollectionSize,
46
- isSelected: boolean,
47
- selectionEnabled?: boolean,
48
- toggleEntitySelection?: (selectedEntity: Entity<M>) => void
49
- onEditClicked?: (selectedEntity: Entity<M>) => void,
50
- onCopyClicked?: (selectedEntity: Entity<M>) => void,
51
- onDeleteClicked?: (selectedEntity: Entity<M>) => void,
52
- hideId?: boolean
53
- }) {
27
+ export const EntityCollectionRowActions = React.memo(function EntityCollectionRowActions({
28
+ entity,
29
+ collection,
30
+ fullPath,
31
+ width,
32
+ frozen,
33
+ isSelected,
34
+ selectionEnabled,
35
+ size,
36
+ highlightEntity,
37
+ onCollectionChange,
38
+ unhighlightEntity,
39
+ actions = [],
40
+ hideId,
41
+ selectionController
42
+ }:
43
+ {
44
+ entity: Entity<any>,
45
+ collection?: EntityCollection<any>,
46
+ fullPath?: string,
47
+ width: number,
48
+ frozen?: boolean,
49
+ size: CollectionSize,
50
+ isSelected: boolean,
51
+ selectionEnabled?: boolean,
52
+ actions?: EntityAction[],
53
+ hideId?: boolean,
54
+ onCollectionChange?: () => void,
55
+ selectionController?: SelectionController;
56
+ highlightEntity?: (entity: Entity<any>) => void;
57
+ unhighlightEntity?: (entity: Entity<any>) => void;
58
+ }) {
54
59
 
55
60
  const largeLayout = useLargeLayout();
56
61
 
57
- const editEnabled = Boolean(onEditClicked);
58
- const copyEnabled = Boolean(onCopyClicked);
59
- const deleteEnabled = Boolean(onDeleteClicked);
62
+ const context = useFireCMSContext();
60
63
 
61
64
  const onCheckedChange = useCallback((checked: boolean) => {
62
- if (toggleEntitySelection)
63
- toggleEntitySelection(entity);
64
- }, [entity, toggleEntitySelection]);
65
-
66
- const onDeleteClick = useCallback((event: MouseEvent) => {
67
- event.stopPropagation();
68
- if (onDeleteClicked)
69
- onDeleteClicked(entity);
70
- }, [entity, onDeleteClicked]);
71
-
72
- const onCopyClick = useCallback((event: MouseEvent) => {
73
- event.stopPropagation();
74
- if (onCopyClicked)
75
- onCopyClicked(entity);
76
- }, [entity, onCopyClicked]);
65
+ selectionController?.toggleEntitySelection(entity);
66
+ }, [entity, selectionController?.toggleEntitySelection]);
77
67
 
78
68
  const onClick = useCallback((event: MouseEvent) => {
79
69
  event.stopPropagation();
80
- if (toggleEntitySelection)
81
- toggleEntitySelection(entity);
82
- }, [entity, toggleEntitySelection]);
70
+ selectionController?.toggleEntitySelection(entity);
71
+ }, [entity, selectionController?.toggleEntitySelection]);
72
+
73
+ const hasActions = actions.length > 0;
74
+ const hasCollapsedActions = actions.some(a => a.collapsed || a.collapsed === undefined);
83
75
 
76
+ const collapsedActions = actions.filter(a => a.collapsed || a.collapsed === undefined);
77
+ const uncollapsedActions = actions.filter(a => a.collapsed === false);
84
78
  return (
85
79
  <div
86
80
  onClick={onClick}
@@ -95,20 +89,58 @@ export function EntityCollectionRowActions<M extends Record<string, any>>({
95
89
  contain: "strict"
96
90
  }}>
97
91
 
98
- {(editEnabled || deleteEnabled || selectionEnabled) &&
92
+ {(hasActions || selectionEnabled) &&
99
93
  <div className="w-34 flex justify-center">
100
- {editEnabled &&
101
- <Tooltip title={`Edit ${entity.id}`}>
94
+
95
+ {uncollapsedActions.map((action, index) => (
96
+ <Tooltip key={index} title={action.name}>
102
97
  <IconButton
103
98
  onClick={(event: MouseEvent) => {
104
99
  event.stopPropagation();
105
- if (onEditClicked)
106
- onEditClicked(entity);
100
+ action.onClick({
101
+ entity,
102
+ fullPath,
103
+ collection,
104
+ context,
105
+ selectionController,
106
+ highlightEntity,
107
+ unhighlightEntity,
108
+ onCollectionChange
109
+ });
107
110
  }}
108
111
  size={largeLayout ? "medium" : "small"}>
109
- <KeyboardTabIcon/>
112
+ {action.icon}
110
113
  </IconButton>
111
114
  </Tooltip>
115
+ ))}
116
+
117
+ {hasCollapsedActions &&
118
+ <Menu
119
+ trigger={<IconButton
120
+ size={largeLayout ? "medium" : "small"}>
121
+ <MoreVertIcon/>
122
+ </IconButton>}>
123
+ {collapsedActions.map((action, index) => (
124
+ <MenuItem
125
+ key={index}
126
+ onClick={(e) => {
127
+ e.stopPropagation();
128
+ action.onClick({
129
+ entity,
130
+ fullPath,
131
+ collection,
132
+ context,
133
+ selectionController,
134
+ highlightEntity,
135
+ unhighlightEntity,
136
+ onCollectionChange
137
+ });
138
+ }}>
139
+ {action.icon}
140
+ {action.name}
141
+ </MenuItem>
142
+ ))}
143
+ </Menu>
112
144
  }
113
145
 
114
146
  {selectionEnabled &&
@@ -120,24 +152,6 @@ export function EntityCollectionRowActions<M extends Record<string, any>>({
120
152
  />
121
153
  </Tooltip>}
122
154
 
123
- {(copyEnabled || deleteEnabled) &&
124
- <Menu
125
- trigger={<IconButton
126
- size={largeLayout ? "medium" : "small"}>
127
- <MoreVertIcon/>
128
- </IconButton>}>
129
- {deleteEnabled && <MenuItem onClick={onDeleteClick}>
130
- <DeleteIcon/>
131
- Delete
132
- </MenuItem>}
133
-
134
- {copyEnabled && <MenuItem onClick={onCopyClick}>
135
- <FileCopyIcon/>
136
- Copy
137
- </MenuItem>}
138
- </Menu>
139
- }
140
-
141
155
  </div>}
142
156
 
143
157
  {!hideId && size !== "xs" && (
@@ -145,7 +159,10 @@ export function EntityCollectionRowActions<M extends Record<string, any>>({
145
159
 
146
160
  {entity
147
161
  ? <Typography
148
- className={"font-mono"}
162
+ onClick={(event) => {
163
+ event.stopPropagation();
164
+ }}
165
+ className={"font-mono select-all"}
149
166
  variant={"caption"}
150
167
  color={"secondary"}> {entity.id} </Typography>
151
168
  : <Skeleton/>
@@ -156,4 +173,4 @@ export function EntityCollectionRowActions<M extends Record<string, any>>({
156
173
  </div>
157
174
  );
158
175
 
159
- }
176
+ }, equal);
@@ -375,7 +375,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
375
375
  hideOverflow = false;
376
376
  }
377
377
  } else if (arrayProperty.of.dataType === "reference") {
378
- if (typeof arrayProperty.of.key === "string") {
378
+ if (typeof arrayProperty.of.path === "string") {
379
379
  innerComponent =
380
380
  <TableReferenceField
381
381
  name={propertyKey as string}
@@ -384,7 +384,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
384
384
  updateValue={updateValue}
385
385
  size={size}
386
386
  multiselect={true}
387
- path={arrayProperty.of.key}
387
+ path={arrayProperty.of.path}
388
388
  previewProperties={arrayProperty.of.previewProperties}
389
389
  title={arrayProperty.of.name}
390
390
  forceFilter={arrayProperty.of.forceFilter}