@firecms/core 3.0.0-canary.5 → 3.0.0-canary.50

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 (210) 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/internal/CollectionTableToolbar.d.ts +1 -4
  9. package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +1 -1
  10. package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +12 -3
  11. package/dist/components/EntityCollectionView/EntityCollectionViewStartActions.d.ts +11 -0
  12. package/dist/components/EntityCollectionView/useSelectionController.d.ts +2 -0
  13. package/dist/components/EntityPreview.d.ts +25 -7
  14. package/dist/components/EntityView.d.ts +11 -0
  15. package/dist/components/FieldCaption.d.ts +5 -0
  16. package/dist/components/FireCMSAppBar.d.ts +3 -2
  17. package/dist/components/HomePage/NavigationCard.d.ts +8 -0
  18. package/dist/components/HomePage/{NavigationCollectionCard.d.ts → NavigationCardBinding.d.ts} +2 -2
  19. package/dist/components/HomePage/SmallNavigationCard.d.ts +6 -0
  20. package/dist/components/HomePage/index.d.ts +3 -1
  21. package/dist/components/SelectableTable/SelectableTable.d.ts +1 -1
  22. package/dist/components/VirtualTable/VirtualTableProps.d.ts +1 -1
  23. package/dist/components/common/types.d.ts +4 -6
  24. package/dist/components/common/useDataSourceEntityCollectionTableController.d.ts +3 -0
  25. package/dist/components/index.d.ts +4 -2
  26. package/dist/contexts/AuthControllerContext.d.ts +1 -1
  27. package/dist/core/{EntityView.d.ts → EntityEditView.d.ts} +2 -2
  28. package/dist/core/NavigationRoutes.d.ts +1 -1
  29. package/dist/core/Scaffold.d.ts +1 -1
  30. package/dist/form/EntityForm.d.ts +1 -1
  31. package/dist/form/components/ErrorFocus.d.ts +1 -1
  32. package/dist/form/components/StorageItemPreview.d.ts +3 -2
  33. package/dist/form/components/StorageUploadProgress.d.ts +1 -1
  34. package/dist/form/field_bindings/KeyValueFieldBinding.d.ts +1 -1
  35. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  36. package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +4 -3
  37. package/dist/form/field_bindings/TextFieldBinding.d.ts +2 -2
  38. package/dist/form/validation.d.ts +1 -1
  39. package/dist/hooks/data/delete.d.ts +2 -2
  40. package/dist/hooks/data/save.d.ts +2 -3
  41. package/dist/hooks/data/useDataSource.d.ts +2 -2
  42. package/dist/hooks/data/useEntityFetch.d.ts +3 -3
  43. package/dist/hooks/index.d.ts +1 -0
  44. package/dist/hooks/useBuildNavigationController.d.ts +6 -4
  45. package/dist/hooks/useProjectLog.d.ts +6 -2
  46. package/dist/hooks/useStorageSource.d.ts +2 -2
  47. package/dist/hooks/useValidateAuthenticator.d.ts +21 -0
  48. package/dist/index.es.js +10402 -9898
  49. package/dist/index.es.js.map +1 -1
  50. package/dist/index.umd.js +5 -5
  51. package/dist/index.umd.js.map +1 -1
  52. package/dist/internal/useBuildDataSource.d.ts +1 -12
  53. package/dist/preview/PropertyPreview.d.ts +1 -1
  54. package/dist/preview/PropertyPreviewProps.d.ts +1 -4
  55. package/dist/preview/components/BooleanPreview.d.ts +5 -1
  56. package/dist/preview/components/EnumValuesChip.d.ts +1 -1
  57. package/dist/preview/components/ReferencePreview.d.ts +1 -7
  58. package/dist/types/analytics.d.ts +1 -1
  59. package/dist/types/auth.d.ts +37 -1
  60. package/dist/types/collections.d.ts +29 -5
  61. package/dist/types/datasource.d.ts +3 -6
  62. package/dist/types/entities.d.ts +5 -1
  63. package/dist/types/entity_actions.d.ts +14 -0
  64. package/dist/types/entity_callbacks.d.ts +2 -2
  65. package/dist/types/entity_overrides.d.ts +6 -0
  66. package/dist/types/index.d.ts +2 -1
  67. package/dist/types/navigation.d.ts +14 -13
  68. package/dist/types/permissions.d.ts +5 -1
  69. package/dist/types/plugins.d.ts +20 -20
  70. package/dist/types/properties.d.ts +4 -4
  71. package/dist/types/property_config.d.ts +2 -2
  72. package/dist/types/roles.d.ts +31 -0
  73. package/dist/types/storage.d.ts +11 -3
  74. package/dist/types/user.d.ts +5 -0
  75. package/dist/util/collections.d.ts +9 -1
  76. package/dist/util/entities.d.ts +1 -1
  77. package/dist/util/icon_synonyms.d.ts +1 -4
  78. package/dist/util/icons.d.ts +8 -2
  79. package/dist/util/navigation_utils.d.ts +2 -2
  80. package/dist/util/permissions.d.ts +4 -4
  81. package/dist/util/references.d.ts +4 -2
  82. package/dist/util/resolutions.d.ts +9 -13
  83. package/dist/util/useTraceUpdate.d.ts +1 -0
  84. package/package.json +139 -119
  85. package/src/components/ClearFilterSortButton.tsx +41 -0
  86. package/src/components/DeleteEntityDialog.tsx +4 -4
  87. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +2 -2
  88. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +275 -278
  89. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +9 -5
  90. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +44 -44
  91. package/src/components/EntityCollectionTable/column_utils.tsx +3 -3
  92. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +9 -16
  93. package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +3 -3
  94. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +27 -32
  95. package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +11 -6
  96. package/src/components/EntityCollectionTable/internal/default_entity_actions.tsx +9 -5
  97. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +2 -4
  98. package/src/components/EntityCollectionView/EntityCollectionView.tsx +69 -64
  99. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +5 -6
  100. package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +68 -0
  101. package/src/components/EntityCollectionView/useSelectionController.tsx +30 -0
  102. package/src/components/EntityPreview.tsx +207 -70
  103. package/src/components/EntityView.tsx +84 -0
  104. package/src/components/FieldCaption.tsx +14 -0
  105. package/src/components/FireCMSAppBar.tsx +33 -11
  106. package/src/components/HomePage/DefaultHomePage.tsx +15 -11
  107. package/src/components/HomePage/NavigationCard.tsx +69 -0
  108. package/src/components/HomePage/NavigationCardBinding.tsx +116 -0
  109. package/src/components/HomePage/SmallNavigationCard.tsx +45 -0
  110. package/src/components/HomePage/index.tsx +3 -1
  111. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +4 -4
  112. package/src/components/ReferenceWidget.tsx +4 -4
  113. package/src/components/SearchIconsView.tsx +4 -4
  114. package/src/components/SelectableTable/SelectableTable.tsx +1 -1
  115. package/src/components/SelectableTable/filters/BooleanFilterField.tsx +2 -3
  116. package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +23 -8
  117. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +35 -24
  118. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +35 -15
  119. package/src/components/VirtualTable/VirtualTable.tsx +28 -20
  120. package/src/components/VirtualTable/VirtualTableProps.tsx +1 -1
  121. package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +1 -1
  122. package/src/components/common/types.tsx +4 -6
  123. package/src/components/common/useDataSourceEntityCollectionTableController.tsx +12 -1
  124. package/src/components/index.tsx +4 -2
  125. package/src/contexts/AuthControllerContext.tsx +1 -1
  126. package/src/core/Drawer.tsx +66 -39
  127. package/src/core/{EntityView.tsx → EntityEditView.tsx} +21 -40
  128. package/src/core/EntitySidePanel.tsx +2 -2
  129. package/src/core/FireCMS.tsx +18 -3
  130. package/src/core/NavigationRoutes.tsx +11 -4
  131. package/src/core/Scaffold.tsx +5 -4
  132. package/src/core/field_configs.tsx +1 -2
  133. package/src/form/EntityForm.tsx +40 -21
  134. package/src/form/PropertyFieldBinding.tsx +0 -2
  135. package/src/form/components/StorageItemPreview.tsx +5 -3
  136. package/src/form/components/StorageUploadProgress.tsx +7 -6
  137. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +8 -12
  138. package/src/form/field_bindings/DateTimeFieldBinding.tsx +1 -1
  139. package/src/form/field_bindings/KeyValueFieldBinding.tsx +15 -15
  140. package/src/form/field_bindings/MapFieldBinding.tsx +15 -15
  141. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +1 -1
  142. package/src/form/field_bindings/ReferenceFieldBinding.tsx +1 -0
  143. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +14 -5
  144. package/src/form/field_bindings/TextFieldBinding.tsx +7 -5
  145. package/src/form/validation.ts +3 -4
  146. package/src/hooks/data/delete.ts +3 -3
  147. package/src/hooks/data/save.ts +2 -2
  148. package/src/hooks/data/useCollectionFetch.tsx +1 -1
  149. package/src/hooks/data/useDataSource.tsx +8 -3
  150. package/src/hooks/data/useEntityFetch.tsx +4 -4
  151. package/src/hooks/index.tsx +2 -0
  152. package/src/hooks/useBuildLocalConfigurationPersistence.tsx +9 -10
  153. package/src/hooks/useBuildModeController.tsx +11 -5
  154. package/src/hooks/useBuildNavigationController.tsx +199 -81
  155. package/src/hooks/useProjectLog.tsx +17 -7
  156. package/src/hooks/useReferenceDialog.tsx +2 -2
  157. package/src/hooks/useStorageSource.tsx +7 -2
  158. package/src/hooks/useValidateAuthenticator.tsx +115 -0
  159. package/src/internal/useBuildDataSource.ts +42 -44
  160. package/src/internal/useBuildSideEntityController.tsx +86 -20
  161. package/src/preview/PropertyPreview.tsx +3 -14
  162. package/src/preview/PropertyPreviewProps.tsx +1 -11
  163. package/src/preview/components/BooleanPreview.tsx +19 -4
  164. package/src/preview/components/EnumValuesChip.tsx +1 -1
  165. package/src/preview/components/ReferencePreview.tsx +55 -147
  166. package/src/preview/property_previews/ArrayOfMapsPreview.tsx +0 -1
  167. package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +0 -1
  168. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +0 -1
  169. package/src/preview/property_previews/ArrayOfStringsPreview.tsx +0 -1
  170. package/src/preview/property_previews/ArrayOneOfPreview.tsx +0 -1
  171. package/src/preview/property_previews/ArrayPropertyPreview.tsx +0 -1
  172. package/src/preview/property_previews/StringPropertyPreview.tsx +8 -7
  173. package/src/types/analytics.ts +1 -0
  174. package/src/types/auth.tsx +50 -1
  175. package/src/types/collections.ts +33 -5
  176. package/src/types/datasource.ts +8 -5
  177. package/src/types/entities.ts +9 -1
  178. package/src/types/entity_actions.tsx +17 -0
  179. package/src/types/entity_callbacks.ts +2 -2
  180. package/src/types/entity_overrides.tsx +7 -0
  181. package/src/types/firecms.tsx +0 -1
  182. package/src/types/index.ts +2 -1
  183. package/src/types/navigation.ts +17 -16
  184. package/src/types/permissions.ts +6 -1
  185. package/src/types/plugins.tsx +26 -28
  186. package/src/types/properties.ts +8 -6
  187. package/src/types/property_config.tsx +2 -2
  188. package/src/types/roles.ts +41 -0
  189. package/src/types/side_entity_controller.tsx +1 -0
  190. package/src/types/storage.ts +12 -3
  191. package/src/types/user.ts +7 -0
  192. package/src/util/collections.ts +22 -0
  193. package/src/util/entities.ts +1 -1
  194. package/src/util/icon_list.ts +2 -2
  195. package/src/util/icon_synonyms.ts +1 -4
  196. package/src/util/icons.tsx +11 -3
  197. package/src/util/navigation_utils.ts +6 -6
  198. package/src/util/objects.ts +0 -14
  199. package/src/util/permissions.ts +11 -8
  200. package/src/util/references.ts +36 -5
  201. package/src/util/resolutions.ts +6 -24
  202. package/src/util/strings.ts +2 -2
  203. package/src/util/useTraceUpdate.tsx +2 -1
  204. package/dist/core/SideEntityView.d.ts +0 -7
  205. package/dist/internal/useLocaleConfig.d.ts +0 -1
  206. package/dist/types/appcheck.d.ts +0 -26
  207. package/src/components/HomePage/NavigationCollectionCard.tsx +0 -146
  208. package/src/core/SideEntityView.tsx +0 -38
  209. package/src/internal/useLocaleConfig.tsx +0 -18
  210. package/src/types/appcheck.ts +0 -29
@@ -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";
@@ -46,6 +46,7 @@ export interface PropertyTableCellProps<T extends CMSType, M extends Record<stri
46
46
  entity: Entity<any>;
47
47
  path: string;
48
48
  disabled: boolean;
49
+ enablePopupIcon?: boolean;
49
50
  }
50
51
 
51
52
  function isStorageProperty(property: ResolvedProperty) {
@@ -62,7 +63,7 @@ function isStorageProperty(property: ResolvedProperty) {
62
63
  return false;
63
64
  }
64
65
 
65
- export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
66
+ export const PropertyTableCell = React.memo<PropertyTableCellProps<any>>(
66
67
  function PropertyTableCell<T extends CMSType, M extends Record<string, any>>({
67
68
  propertyKey,
68
69
  customFieldValidator,
@@ -74,10 +75,9 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
74
75
  path,
75
76
  entity,
76
77
  readonly,
77
- disabled: disabledProp
78
- }: PropertyTableCellProps<T, M>) {
79
-
80
- const context = useFireCMSContext();
78
+ disabled: disabledProp,
79
+ enablePopupIcon = true
80
+ }: PropertyTableCellProps<T>) {
81
81
 
82
82
  const {
83
83
  onValueChange,
@@ -95,6 +95,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
95
95
  const internalValueRef = useRef(value);
96
96
 
97
97
  const [error, setError] = useState<Error | undefined>();
98
+ const [validationError, setValidationError] = useState<Error | undefined>();
98
99
  const [saved, setSaved] = useState<boolean>(false);
99
100
 
100
101
  const onValueUpdated = useCallback(() => {
@@ -120,7 +121,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
120
121
  useEffect(
121
122
  () => {
122
123
  if (!equal(value, internalValueRef.current)) {
123
- setError(undefined);
124
+ setValidationError(undefined);
124
125
  setInternalValue(value);
125
126
  internalValueRef.current = value;
126
127
  onValueUpdated();
@@ -136,32 +137,34 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
136
137
  validation
137
138
  .validate(value)
138
139
  .then(() => {
139
- setError(undefined);
140
+ setValidationError(undefined);
140
141
  internalValueRef.current = value;
141
142
  if (onValueChange) {
142
- onValueChange({
143
- value,
144
- propertyKey,
145
- setError,
146
- onValueUpdated,
147
- entity,
148
- fullPath: path,
149
- context
150
- });
143
+ try {
144
+ onValueChange({
145
+ value,
146
+ propertyKey,
147
+ setError,
148
+ onValueUpdated,
149
+ data: entity,
150
+ });
151
+ } catch (e:any) {
152
+ console.error("onValueChange error", e);
153
+ setError(e);
154
+ }
155
+
151
156
  }
152
157
  })
153
158
  .catch((e) => {
154
- setError(e);
159
+ setValidationError(e);
155
160
  });
156
161
  };
157
162
 
158
163
  useEffect(() => {
159
164
  validation
160
165
  .validate(internalValue)
161
- .then(() => setError(undefined))
162
- .catch((e) => {
163
- setError(e);
164
- });
166
+ .then(() => setValidationError(undefined))
167
+ .catch(setValidationError);
165
168
  }, [internalValue, validation, propertyKey, property, entity]);
166
169
 
167
170
  const updateValue = (newValue: any | null) => {
@@ -237,7 +240,6 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
237
240
  height={getRowHeight(size)}
238
241
  propertyKey={propertyKey}
239
242
  property={property}
240
- // entity={entity}
241
243
  value={internalValue}
242
244
  size={getPreviewSizeFrom(size)}
243
245
  />
@@ -247,7 +249,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
247
249
  if (!customField && (!customPreview || selected)) {
248
250
  const isAStorageProperty = isStorageProperty(property);
249
251
  if (isAStorageProperty) {
250
- innerComponent = <TableStorageUpload error={error}
252
+ innerComponent = <TableStorageUpload error={validationError ?? error}
251
253
  disabled={disabled}
252
254
  focused={selected}
253
255
  selected={selected}
@@ -274,7 +276,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
274
276
  valueType={"number"}
275
277
  small={getPreviewSizeFrom(size) !== "medium"}
276
278
  enumValues={numberProperty.enumValues}
277
- error={error}
279
+ error={validationError ?? error}
278
280
  internalValue={internalValue as string | number}
279
281
  updateValue={updateValue}
280
282
  />;
@@ -282,7 +284,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
282
284
  } else {
283
285
  innerComponent = <VirtualTableNumberInput
284
286
  align={align}
285
- error={error}
287
+ error={validationError ?? error}
286
288
  focused={selected}
287
289
  disabled={disabled}
288
290
  value={internalValue as number}
@@ -300,14 +302,14 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
300
302
  valueType={"string"}
301
303
  small={getPreviewSizeFrom(size) !== "medium"}
302
304
  enumValues={stringProperty.enumValues}
303
- error={error}
305
+ error={validationError ?? error}
304
306
  internalValue={internalValue as string | number}
305
307
  updateValue={updateValue}
306
308
  />;
307
309
  fullHeight = true;
308
310
  } else if (!stringProperty.storage) {
309
311
  const multiline = Boolean(stringProperty.multiline) || Boolean(stringProperty.markdown);
310
- innerComponent = <VirtualTableInput error={error}
312
+ innerComponent = <VirtualTableInput error={validationError ?? error}
311
313
  disabled={disabled}
312
314
  multiline={multiline}
313
315
  focused={selected}
@@ -317,7 +319,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
317
319
  allowScroll = true;
318
320
  }
319
321
  } else if (property.dataType === "boolean") {
320
- innerComponent = <VirtualTableSwitch error={error}
322
+ innerComponent = <VirtualTableSwitch error={validationError ?? error}
321
323
  disabled={disabled}
322
324
  focused={selected}
323
325
  internalValue={internalValue as boolean}
@@ -325,7 +327,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
325
327
  />;
326
328
  } else if (property.dataType === "date") {
327
329
  innerComponent = <VirtualTableDateField name={propertyKey as string}
328
- error={error}
330
+ error={validationError ?? error}
329
331
  disabled={disabled}
330
332
  mode={property.mode}
331
333
  focused={selected}
@@ -368,7 +370,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
368
370
  small={getPreviewSizeFrom(size) !== "medium"}
369
371
  valueType={arrayProperty.of.dataType}
370
372
  enumValues={arrayProperty.of.enumValues}
371
- error={error}
373
+ error={validationError ?? error}
372
374
  internalValue={internalValue as string | number}
373
375
  updateValue={updateValue}
374
376
  />;
@@ -401,16 +403,14 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
401
403
 
402
404
  if (!innerComponent) {
403
405
  allowScroll = false;
404
- showExpandIcon = selected && !innerComponent && !disabled && !readOnlyProperty;
406
+ showExpandIcon = enablePopupIcon && selected && !innerComponent && !disabled && !readOnlyProperty;
405
407
  innerComponent = (
406
- <PropertyPreview
407
- width={width}
408
- height={height}
409
- // entity={entity}
410
- propertyKey={propertyKey as string}
411
- value={internalValue}
412
- property={property}
413
- size={getPreviewSizeFrom(size)}
408
+ <PropertyPreview width={width}
409
+ height={height}
410
+ propertyKey={propertyKey as string}
411
+ value={internalValue}
412
+ property={property}
413
+ size={getPreviewSizeFrom(size)}
414
414
  />
415
415
  );
416
416
  }
@@ -427,7 +427,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
427
427
  removePadding={removePadding}
428
428
  fullHeight={fullHeight}
429
429
  saved={saved}
430
- error={error}
430
+ error={validationError ?? error}
431
431
  align={align}
432
432
  allowScroll={allowScroll}
433
433
  showExpandIcon={showExpandIcon}
@@ -447,9 +447,9 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
447
447
  );
448
448
 
449
449
  },
450
- areEqual) as React.FunctionComponent<PropertyTableCellProps<any, any>>;
450
+ areEqual) as React.FunctionComponent<PropertyTableCellProps<any>>;
451
451
 
452
- function areEqual(prevProps: PropertyTableCellProps<any, any>, nextProps: PropertyTableCellProps<any, any>) {
452
+ function areEqual(prevProps: PropertyTableCellProps<any>, nextProps: PropertyTableCellProps<any>) {
453
453
  return prevProps.height === nextProps.height &&
454
454
  prevProps.propertyKey === nextProps.propertyKey &&
455
455
  prevProps.align === nextProps.align &&
@@ -21,7 +21,6 @@ export interface PropertiesToColumnsParams<M extends Record<string, any>> {
21
21
  properties: ResolvedProperties<M>;
22
22
  sortable?: boolean;
23
23
  forceFilter?: FilterValues<keyof M extends string ? keyof M : never>;
24
- disabledFilter?: boolean;
25
24
  AdditionalHeaderWidget?: React.ComponentType<{
26
25
  property: ResolvedProperty,
27
26
  propertyKey: string,
@@ -29,7 +28,8 @@ export interface PropertiesToColumnsParams<M extends Record<string, any>> {
29
28
  }>;
30
29
  }
31
30
 
32
- export function propertiesToColumns<M extends Record<string, any>>({ properties, sortable, forceFilter, disabledFilter, AdditionalHeaderWidget }: PropertiesToColumnsParams<M>): VirtualTableColumn[] {
31
+ export function propertiesToColumns<M extends Record<string, any>>({ properties, sortable, forceFilter, AdditionalHeaderWidget }: PropertiesToColumnsParams<M>): VirtualTableColumn[] {
32
+ const disabledFilter = Boolean(forceFilter);
33
33
  return Object.entries<ResolvedProperty>(properties)
34
34
  .flatMap(([key, property]) => getColumnKeysForProperty(property, key))
35
35
  .map(({
@@ -45,7 +45,7 @@ export function propertiesToColumns<M extends Record<string, any>>({ properties,
45
45
  align: getTableCellAlignment(property),
46
46
  icon: getIconForProperty(property, "small"),
47
47
  title: property.name ?? key as string,
48
- sortable: sortable && (forceFilter ? Object.keys(forceFilter).includes(key) : true),
48
+ sortable: sortable,
49
49
  filter: !disabledFilter && filterable,
50
50
  width: getTablePropertyColumnWidth(property),
51
51
  resizable: true,
@@ -1,7 +1,7 @@
1
1
  import React, { useCallback, useState } from "react";
2
2
  import equal from "react-fast-compare"
3
3
 
4
- import { ReferencePreview, ReferencePreviewContainer } from "../../../preview";
4
+ import { ReferencePreview } from "../../../preview";
5
5
  import { CollectionSize, Entity, EntityCollection, EntityReference, FilterValues } from "../../../types";
6
6
 
7
7
  import { getPreviewSizeFrom } from "../../../preview/util";
@@ -9,6 +9,7 @@ import { getReferenceFrom } from "../../../util";
9
9
  import { useCustomizationController, useNavigationController, useReferenceDialog } from "../../../hooks";
10
10
  import { ErrorView } from "../../ErrorView";
11
11
  import { Button } from "@firecms/ui";
12
+ import { EntityPreviewContainer } from "../../EntityPreview";
12
13
 
13
14
  type TableReferenceFieldProps = {
14
15
  name: string;
@@ -28,7 +29,7 @@ export function TableReferenceField(props: TableReferenceFieldProps) {
28
29
 
29
30
  const navigationController = useNavigationController();
30
31
  const { path } = props;
31
- const collection = navigationController.getCollection<EntityCollection>(path);
32
+ const collection = navigationController.getCollection(path);
32
33
  if (!collection) {
33
34
  if (customizationController.components?.missingReference) {
34
35
  return <customizationController.components.missingReference path={path}/>;
@@ -57,11 +58,6 @@ export const TableReferenceFieldSuccess = React.memo(
57
58
  collection
58
59
  } = props;
59
60
 
60
- const [onHover, setOnHover] = useState(false);
61
-
62
- const hoverTrue = useCallback(() => setOnHover(true), []);
63
- const hoverFalse = useCallback(() => setOnHover(false), []);
64
-
65
61
  const onSingleEntitySelected = useCallback((entity: Entity<any>) => {
66
62
  updateValue(entity ? getReferenceFrom(entity) : null);
67
63
  }, [updateValue]);
@@ -101,29 +97,29 @@ export const TableReferenceFieldSuccess = React.memo(
101
97
  onClick={disabled ? undefined : handleOpen}
102
98
  size={getPreviewSizeFrom(size)}
103
99
  reference={internalValue as EntityReference}
104
- onHover={onHover}
100
+ hover={!disabled}
105
101
  disabled={!path}
106
102
  previewProperties={previewProperties}
107
103
  />;
108
104
  else
109
- return <ReferencePreviewContainer
105
+ return <EntityPreviewContainer
110
106
  onClick={disabled ? undefined : handleOpen}
111
107
  size={getPreviewSizeFrom(size)}>
112
108
  <ErrorView title="Value is not a reference." error={"Click to edit"}/>
113
- </ReferencePreviewContainer>;
109
+ </EntityPreviewContainer>;
114
110
  };
115
111
 
116
112
  const buildMultipleReferenceField = () => {
117
113
  if (Array.isArray(internalValue))
118
114
  return <>
119
115
  {internalValue.map((reference, index) =>
120
- <div className="m-1 w-full"
116
+ <div className="w-full my-0.5"
121
117
  key={`preview_array_ref_${name}_${index}`}>
122
118
  <ReferencePreview
123
119
  onClick={disabled ? undefined : handleOpen}
124
120
  size={"tiny"}
125
121
  reference={reference}
126
- onHover={onHover}
122
+ hover={!disabled}
127
123
  disabled={!path}
128
124
  previewProperties={previewProperties}
129
125
  />
@@ -139,10 +135,7 @@ export const TableReferenceFieldSuccess = React.memo(
139
135
  return <ErrorView error={"The specified collection does not exist"}/>;
140
136
 
141
137
  return (
142
- <div className="w-full"
143
- onMouseEnter={hoverTrue}
144
- onMouseMove={hoverTrue}
145
- onMouseLeave={hoverFalse}>
138
+ <div className="w-full group">
146
139
 
147
140
  {internalValue && !multiselect && buildSingleReferenceField()}
148
141
 
@@ -51,7 +51,7 @@ export function TableStorageUpload(props: {
51
51
  entity,
52
52
  path,
53
53
  previewSize,
54
- updateValue
54
+ updateValue,
55
55
  } = props;
56
56
 
57
57
  const storageSource = useStorageSource();
@@ -137,7 +137,7 @@ function StorageUpload({
137
137
  storage,
138
138
  onFilesAdded,
139
139
  onFileUploadComplete,
140
- storagePathBuilder
140
+ storagePathBuilder,
141
141
  }: StorageUploadProps) {
142
142
 
143
143
  const [onHover, setOnHover] = useState(false);
@@ -293,7 +293,7 @@ export function TableStorageItemPreview({
293
293
 
294
294
  return (
295
295
  <div
296
- className={"relative m-2"}
296
+ className={"relative p-2 max-w-full"}
297
297
  >
298
298
 
299
299
  {value &&
@@ -16,20 +16,27 @@ import { useLargeLayout } from "../../../hooks";
16
16
 
17
17
  interface CollectionTableToolbarProps {
18
18
  size: CollectionSize;
19
- filterIsSet: boolean;
20
19
  loading: boolean;
21
- forceFilter?: boolean;
22
20
  actionsStart?: React.ReactNode;
23
21
  actions?: React.ReactNode;
24
22
  title?: React.ReactNode,
25
23
  onTextSearchClick?: () => void;
26
24
  onTextSearch?: (searchString?: string) => void;
27
25
  onSizeChanged: (size: CollectionSize) => void;
28
- clearFilter?: () => void;
29
26
  textSearchLoading?: boolean;
30
27
  }
31
28
 
32
- export function CollectionTableToolbar(props: CollectionTableToolbarProps) {
29
+ export function CollectionTableToolbar({
30
+ actions,
31
+ actionsStart,
32
+ loading,
33
+ onSizeChanged,
34
+ onTextSearch,
35
+ onTextSearchClick,
36
+ size,
37
+ textSearchLoading,
38
+ title
39
+ }: CollectionTableToolbarProps) {
33
40
 
34
41
  const searchInputRef = React.useRef<HTMLInputElement>(null);
35
42
  const largeLayout = useLargeLayout();
@@ -37,30 +44,20 @@ export function CollectionTableToolbar(props: CollectionTableToolbarProps) {
37
44
  const searchLoading = React.useRef<boolean>(false);
38
45
 
39
46
  useEffect(() => {
40
- if (searchInputRef.current && searchLoading.current && !props.textSearchLoading) {
47
+ if (searchInputRef.current && searchLoading.current && !textSearchLoading) {
41
48
  searchInputRef.current.focus();
42
49
  }
43
- searchLoading.current = props.textSearchLoading ?? false;
44
- }, [props.textSearchLoading]);
45
-
46
- const clearFilterButton = !props.forceFilter && props.filterIsSet && props.clearFilter &&
47
- <Button
48
- variant={"outlined"}
49
- className="h-fit-content"
50
- aria-label="filter clear"
51
- onClick={props.clearFilter}
52
- size="small">
53
- <FilterListOffIcon/>
54
- Clear filter
55
- </Button>;
50
+ searchLoading.current = textSearchLoading ?? false;
51
+ }, [textSearchLoading]);
52
+
56
53
 
57
54
  const sizeSelect = (
58
55
  <Tooltip title={"Table row size"} side={"right"} sideOffset={4}>
59
56
  <Select
60
- value={props.size as string}
57
+ value={size as string}
61
58
  className="w-16 h-10"
62
59
  size={"small"}
63
- onValueChange={(v) => props.onSizeChanged(v as CollectionSize)}
60
+ onValueChange={(v) => onSizeChanged(v as CollectionSize)}
64
61
  renderValue={(v) => <div className={"font-medium"}>{v.toUpperCase()}</div>}
65
62
  >
66
63
  {["xs", "s", "m", "l", "xl"].map((size) => (
@@ -78,36 +75,34 @@ export function CollectionTableToolbar(props: CollectionTableToolbarProps) {
78
75
 
79
76
  <div className="flex items-center gap-2 md:mr-4 mr-2">
80
77
 
81
- {props.title && <div className={"hidden lg:block"}>
82
- {props.title}
78
+ {title && <div className={"hidden lg:block"}>
79
+ {title}
83
80
  </div>}
84
81
 
85
82
  {sizeSelect}
86
83
 
87
- {props.actionsStart}
88
-
89
- {clearFilterButton}
84
+ {actionsStart}
90
85
 
91
86
  </div>
92
87
 
93
88
  <div className="flex items-center gap-2">
94
89
 
95
90
  {largeLayout && <div className="w-[22px]">
96
- {props.loading &&
91
+ {loading &&
97
92
  <CircularProgress size={"small"}/>}
98
93
  </div>}
99
94
 
100
- {(props.onTextSearch || props.onTextSearchClick) &&
95
+ {(onTextSearch || onTextSearchClick) &&
101
96
  <SearchBar
102
97
  key={"search-bar"}
103
98
  inputRef={searchInputRef}
104
- loading={props.textSearchLoading}
105
- disabled={Boolean(props.onTextSearchClick)}
106
- onClick={props.onTextSearchClick}
107
- onTextSearch={props.onTextSearchClick ? undefined : props.onTextSearch}
99
+ loading={textSearchLoading}
100
+ disabled={Boolean(onTextSearchClick)}
101
+ onClick={onTextSearchClick}
102
+ onTextSearch={onTextSearchClick ? undefined : onTextSearch}
108
103
  expandable={true}/>}
109
104
 
110
- {props.actions}
105
+ {actions}
111
106
 
112
107
  </div>
113
108
 
@@ -96,7 +96,7 @@ export const EntityTableCell = React.memo<EntityTableCellProps>(
96
96
  const [onHover, setOnHover] = useState(false);
97
97
  const [internalSaved, setInternalSaved] = useState(saved);
98
98
 
99
- const showError = !disabled && error;
99
+ const showError = !disabled && Boolean(error);
100
100
 
101
101
  useEffect(() => {
102
102
  if (saved) {
@@ -176,21 +176,26 @@ export const EntityTableCell = React.memo<EntityTableCellProps>(
176
176
  const setOnHoverTrue = useCallback(() => setOnHover(true), []);
177
177
  const setOnHoverFalse = useCallback(() => setOnHover(false), []);
178
178
 
179
+ const borderClass = showError
180
+ ? "border-red-500"
181
+ : internalSaved
182
+ ? "border-green-500"
183
+ : isSelected
184
+ ? "border-primary"
185
+ : "border-transparent";
186
+
179
187
  return (
180
188
  <div
181
- ref={ref}
182
189
  className={cn(
183
190
  "transition-colors duration-100 ease-in-out",
184
191
  `flex relative h-full rounded-md p-${p} border border-4 border-opacity-75`,
185
192
  onHover && !disabled ? "bg-gray-50 dark:bg-gray-900" : "",
186
193
  saved ? "bg-gray-100 bg-opacity-75 dark:bg-gray-800 dark:bg-opacity-75" : "",
187
- !isSelected && !internalSaved && !showError ? "border-transparent" : "",
188
194
  hideOverflow ? "overflow-hidden" : "",
189
195
  isSelected ? "bg-gray-50 dark:bg-gray-900" : "",
190
- isSelected && !internalSaved ? "border-primary" : "",
191
- internalSaved ? "border-green-500 " : "",
192
- showError ? "border-red-500" : ""
196
+ borderClass
193
197
  )}
198
+ ref={ref}
194
199
  style={{
195
200
  justifyContent,
196
201
  alignItems: disabled || !isOverflowing ? "center" : undefined,
@@ -9,21 +9,23 @@ export const editEntityAction: EntityAction = {
9
9
  onClick({
10
10
  entity,
11
11
  collection,
12
+ fullPath,
12
13
  context,
13
14
  highlightEntity,
14
- unhighlightEntity
15
+ unhighlightEntity,
15
16
  }): Promise<void> {
16
17
  highlightEntity?.(entity);
17
18
  context.analyticsController?.onAnalyticsEvent?.("entity_click", {
18
19
  path: entity.path,
19
20
  entityId: entity.id
20
21
  });
22
+ const path = collection?.collectionGroup ? entity.path : (fullPath ?? entity.path);
21
23
  context.sideEntityController.open({
22
24
  entityId: entity.id,
23
- path: entity.path,
25
+ path,
24
26
  collection,
25
27
  updateUrl: true,
26
- onClose: () => unhighlightEntity?.(entity)
28
+ onClose: () => unhighlightEntity?.(entity),
27
29
  });
28
30
  return Promise.resolve(undefined);
29
31
  }
@@ -37,7 +39,7 @@ export const copyEntityAction: EntityAction = {
37
39
  collection,
38
40
  context,
39
41
  highlightEntity,
40
- unhighlightEntity
42
+ unhighlightEntity,
41
43
  }): Promise<void> {
42
44
  highlightEntity?.(entity);
43
45
  context.analyticsController?.onAnalyticsEvent?.("copy_entity_click", {
@@ -50,11 +52,12 @@ export const copyEntityAction: EntityAction = {
50
52
  copy: true,
51
53
  collection,
52
54
  updateUrl: true,
53
- onClose: () => unhighlightEntity?.(entity)
55
+ onClose: () => unhighlightEntity?.(entity),
54
56
  });
55
57
  return Promise.resolve(undefined);
56
58
  }
57
59
  }
60
+
58
61
  export const archiveEntityAction: EntityAction = {
59
62
  icon: <ArchiveIcon/>,
60
63
  name: "Archive",
@@ -69,6 +72,7 @@ export const archiveEntityAction: EntityAction = {
69
72
  return Promise.resolve(undefined);
70
73
  }
71
74
  }
75
+
72
76
  export const openWebsiteAction: EntityAction = {
73
77
  icon: <OpenInNewIcon/>,
74
78
  name: "See in website",
@@ -41,7 +41,7 @@ interface PopupFormFieldProps<M extends Record<string, any>> {
41
41
  * Callback when the value of a cell has been edited
42
42
  * @param params
43
43
  */
44
- onCellValueChange?: (params: OnCellValueChangeParams<any, M>) => Promise<void> | void;
44
+ onCellValueChange?: (params: OnCellValueChangeParams<any, any>) => Promise<void> | void;
45
45
  }
46
46
 
47
47
  export function PopupFormField<M extends Record<string, any>>(props: PopupFormFieldProps<M>) {
@@ -205,12 +205,10 @@ export function PopupFormFieldInternal<M extends Record<string, any>>({
205
205
  return onCellValueChange({
206
206
  value: values[propertyKey as string],
207
207
  propertyKey: propertyKey as string,
208
- entity,
208
+ data: entity,
209
209
  setError: setSavingError,
210
210
  onValueUpdated: () => {
211
211
  },
212
- fullPath: path,
213
- context: fireCMSContext
214
212
  });
215
213
  }
216
214
  return Promise.resolve();