@firecms/core 3.0.0-canary.7 → 3.0.0-canary.9

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