@firecms/core 3.0.0-canary.6 → 3.0.0-canary.60

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