@firecms/core 3.0.0-canary.4 → 3.0.0-canary.40

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