@firecms/core 3.0.0-beta.2 → 3.0.0-beta.4.pre.1

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 (157) hide show
  1. package/README.md +1 -1
  2. package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +3 -7
  3. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +2 -2
  4. package/dist/components/EntityCollectionTable/PropertyTableCell.d.ts +2 -2
  5. package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +1 -2
  6. package/dist/components/EntityCollectionView/useSelectionController.d.ts +2 -0
  7. package/dist/components/EntityPreview.d.ts +25 -7
  8. package/dist/components/EntityView.d.ts +11 -0
  9. package/dist/components/FieldCaption.d.ts +4 -0
  10. package/dist/components/HomePage/NavigationCard.d.ts +8 -0
  11. package/dist/components/HomePage/{NavigationCollectionCard.d.ts → NavigationCardBinding.d.ts} +2 -2
  12. package/dist/components/HomePage/SmallNavigationCard.d.ts +6 -0
  13. package/dist/components/HomePage/index.d.ts +3 -1
  14. package/dist/components/ReferenceWidget.d.ts +3 -3
  15. package/dist/components/VirtualTable/VirtualTableProps.d.ts +1 -1
  16. package/dist/components/index.d.ts +4 -3
  17. package/dist/{internal/EntityView.d.ts → core/EntityEditView.d.ts} +2 -2
  18. package/dist/core/SideEntityView.d.ts +7 -0
  19. package/dist/core/index.d.ts +0 -2
  20. package/dist/form/EntityForm.d.ts +1 -1
  21. package/dist/form/components/StorageItemPreview.d.ts +3 -2
  22. package/dist/form/components/StorageUploadProgress.d.ts +1 -1
  23. package/dist/form/components/index.d.ts +1 -0
  24. package/dist/form/field_bindings/KeyValueFieldBinding.d.ts +1 -1
  25. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  26. package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +4 -3
  27. package/dist/form/field_bindings/TextFieldBinding.d.ts +2 -2
  28. package/dist/form/index.d.ts +1 -0
  29. package/dist/form/validation.d.ts +1 -1
  30. package/dist/hooks/data/useDataSource.d.ts +2 -2
  31. package/dist/hooks/index.d.ts +2 -1
  32. package/dist/{core → hooks}/useBuildModeController.d.ts +1 -1
  33. package/dist/hooks/useBuildNavigationController.d.ts +5 -2
  34. package/dist/hooks/useProjectLog.d.ts +5 -1
  35. package/dist/hooks/useStorageSource.d.ts +2 -2
  36. package/dist/index.es.js +8444 -8152
  37. package/dist/index.es.js.map +1 -1
  38. package/dist/index.umd.js +5 -5
  39. package/dist/index.umd.js.map +1 -1
  40. package/dist/internal/useBuildDataSource.d.ts +4 -0
  41. package/dist/internal/useRestoreScroll.d.ts +1 -1
  42. package/dist/preview/PropertyPreview.d.ts +1 -1
  43. package/dist/preview/components/BooleanPreview.d.ts +5 -1
  44. package/dist/preview/components/EnumValuesChip.d.ts +1 -1
  45. package/dist/preview/components/ReferencePreview.d.ts +1 -7
  46. package/dist/types/analytics.d.ts +1 -1
  47. package/dist/types/auth.d.ts +8 -1
  48. package/dist/types/collections.d.ts +14 -1
  49. package/dist/types/entities.d.ts +1 -0
  50. package/dist/types/entity_overrides.d.ts +6 -0
  51. package/dist/types/index.d.ts +1 -0
  52. package/dist/types/navigation.d.ts +10 -9
  53. package/dist/types/permissions.d.ts +5 -1
  54. package/dist/types/plugins.d.ts +15 -17
  55. package/dist/types/properties.d.ts +2 -2
  56. package/dist/types/property_config.d.ts +2 -2
  57. package/dist/util/collections.d.ts +9 -1
  58. package/dist/util/icons.d.ts +8 -2
  59. package/dist/util/index.d.ts +1 -0
  60. package/dist/util/permissions.d.ts +4 -4
  61. package/dist/util/references.d.ts +4 -2
  62. package/dist/util/resolutions.d.ts +1 -1
  63. package/package.json +31 -23
  64. package/src/components/DeleteEntityDialog.tsx +4 -4
  65. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +35 -39
  66. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +276 -282
  67. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +1 -1
  68. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +13 -13
  69. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +9 -16
  70. package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +3 -3
  71. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +1 -1
  72. package/src/components/EntityCollectionTable/internal/default_entity_actions.tsx +9 -5
  73. package/src/components/EntityCollectionView/EntityCollectionView.tsx +37 -58
  74. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +5 -6
  75. package/src/components/EntityCollectionView/useSelectionController.tsx +30 -0
  76. package/src/components/EntityPreview.tsx +204 -70
  77. package/src/components/EntityView.tsx +84 -0
  78. package/src/components/FieldCaption.tsx +13 -0
  79. package/src/components/FireCMSAppBar.tsx +8 -0
  80. package/src/components/HomePage/DefaultHomePage.tsx +13 -9
  81. package/src/components/HomePage/NavigationCard.tsx +69 -0
  82. package/src/components/HomePage/NavigationCardBinding.tsx +116 -0
  83. package/src/components/HomePage/SmallNavigationCard.tsx +45 -0
  84. package/src/components/HomePage/index.tsx +3 -1
  85. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +3 -4
  86. package/src/components/ReferenceWidget.tsx +7 -7
  87. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +11 -19
  88. package/src/components/VirtualTable/VirtualTableProps.tsx +1 -1
  89. package/src/components/common/useDataSourceEntityCollectionTableController.tsx +1 -1
  90. package/src/components/index.tsx +4 -3
  91. package/src/core/Drawer.tsx +66 -39
  92. package/src/{internal/EntityView.tsx → core/EntityEditView.tsx} +22 -39
  93. package/src/core/EntitySidePanel.tsx +2 -2
  94. package/src/core/FireCMS.tsx +18 -2
  95. package/src/core/NavigationRoutes.tsx +8 -0
  96. package/src/core/SideEntityView.tsx +38 -0
  97. package/src/core/index.tsx +0 -2
  98. package/src/form/EntityForm.tsx +19 -11
  99. package/src/form/components/StorageItemPreview.tsx +5 -3
  100. package/src/form/components/StorageUploadProgress.tsx +6 -5
  101. package/src/form/components/index.tsx +1 -0
  102. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +2 -3
  103. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +12 -15
  104. package/src/form/field_bindings/BlockFieldBinding.tsx +2 -3
  105. package/src/form/field_bindings/DateTimeFieldBinding.tsx +3 -3
  106. package/src/form/field_bindings/KeyValueFieldBinding.tsx +18 -18
  107. package/src/form/field_bindings/MapFieldBinding.tsx +17 -17
  108. package/src/form/field_bindings/MarkdownFieldBinding.tsx +1 -2
  109. package/src/form/field_bindings/MultiSelectBinding.tsx +2 -3
  110. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +3 -3
  111. package/src/form/field_bindings/ReferenceFieldBinding.tsx +6 -4
  112. package/src/form/field_bindings/RepeatFieldBinding.tsx +3 -3
  113. package/src/form/field_bindings/SelectFieldBinding.tsx +2 -3
  114. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +15 -6
  115. package/src/form/field_bindings/SwitchFieldBinding.tsx +2 -3
  116. package/src/form/field_bindings/TextFieldBinding.tsx +10 -9
  117. package/src/form/index.tsx +1 -0
  118. package/src/form/validation.ts +3 -4
  119. package/src/hooks/data/useCollectionFetch.tsx +1 -1
  120. package/src/hooks/data/useDataSource.tsx +8 -3
  121. package/src/hooks/data/useEntityFetch.tsx +1 -1
  122. package/src/hooks/index.tsx +3 -1
  123. package/src/{core → hooks}/useBuildModeController.tsx +1 -1
  124. package/src/hooks/useBuildNavigationController.tsx +105 -49
  125. package/src/hooks/useProjectLog.tsx +11 -3
  126. package/src/hooks/useReferenceDialog.tsx +2 -2
  127. package/src/hooks/useStorageSource.tsx +7 -2
  128. package/src/internal/useBuildDataSource.ts +7 -2
  129. package/src/preview/PropertyPreview.tsx +2 -2
  130. package/src/preview/components/BooleanPreview.tsx +16 -3
  131. package/src/preview/components/EnumValuesChip.tsx +1 -1
  132. package/src/preview/components/ReferencePreview.tsx +55 -147
  133. package/src/preview/property_previews/StringPropertyPreview.tsx +8 -7
  134. package/src/types/analytics.ts +1 -0
  135. package/src/types/auth.tsx +11 -1
  136. package/src/types/collections.ts +16 -1
  137. package/src/types/entities.ts +4 -0
  138. package/src/types/entity_actions.tsx +4 -0
  139. package/src/types/entity_overrides.tsx +7 -0
  140. package/src/types/firecms.tsx +0 -1
  141. package/src/types/index.ts +1 -0
  142. package/src/types/navigation.ts +11 -10
  143. package/src/types/permissions.ts +6 -1
  144. package/src/types/plugins.tsx +22 -25
  145. package/src/types/properties.ts +1 -1
  146. package/src/types/property_config.tsx +2 -2
  147. package/src/types/side_entity_controller.tsx +1 -0
  148. package/src/util/collections.ts +22 -0
  149. package/src/util/icons.tsx +11 -3
  150. package/src/util/index.ts +1 -0
  151. package/src/util/permissions.ts +11 -8
  152. package/src/util/references.ts +36 -5
  153. package/src/components/HomePage/NavigationCollectionCard.tsx +0 -146
  154. /package/dist/{components → form/components}/LabelWithIcon.d.ts +0 -0
  155. /package/dist/{core → hooks}/useBuildLocalConfigurationPersistence.d.ts +0 -0
  156. /package/src/{components → form/components}/LabelWithIcon.tsx +0 -0
  157. /package/src/{core → hooks}/useBuildLocalConfigurationPersistence.tsx +0 -0
@@ -1,5 +1,4 @@
1
- import React, { useCallback, useContext, useMemo, useRef } from "react";
2
- import equal from "react-fast-compare";
1
+ import React, { useCallback, useMemo, useRef } from "react";
3
2
  import { AdditionalFieldDelegate, CollectionSize, Entity, FireCMSContext, User } from "../../types";
4
3
  import { PropertyTableCell } from "./PropertyTableCell";
5
4
  import { ErrorBoundary } from "../ErrorBoundary";
@@ -8,7 +7,6 @@ import { CellRendererParams, VirtualTableColumn } from "../VirtualTable";
8
7
  import { getValueInPath } from "../../util";
9
8
  import { getRowHeight } from "../VirtualTable/common";
10
9
  import { EntityCollectionRowActions } from "./EntityCollectionRowActions";
11
- import { EntityCollectionTableController } from "../common/types";
12
10
  import { CollectionTableToolbar } from "./internal/CollectionTableToolbar";
13
11
  import { EntityCollectionTableProps } from "./EntityCollectionTableProps";
14
12
  import { EntityTableCell } from "./internal/EntityTableCell";
@@ -43,289 +41,285 @@ import { SelectableTable } from "../SelectableTable/SelectableTable";
43
41
  * @see VirtualTable
44
42
  * @group Components
45
43
  */
46
- export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>(
47
- function EntityCollectionTable<M extends Record<string, any>, UserType extends User>
48
- ({
49
- forceFilter,
50
- actionsStart,
51
- actions,
52
- title,
53
- tableRowActionsBuilder,
54
- uniqueFieldValidator,
55
- getPropertyFor,
56
- onValueChange,
57
- selectionController,
58
- highlightedEntities,
59
- onEntityClick,
60
- onColumnResize,
61
- onSizeChanged,
62
- textSearchEnabled = false,
63
- hoverRow = true,
64
- inlineEditing = false,
65
- additionalFields,
66
- displayedColumnIds,
67
- defaultSize,
68
- properties,
69
- tableController,
70
- filterable = true,
71
- sortable = true,
72
- endAdornment,
73
- AddColumnComponent,
74
- AdditionalHeaderWidget,
75
- additionalIDHeaderWidget,
76
- emptyComponent,
77
- getIdColumnWidth,
78
- onTextSearchClick,
79
- textSearchLoading
80
- }: EntityCollectionTableProps<M>) {
81
-
82
- const ref = useRef<HTMLDivElement>(null);
83
-
84
- const largeLayout = useLargeLayout();
85
- const disabledFilterChange = Boolean(forceFilter);
86
- const selectedEntities = (selectionController?.selectedEntities?.length > 0 ? selectionController?.selectedEntities : highlightedEntities)?.filter(Boolean);
87
-
88
- const context: FireCMSContext<UserType> = useFireCMSContext();
89
-
90
- const [size, setSize] = React.useState<CollectionSize>(defaultSize ?? "m");
91
-
92
- const selectedEntityIds = selectedEntities?.map(e => e.id);
93
-
94
- const filterIsSet = !!tableController.filterValues && Object.keys(tableController.filterValues).length > 0;
95
-
96
- const updateSize = useCallback((size: CollectionSize) => {
97
- if (onSizeChanged)
98
- onSizeChanged(size);
99
- setSize(size);
100
- }, []);
101
-
102
- const onTextSearch = useCallback((newSearchString?: string) => tableController.setSearchString?.(newSearchString), []);
103
-
104
- const additionalFieldsMap: Record<string, AdditionalFieldDelegate<M, UserType>> = useMemo(() => {
105
- return (additionalFields
106
- ? additionalFields
107
- .map((aC) => ({ [aC.key]: aC as AdditionalFieldDelegate<M, any> }))
108
- .reduce((a, b) => ({ ...a, ...b }), {})
109
- : {}) as Record<string, AdditionalFieldDelegate<M, UserType>>;
110
- }, [additionalFields]);
111
-
112
- const customFieldValidator: CustomFieldValidator | undefined = uniqueFieldValidator;
113
-
114
- const propertyCellRenderer = useCallback(({
115
- column,
116
- columnIndex,
117
- rowData,
118
- rowIndex
119
- }: CellRendererParams<any>) => {
120
-
121
- const entity: Entity<M> = rowData;
122
-
123
- const propertyKey = column.key;
124
-
125
- let disabled = column.custom?.disabled;
126
- const propertyValue = entity.values ? getValueInPath(entity.values, propertyKey) : undefined;
127
- const property = getPropertyFor?.({
128
- propertyKey,
129
- propertyValue,
130
- entity
131
- }) ?? column.custom.resolvedProperty;
132
- if (!property?.disabled) {
133
- disabled = false;
134
- }
44
+ export const EntityCollectionTable = function EntityCollectionTable<M extends Record<string, any>, UserType extends User>
45
+ ({
46
+ forceFilter,
47
+ actionsStart,
48
+ actions,
49
+ title,
50
+ tableRowActionsBuilder,
51
+ uniqueFieldValidator,
52
+ getPropertyFor,
53
+ onValueChange,
54
+ selectionController,
55
+ highlightedEntities,
56
+ onEntityClick,
57
+ onColumnResize,
58
+ onSizeChanged,
59
+ textSearchEnabled = false,
60
+ hoverRow = true,
61
+ inlineEditing = false,
62
+ additionalFields,
63
+ displayedColumnIds,
64
+ defaultSize,
65
+ properties,
66
+ tableController,
67
+ filterable = true,
68
+ sortable = true,
69
+ endAdornment,
70
+ AddColumnComponent,
71
+ AdditionalHeaderWidget,
72
+ additionalIDHeaderWidget,
73
+ emptyComponent,
74
+ getIdColumnWidth,
75
+ onTextSearchClick,
76
+ textSearchLoading
77
+ }: EntityCollectionTableProps<M>) {
78
+
79
+ const ref = useRef<HTMLDivElement>(null);
80
+
81
+ const largeLayout = useLargeLayout();
82
+ const disabledFilterChange = Boolean(forceFilter);
83
+ const selectedEntities = (selectionController?.selectedEntities?.length > 0 ? selectionController?.selectedEntities : highlightedEntities)?.filter(Boolean);
84
+
85
+ const context: FireCMSContext<UserType> = useFireCMSContext();
86
+
87
+ const [size, setSize] = React.useState<CollectionSize>(defaultSize ?? "m");
88
+
89
+ const selectedEntityIds = selectedEntities?.map(e => e.id);
90
+
91
+ const filterIsSet = !!tableController.filterValues && Object.keys(tableController.filterValues).length > 0;
92
+
93
+ const updateSize = useCallback((size: CollectionSize) => {
94
+ if (onSizeChanged)
95
+ onSizeChanged(size);
96
+ setSize(size);
97
+ }, []);
98
+
99
+ const onTextSearch = useCallback((newSearchString?: string) => tableController.setSearchString?.(newSearchString), []);
100
+
101
+ const additionalFieldsMap: Record<string, AdditionalFieldDelegate<M, UserType>> = useMemo(() => {
102
+ return (additionalFields
103
+ ? additionalFields
104
+ .map((aC) => ({ [aC.key]: aC as AdditionalFieldDelegate<M, any> }))
105
+ .reduce((a, b) => ({ ...a, ...b }), {})
106
+ : {}) as Record<string, AdditionalFieldDelegate<M, UserType>>;
107
+ }, [additionalFields]);
108
+
109
+ const customFieldValidator: CustomFieldValidator | undefined = uniqueFieldValidator;
110
+
111
+ const propertyCellRenderer = ({
112
+ column,
113
+ columnIndex,
114
+ rowData,
115
+ rowIndex
116
+ }: CellRendererParams<any>) => {
117
+
118
+ const entity: Entity<M> = rowData;
119
+
120
+ const propertyKey = column.key;
121
+
122
+ let disabled = column.custom?.disabled;
123
+ const propertyValue = entity.values ? getValueInPath(entity.values, propertyKey) : undefined;
124
+ const property = getPropertyFor?.({
125
+ propertyKey,
126
+ propertyValue,
127
+ entity
128
+ }) ?? column.custom.resolvedProperty;
129
+ if (!property?.disabled) {
130
+ disabled = false;
131
+ }
132
+
133
+ if (!property) {
134
+ return null;
135
+ }
135
136
 
136
- if (!property) {
137
- return null;
138
- }
137
+ return (
138
+ <ErrorBoundary>
139
+ {entity
140
+ ? <PropertyTableCell
141
+ key={`property_table_cell_${entity.id}_${propertyKey}`}
142
+ readonly={!inlineEditing}
143
+ align={column.align ?? "left"}
144
+ propertyKey={propertyKey as string}
145
+ property={property}
146
+ value={entity?.values ? getValueInPath(entity.values, propertyKey) : undefined}
147
+ customFieldValidator={customFieldValidator}
148
+ columnIndex={columnIndex}
149
+ width={column.width}
150
+ height={getRowHeight(size)}
151
+ entity={entity}
152
+ disabled={disabled}
153
+ path={entity.path}/>
154
+ : renderSkeletonText()
155
+ }
156
+ </ErrorBoundary>);
139
157
 
140
- return (
141
- <ErrorBoundary>
142
- {entity
143
- ? <PropertyTableCell
144
- key={`property_table_cell_${entity.id}_${propertyKey}`}
145
- readonly={!inlineEditing}
146
- align={column.align ?? "left"}
147
- propertyKey={propertyKey as string}
148
- property={property}
149
- value={entity?.values ? getValueInPath(entity.values, propertyKey) : undefined}
150
- customFieldValidator={customFieldValidator}
151
- columnIndex={columnIndex}
152
- width={column.width}
153
- height={getRowHeight(size)}
154
- entity={entity}
155
- disabled={disabled}
156
- path={entity.path}/>
157
- : renderSkeletonText()
158
- }
159
- </ErrorBoundary>);
160
-
161
- }, [inlineEditing, size, selectedEntityIds]);
162
-
163
- const additionalCellRenderer = useCallback(({
164
- column,
165
- rowData,
166
- width
167
- }: CellRendererParams<any>) => {
168
-
169
- const entity: Entity<M> = rowData;
170
-
171
- const additionalField = additionalFieldsMap[column.key as string];
172
- const value = additionalField.dependencies
173
- ? Object.entries(entity.values)
174
- .filter(([key, value]) => additionalField.dependencies!.includes(key as Extract<keyof M, string>))
175
- .reduce((a, b) => ({ ...a, ...b }), {})
176
- : entity;
177
-
178
- const Builder = additionalField.Builder;
179
- if (!Builder && !additionalField.value) {
180
- throw new Error("When using additional fields you need to provide a Builder or a value");
181
- }
158
+ };
182
159
 
183
- const child = Builder
184
- ? <Builder entity={entity} context={context}/>
185
- : <>{additionalField.value?.({ entity, context })}</>;
186
-
187
- return (
188
- <EntityTableCell
189
- key={`additional_table_cell_${entity.id}_${column.key}`}
190
- width={width}
191
- size={size}
192
- value={value}
193
- selected={false}
194
- disabled={true}
195
- align={"left"}
196
- allowScroll={false}
197
- showExpandIcon={false}
198
- disabledTooltip={"This column can't be edited directly"}
199
- >
200
- <ErrorBoundary>
201
- {child}
202
- </ErrorBoundary>
203
- </EntityTableCell>
204
- );
205
-
206
- }, [size, selectedEntityIds]);
207
-
208
- const collectionColumns: VirtualTableColumn[] = useMemo(() => {
209
- const columnsResult: VirtualTableColumn[] = propertiesToColumns({
210
- properties,
211
- sortable,
212
- forceFilter,
213
- disabledFilter: disabledFilterChange,
214
- AdditionalHeaderWidget
215
- });
216
-
217
- const additionalTableColumns: VirtualTableColumn[] = additionalFields
218
- ? additionalFields.map((additionalField) =>
219
- ({
220
- key: additionalField.key,
221
- align: "left",
222
- sortable: false,
223
- title: additionalField.name,
224
- width: additionalField.width ?? 200
225
- }))
226
- : [];
227
- return [...columnsResult, ...additionalTableColumns];
228
- },
229
- [additionalFields, disabledFilterChange, forceFilter, properties, sortable]);
230
-
231
- const idColumn: VirtualTableColumn = useMemo(() => ({
232
- key: "id_ewcfedcswdf3",
233
- width: getIdColumnWidth?.() ?? (largeLayout ? 160 : 130),
234
- title: "ID",
235
- resizable: false,
236
- frozen: largeLayout,
237
- headerAlign: "center",
238
- align: "center",
239
- AdditionalHeaderWidget: () => additionalIDHeaderWidget
240
- }), [getIdColumnWidth, largeLayout])
241
-
242
- const columns: VirtualTableColumn[] = useMemo(() => [
243
- idColumn,
244
- ...displayedColumnIds
245
- .map((p) => {
246
- return collectionColumns.find(c => c.key === p.key);
247
- }).filter(Boolean) as VirtualTableColumn[]
248
- ], [collectionColumns, displayedColumnIds, idColumn]);
249
-
250
- const cellRenderer = useCallback((props: CellRendererParams<any>) => {
251
- const column = props.column;
252
- const columns = props.columns;
253
- const columnKey = column.key;
254
-
255
- try {
256
- if (props.columnIndex === 0) {
257
- if (tableRowActionsBuilder)
258
- return tableRowActionsBuilder({
259
- entity: props.rowData,
260
- size,
261
- width: column.width,
262
- frozen: column.frozen
263
- });
264
- else
265
- return <EntityCollectionRowActions entity={props.rowData}
266
- width={column.width}
267
- frozen={column.frozen}
268
- isSelected={false}
269
- size={size}/>;
270
- } else if (additionalFieldsMap[columnKey]) {
271
- return additionalCellRenderer(props);
272
- } else if (props.columnIndex < columns.length + 1) {
273
- return propertyCellRenderer(props);
274
- } else {
275
- throw Error("Internal: columns not mapped properly");
276
- }
277
- } catch (e: any) {
278
- console.error("Error rendering cell", e);
279
- return <EntityTableCell
280
- size={size}
281
- width={column.width}
282
- saved={false}
283
- value={null}
284
- align={"left"}
285
- fullHeight={false}
286
- disabled={true}>
287
- <ErrorView error={e}/>
288
- </EntityTableCell>;
289
- }
290
- }, [additionalFieldsMap, tableRowActionsBuilder, size, additionalCellRenderer, propertyCellRenderer])
160
+ const additionalCellRenderer = useCallback(({
161
+ column,
162
+ rowData,
163
+ width
164
+ }: CellRendererParams<any>) => {
291
165
 
292
- return (
166
+ const entity: Entity<M> = rowData;
167
+
168
+ const additionalField = additionalFieldsMap[column.key as string];
169
+ const value = additionalField.dependencies
170
+ ? Object.entries(entity.values)
171
+ .filter(([key, value]) => additionalField.dependencies!.includes(key as Extract<keyof M, string>))
172
+ .reduce((a, b) => ({ ...a, ...b }), {})
173
+ : entity;
174
+
175
+ const Builder = additionalField.Builder;
176
+ if (!Builder && !additionalField.value) {
177
+ throw new Error("When using additional fields you need to provide a Builder or a value");
178
+ }
179
+
180
+ const child = Builder
181
+ ? <Builder entity={entity} context={context}/>
182
+ : <>{additionalField.value?.({ entity, context })}</>;
293
183
 
294
- <div ref={ref}
295
- className="h-full w-full flex flex-col bg-white dark:bg-gray-950">
296
-
297
- <CollectionTableToolbar
298
- forceFilter={disabledFilterChange}
299
- filterIsSet={filterIsSet}
300
- onTextSearch={textSearchEnabled ? onTextSearch : undefined}
301
- textSearchLoading={textSearchLoading}
302
- onTextSearchClick={textSearchEnabled ? onTextSearchClick : undefined}
303
- clearFilter={tableController.clearFilter}
304
- size={size}
305
- onSizeChanged={updateSize}
306
- title={title}
307
- actionsStart={actionsStart}
308
- actions={actions}
309
- loading={tableController.dataLoading}/>
310
-
311
- <SelectableTable columns={columns}
312
- size={size}
313
- inlineEditing={inlineEditing}
314
- cellRenderer={cellRenderer}
315
- onEntityClick={onEntityClick}
316
- highlightedRow={useCallback((entity: Entity<M>) => selectedEntityIds?.includes(entity.id) ?? false, [selectedEntityIds])}
317
- tableController={tableController}
318
- onValueChange={onValueChange}
319
- onColumnResize={onColumnResize}
320
- hoverRow={hoverRow}
321
- filterable={filterable}
322
- emptyComponent={emptyComponent}
323
- endAdornment={endAdornment}
324
- AddColumnComponent={AddColumnComponent}/>
325
-
326
- </div>
184
+ return (
185
+ <EntityTableCell
186
+ key={`additional_table_cell_${entity.id}_${column.key}`}
187
+ width={width}
188
+ size={size}
189
+ value={value}
190
+ selected={false}
191
+ disabled={true}
192
+ align={"left"}
193
+ allowScroll={false}
194
+ showExpandIcon={false}
195
+ disabledTooltip={"This column can't be edited directly"}
196
+ >
197
+ <ErrorBoundary>
198
+ {child}
199
+ </ErrorBoundary>
200
+ </EntityTableCell>
327
201
  );
328
202
 
329
- },
330
- equal
331
- );
203
+ }, [size, selectedEntityIds]);
204
+
205
+ const collectionColumns: VirtualTableColumn[] = (() => {
206
+ const columnsResult: VirtualTableColumn[] = propertiesToColumns({
207
+ properties,
208
+ sortable,
209
+ forceFilter,
210
+ disabledFilter: disabledFilterChange,
211
+ AdditionalHeaderWidget
212
+ });
213
+
214
+ const additionalTableColumns: VirtualTableColumn[] = additionalFields
215
+ ? additionalFields.map((additionalField) =>
216
+ ({
217
+ key: additionalField.key,
218
+ align: "left",
219
+ sortable: false,
220
+ title: additionalField.name,
221
+ width: additionalField.width ?? 200
222
+ }))
223
+ : [];
224
+ return [...columnsResult, ...additionalTableColumns];
225
+ })();
226
+
227
+ const idColumn: VirtualTableColumn = {
228
+ key: "id_ewcfedcswdf3",
229
+ width: getIdColumnWidth?.() ?? (largeLayout ? 160 : 130),
230
+ title: "ID",
231
+ resizable: false,
232
+ frozen: largeLayout,
233
+ headerAlign: "center",
234
+ align: "center",
235
+ AdditionalHeaderWidget: () => additionalIDHeaderWidget
236
+ }
237
+
238
+ const columns: VirtualTableColumn[] = [
239
+ idColumn,
240
+ ...displayedColumnIds
241
+ .map((p) => {
242
+ return collectionColumns.find(c => c.key === p.key);
243
+ }).filter(Boolean) as VirtualTableColumn[]
244
+ ];
245
+
246
+ const cellRenderer = (props: CellRendererParams<any>) => {
247
+ const column = props.column;
248
+ const columns = props.columns;
249
+ const columnKey = column.key;
250
+
251
+ try {
252
+ if (props.columnIndex === 0) {
253
+ if (tableRowActionsBuilder)
254
+ return tableRowActionsBuilder({
255
+ entity: props.rowData,
256
+ size,
257
+ width: column.width,
258
+ frozen: column.frozen
259
+ });
260
+ else
261
+ return <EntityCollectionRowActions entity={props.rowData}
262
+ width={column.width}
263
+ frozen={column.frozen}
264
+ isSelected={false}
265
+ size={size}/>;
266
+ } else if (additionalFieldsMap[columnKey]) {
267
+ return additionalCellRenderer(props);
268
+ } else if (props.columnIndex < columns.length + 1) {
269
+ return propertyCellRenderer(props);
270
+ } else {
271
+ throw Error("Internal: columns not mapped properly");
272
+ }
273
+ } catch (e: any) {
274
+ console.error("Error rendering cell", e);
275
+ return <EntityTableCell
276
+ size={size}
277
+ width={column.width}
278
+ saved={false}
279
+ value={null}
280
+ align={"left"}
281
+ fullHeight={false}
282
+ disabled={true}>
283
+ <ErrorView error={e}/>
284
+ </EntityTableCell>;
285
+ }
286
+ }
287
+
288
+ return (
289
+
290
+ <div ref={ref}
291
+ className="h-full w-full flex flex-col bg-white dark:bg-gray-950">
292
+
293
+ <CollectionTableToolbar
294
+ forceFilter={disabledFilterChange}
295
+ filterIsSet={filterIsSet}
296
+ onTextSearch={textSearchEnabled ? onTextSearch : undefined}
297
+ textSearchLoading={textSearchLoading}
298
+ onTextSearchClick={textSearchEnabled ? onTextSearchClick : undefined}
299
+ clearFilter={tableController.clearFilter}
300
+ size={size}
301
+ onSizeChanged={updateSize}
302
+ title={title}
303
+ actionsStart={actionsStart}
304
+ actions={actions}
305
+ loading={tableController.dataLoading}/>
306
+
307
+ <SelectableTable columns={columns}
308
+ size={size}
309
+ inlineEditing={inlineEditing}
310
+ cellRenderer={cellRenderer}
311
+ onEntityClick={onEntityClick}
312
+ highlightedRow={useCallback((entity: Entity<M>) => selectedEntityIds?.includes(entity.id) ?? false, [selectedEntityIds])}
313
+ tableController={tableController}
314
+ onValueChange={onValueChange}
315
+ onColumnResize={onColumnResize}
316
+ hoverRow={hoverRow}
317
+ filterable={filterable}
318
+ emptyComponent={emptyComponent}
319
+ endAdornment={endAdornment}
320
+ AddColumnComponent={AddColumnComponent}/>
321
+
322
+ </div>
323
+ );
324
+
325
+ };
@@ -2,7 +2,7 @@ import React from "react";
2
2
  import {
3
3
  AdditionalFieldDelegate,
4
4
  CollectionSize,
5
- Entity,
5
+ Entity, EntityCollection,
6
6
  EntityTableController,
7
7
  FilterValues,
8
8
  ResolvedProperties,
@@ -24,15 +24,16 @@ import { getPreviewSizeFrom } from "../../preview/util";
24
24
  import { isReadOnly } from "../../util";
25
25
 
26
26
  import { CustomFieldValidator, mapPropertyToYup } from "../../form/validation";
27
- import { useClearRestoreValue, useFireCMSContext } from "../../hooks";
27
+ import { useFireCMSContext } from "../../hooks";
28
28
 
29
29
  import { EntityTableCell } from "./internal/EntityTableCell";
30
30
  import { EntityTableCellActions } from "./internal/EntityTableCellActions";
31
31
 
32
32
  import { getRowHeight } from "../VirtualTable/common";
33
33
  import { useSelectableTableController } from "../SelectableTable/SelectableTableContext";
34
+ import { useClearRestoreValue } from "../../form/useClearRestoreValue";
34
35
 
35
- export interface PropertyTableCellProps<T extends CMSType, M extends Record<string, any>> {
36
+ export interface PropertyTableCellProps<T extends CMSType> {
36
37
  propertyKey: string;
37
38
  columnIndex: number;
38
39
  align: "right" | "left" | "center";
@@ -61,7 +62,7 @@ function isStorageProperty(property: ResolvedProperty) {
61
62
  return false;
62
63
  }
63
64
 
64
- export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
65
+ export const PropertyTableCell = React.memo<PropertyTableCellProps<any>>(
65
66
  function PropertyTableCell<T extends CMSType, M extends Record<string, any>>({
66
67
  propertyKey,
67
68
  customFieldValidator,
@@ -74,7 +75,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
74
75
  entity,
75
76
  readonly,
76
77
  disabled: disabledProp
77
- }: PropertyTableCellProps<T, M>) {
78
+ }: PropertyTableCellProps<T>) {
78
79
 
79
80
  const context = useFireCMSContext();
80
81
 
@@ -402,14 +403,13 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
402
403
  allowScroll = false;
403
404
  showExpandIcon = selected && !innerComponent && !disabled && !readOnlyProperty;
404
405
  innerComponent = (
405
- <PropertyPreview
406
- width={width}
407
- height={height}
406
+ <PropertyPreview width={width}
407
+ height={height}
408
408
  // entity={entity}
409
- propertyKey={propertyKey as string}
410
- value={internalValue}
411
- property={property}
412
- size={getPreviewSizeFrom(size)}
409
+ propertyKey={propertyKey as string}
410
+ value={internalValue}
411
+ property={property}
412
+ size={getPreviewSizeFrom(size)}
413
413
  />
414
414
  );
415
415
  }
@@ -446,9 +446,9 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
446
446
  );
447
447
 
448
448
  },
449
- areEqual) as React.FunctionComponent<PropertyTableCellProps<any, any>>;
449
+ areEqual) as React.FunctionComponent<PropertyTableCellProps<any>>;
450
450
 
451
- function areEqual(prevProps: PropertyTableCellProps<any, any>, nextProps: PropertyTableCellProps<any, any>) {
451
+ function areEqual(prevProps: PropertyTableCellProps<any>, nextProps: PropertyTableCellProps<any>) {
452
452
  return prevProps.height === nextProps.height &&
453
453
  prevProps.propertyKey === nextProps.propertyKey &&
454
454
  prevProps.align === nextProps.align &&