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

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 (271) hide show
  1. package/README.md +2 -2
  2. package/dist/app/AppBar.d.ts +12 -0
  3. package/dist/app/Drawer.d.ts +17 -0
  4. package/dist/app/Scaffold.d.ts +30 -0
  5. package/dist/app/index.d.ts +4 -0
  6. package/dist/app/useApp.d.ts +16 -0
  7. package/dist/components/ClearFilterSortButton.d.ts +5 -0
  8. package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +11 -11
  9. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +2 -2
  10. package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +5 -3
  11. package/dist/components/EntityCollectionTable/PropertyTableCell.d.ts +3 -2
  12. package/dist/components/EntityCollectionTable/column_utils.d.ts +1 -2
  13. package/dist/components/EntityCollectionTable/fields/TableReferenceField.d.ts +2 -0
  14. package/dist/components/EntityCollectionTable/internal/CollectionTableToolbar.d.ts +1 -4
  15. package/dist/components/EntityCollectionTable/internal/EntityTableCell.d.ts +2 -2
  16. package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +1 -1
  17. package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +12 -3
  18. package/dist/components/EntityCollectionView/EntityCollectionViewStartActions.d.ts +11 -0
  19. package/dist/components/EntityCollectionView/useSelectionController.d.ts +2 -0
  20. package/dist/components/EntityPreview.d.ts +26 -7
  21. package/dist/components/EntityView.d.ts +11 -0
  22. package/dist/components/FieldCaption.d.ts +5 -0
  23. package/dist/components/HomePage/NavigationCard.d.ts +8 -0
  24. package/dist/components/HomePage/{NavigationCollectionCard.d.ts → NavigationCardBinding.d.ts} +2 -2
  25. package/dist/components/HomePage/SmallNavigationCard.d.ts +6 -0
  26. package/dist/components/HomePage/index.d.ts +3 -1
  27. package/dist/components/ReferenceWidget.d.ts +3 -1
  28. package/dist/components/SelectableTable/SelectableTable.d.ts +1 -1
  29. package/dist/components/SelectableTable/filters/ReferenceFilterField.d.ts +2 -1
  30. package/dist/components/VirtualTable/VirtualTableProps.d.ts +6 -7
  31. package/dist/components/VirtualTable/types.d.ts +3 -3
  32. package/dist/components/{EntityCollectionTable/internal → common}/default_entity_actions.d.ts +1 -1
  33. package/dist/components/common/index.d.ts +1 -0
  34. package/dist/components/common/table_height.d.ts +5 -0
  35. package/dist/components/common/types.d.ts +4 -6
  36. package/dist/components/common/useDataSourceEntityCollectionTableController.d.ts +3 -0
  37. package/dist/components/index.d.ts +6 -3
  38. package/dist/contexts/AuthControllerContext.d.ts +1 -1
  39. package/dist/{components/FireCMSAppBar.d.ts → core/DefaultAppBar.d.ts} +5 -8
  40. package/dist/core/DefaultDrawer.d.ts +19 -0
  41. package/dist/core/DrawerNavigationItem.d.ts +9 -0
  42. package/dist/core/EntityEditView.d.ts +36 -0
  43. package/dist/core/NavigationRoutes.d.ts +2 -2
  44. package/dist/core/index.d.ts +3 -4
  45. package/dist/form/PropertiesForm.d.ts +8 -0
  46. package/dist/form/components/ErrorFocus.d.ts +1 -1
  47. package/dist/form/components/FieldHelperText.d.ts +3 -3
  48. package/dist/form/components/StorageItemPreview.d.ts +2 -3
  49. package/dist/form/components/StorageUploadProgress.d.ts +1 -1
  50. package/dist/form/field_bindings/KeyValueFieldBinding.d.ts +1 -1
  51. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  52. package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +3 -4
  53. package/dist/form/field_bindings/TextFieldBinding.d.ts +2 -2
  54. package/dist/form/index.d.ts +0 -2
  55. package/dist/form/validation.d.ts +1 -1
  56. package/dist/hooks/data/delete.d.ts +2 -2
  57. package/dist/hooks/data/save.d.ts +2 -3
  58. package/dist/hooks/data/useDataSource.d.ts +2 -2
  59. package/dist/hooks/data/useEntityFetch.d.ts +3 -3
  60. package/dist/hooks/index.d.ts +2 -0
  61. package/dist/hooks/useBuildNavigationController.d.ts +6 -4
  62. package/dist/hooks/useProjectLog.d.ts +6 -2
  63. package/dist/hooks/useStorageSource.d.ts +2 -2
  64. package/dist/hooks/useValidateAuthenticator.d.ts +21 -0
  65. package/dist/index.d.ts +1 -0
  66. package/dist/index.es.js +10512 -9997
  67. package/dist/index.es.js.map +1 -1
  68. package/dist/index.umd.js +5 -5
  69. package/dist/index.umd.js.map +1 -1
  70. package/dist/internal/useBuildDataSource.d.ts +1 -16
  71. package/dist/preview/PropertyPreview.d.ts +1 -1
  72. package/dist/preview/PropertyPreviewProps.d.ts +1 -4
  73. package/dist/preview/components/BooleanPreview.d.ts +5 -1
  74. package/dist/preview/components/EnumValuesChip.d.ts +1 -1
  75. package/dist/preview/components/ReferencePreview.d.ts +3 -8
  76. package/dist/types/analytics.d.ts +1 -1
  77. package/dist/types/auth.d.ts +37 -1
  78. package/dist/types/collections.d.ts +44 -6
  79. package/dist/types/datasource.d.ts +21 -14
  80. package/dist/types/entities.d.ts +5 -1
  81. package/dist/types/entity_actions.d.ts +14 -0
  82. package/dist/types/entity_callbacks.d.ts +2 -2
  83. package/dist/types/entity_overrides.d.ts +6 -0
  84. package/dist/types/fields.d.ts +31 -30
  85. package/dist/types/index.d.ts +2 -1
  86. package/dist/types/navigation.d.ts +15 -14
  87. package/dist/types/permissions.d.ts +5 -1
  88. package/dist/types/plugins.d.ts +22 -22
  89. package/dist/types/properties.d.ts +13 -5
  90. package/dist/types/property_config.d.ts +2 -2
  91. package/dist/types/roles.d.ts +31 -0
  92. package/dist/types/storage.d.ts +11 -3
  93. package/dist/types/user.d.ts +5 -0
  94. package/dist/util/collections.d.ts +9 -1
  95. package/dist/util/entities.d.ts +1 -1
  96. package/dist/util/icon_synonyms.d.ts +1 -97
  97. package/dist/util/icons.d.ts +8 -2
  98. package/dist/util/navigation_utils.d.ts +2 -2
  99. package/dist/util/objects.d.ts +1 -1
  100. package/dist/util/permissions.d.ts +4 -4
  101. package/dist/util/references.d.ts +4 -2
  102. package/dist/util/resolutions.d.ts +14 -14
  103. package/dist/util/storage.d.ts +23 -2
  104. package/dist/util/useStorageUploadController.d.ts +1 -1
  105. package/dist/util/useTraceUpdate.d.ts +1 -0
  106. package/package.json +139 -119
  107. package/src/app/AppBar.tsx +18 -0
  108. package/src/app/Drawer.tsx +25 -0
  109. package/src/app/Scaffold.tsx +249 -0
  110. package/src/app/index.ts +4 -0
  111. package/src/app/useApp.tsx +32 -0
  112. package/src/components/ClearFilterSortButton.tsx +41 -0
  113. package/src/components/DeleteEntityDialog.tsx +4 -4
  114. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +4 -4
  115. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +276 -279
  116. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +9 -5
  117. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +48 -45
  118. package/src/components/EntityCollectionTable/column_utils.tsx +3 -3
  119. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +18 -17
  120. package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +5 -5
  121. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +29 -34
  122. package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +16 -12
  123. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +4 -5
  124. package/src/components/EntityCollectionView/EntityCollectionView.tsx +73 -72
  125. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +5 -6
  126. package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +68 -0
  127. package/src/components/EntityCollectionView/useSelectionController.tsx +30 -0
  128. package/src/components/EntityPreview.tsx +209 -70
  129. package/src/components/EntityView.tsx +84 -0
  130. package/src/components/FieldCaption.tsx +14 -0
  131. package/src/components/HomePage/DefaultHomePage.tsx +15 -11
  132. package/src/components/HomePage/NavigationCard.tsx +69 -0
  133. package/src/components/HomePage/NavigationCardBinding.tsx +116 -0
  134. package/src/components/HomePage/SmallNavigationCard.tsx +45 -0
  135. package/src/components/HomePage/index.tsx +3 -1
  136. package/src/components/PropertyIdCopyTooltipContent.tsx +2 -3
  137. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +4 -4
  138. package/src/components/ReferenceWidget.tsx +22 -12
  139. package/src/components/SearchIconsView.tsx +5 -5
  140. package/src/components/SelectableTable/SelectableTable.tsx +5 -3
  141. package/src/components/SelectableTable/filters/BooleanFilterField.tsx +2 -3
  142. package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +23 -8
  143. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +38 -24
  144. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +35 -15
  145. package/src/components/VirtualTable/VirtualTable.tsx +38 -29
  146. package/src/components/VirtualTable/VirtualTableHeader.tsx +4 -4
  147. package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +2 -2
  148. package/src/components/VirtualTable/VirtualTableProps.tsx +7 -7
  149. package/src/components/VirtualTable/VirtualTableRow.tsx +4 -5
  150. package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +1 -1
  151. package/src/components/VirtualTable/types.tsx +2 -3
  152. package/src/components/{EntityCollectionTable/internal → common}/default_entity_actions.tsx +11 -7
  153. package/src/components/common/index.ts +1 -0
  154. package/src/components/{VirtualTable/common.tsx → common/table_height.tsx} +5 -2
  155. package/src/components/common/types.tsx +4 -6
  156. package/src/components/common/useColumnsIds.tsx +10 -2
  157. package/src/components/common/useDataSourceEntityCollectionTableController.tsx +12 -1
  158. package/src/components/common/useTableSearchHelper.ts +39 -9
  159. package/src/components/index.tsx +6 -3
  160. package/src/contexts/AuthControllerContext.tsx +1 -1
  161. package/src/{components/FireCMSAppBar.tsx → core/DefaultAppBar.tsx} +51 -34
  162. package/src/core/DefaultDrawer.tsx +177 -0
  163. package/src/core/DrawerNavigationItem.tsx +62 -0
  164. package/src/core/EntityEditView.tsx +1101 -0
  165. package/src/core/EntitySidePanel.tsx +3 -4
  166. package/src/core/FireCMS.tsx +54 -43
  167. package/src/core/NavigationRoutes.tsx +14 -7
  168. package/src/core/field_configs.tsx +2 -3
  169. package/src/core/index.tsx +3 -4
  170. package/src/form/PropertiesForm.tsx +81 -0
  171. package/src/form/PropertyFieldBinding.tsx +29 -7
  172. package/src/form/components/FieldHelperText.tsx +3 -3
  173. package/src/form/components/StorageItemPreview.tsx +5 -7
  174. package/src/form/components/StorageUploadProgress.tsx +9 -8
  175. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +10 -12
  176. package/src/form/field_bindings/BlockFieldBinding.tsx +2 -2
  177. package/src/form/field_bindings/DateTimeFieldBinding.tsx +1 -1
  178. package/src/form/field_bindings/KeyValueFieldBinding.tsx +19 -19
  179. package/src/form/field_bindings/MapFieldBinding.tsx +25 -17
  180. package/src/form/field_bindings/MarkdownFieldBinding.tsx +2 -2
  181. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +2 -9
  182. package/src/form/field_bindings/ReferenceFieldBinding.tsx +16 -13
  183. package/src/form/field_bindings/SelectFieldBinding.tsx +3 -3
  184. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +14 -35
  185. package/src/form/field_bindings/TextFieldBinding.tsx +7 -5
  186. package/src/form/index.tsx +4 -4
  187. package/src/form/validation.ts +4 -21
  188. package/src/hooks/data/delete.ts +3 -3
  189. package/src/hooks/data/save.ts +4 -2
  190. package/src/hooks/data/useCollectionFetch.tsx +1 -1
  191. package/src/hooks/data/useDataSource.tsx +8 -3
  192. package/src/hooks/data/useEntityFetch.tsx +4 -4
  193. package/src/hooks/index.tsx +3 -0
  194. package/src/hooks/useBuildLocalConfigurationPersistence.tsx +8 -10
  195. package/src/hooks/useBuildModeController.tsx +11 -5
  196. package/src/hooks/useBuildNavigationController.tsx +200 -83
  197. package/src/hooks/useProjectLog.tsx +17 -7
  198. package/src/hooks/useReferenceDialog.tsx +2 -2
  199. package/src/hooks/useResolvedNavigationFrom.tsx +1 -1
  200. package/src/hooks/useStorageSource.tsx +7 -2
  201. package/src/hooks/useValidateAuthenticator.tsx +115 -0
  202. package/src/index.ts +1 -0
  203. package/src/internal/useBuildDataSource.ts +54 -47
  204. package/src/internal/useBuildSideEntityController.tsx +88 -21
  205. package/src/preview/PropertyPreview.tsx +5 -15
  206. package/src/preview/PropertyPreviewProps.tsx +1 -11
  207. package/src/preview/components/BooleanPreview.tsx +19 -4
  208. package/src/preview/components/EnumValuesChip.tsx +2 -2
  209. package/src/preview/components/ReferencePreview.tsx +72 -165
  210. package/src/preview/property_previews/ArrayOfMapsPreview.tsx +0 -1
  211. package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +2 -1
  212. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +0 -1
  213. package/src/preview/property_previews/ArrayOfStringsPreview.tsx +0 -1
  214. package/src/preview/property_previews/ArrayOneOfPreview.tsx +2 -3
  215. package/src/preview/property_previews/ArrayPropertyPreview.tsx +2 -3
  216. package/src/preview/property_previews/MapPropertyPreview.tsx +5 -5
  217. package/src/preview/property_previews/StringPropertyPreview.tsx +8 -7
  218. package/src/types/analytics.ts +1 -0
  219. package/src/types/auth.tsx +50 -1
  220. package/src/types/collections.ts +51 -6
  221. package/src/types/customization_controller.tsx +0 -1
  222. package/src/types/datasource.ts +24 -17
  223. package/src/types/entities.ts +9 -1
  224. package/src/types/entity_actions.tsx +17 -0
  225. package/src/types/entity_callbacks.ts +2 -2
  226. package/src/types/entity_overrides.tsx +7 -0
  227. package/src/types/fields.tsx +33 -33
  228. package/src/types/firecms.tsx +0 -1
  229. package/src/types/index.ts +2 -1
  230. package/src/types/navigation.ts +17 -17
  231. package/src/types/permissions.ts +6 -1
  232. package/src/types/plugins.tsx +28 -30
  233. package/src/types/properties.ts +19 -7
  234. package/src/types/property_config.tsx +2 -2
  235. package/src/types/roles.ts +41 -0
  236. package/src/types/side_entity_controller.tsx +1 -0
  237. package/src/types/storage.ts +12 -3
  238. package/src/types/user.ts +7 -0
  239. package/src/util/collections.ts +22 -0
  240. package/src/util/entities.ts +2 -1
  241. package/src/util/enums.ts +1 -1
  242. package/src/util/icon_list.ts +2 -2
  243. package/src/util/icon_synonyms.ts +3 -99
  244. package/src/util/icons.tsx +11 -3
  245. package/src/util/navigation_utils.ts +6 -6
  246. package/src/util/objects.ts +8 -21
  247. package/src/util/permissions.ts +12 -8
  248. package/src/util/references.ts +36 -5
  249. package/src/util/resolutions.ts +32 -31
  250. package/src/util/storage.ts +75 -21
  251. package/src/util/strings.ts +2 -2
  252. package/src/util/useStorageUploadController.tsx +21 -3
  253. package/src/util/useTraceUpdate.tsx +2 -1
  254. package/dist/components/VirtualTable/common.d.ts +0 -2
  255. package/dist/core/Drawer.d.ts +0 -23
  256. package/dist/core/EntityView.d.ts +0 -22
  257. package/dist/core/Scaffold.d.ts +0 -55
  258. package/dist/core/SideEntityView.d.ts +0 -7
  259. package/dist/form/EntityForm.d.ts +0 -77
  260. package/dist/internal/useBuildCustomizationController.d.ts +0 -2
  261. package/dist/internal/useLocaleConfig.d.ts +0 -1
  262. package/dist/types/appcheck.d.ts +0 -26
  263. package/src/components/HomePage/NavigationCollectionCard.tsx +0 -146
  264. package/src/core/Drawer.tsx +0 -164
  265. package/src/core/EntityView.tsx +0 -578
  266. package/src/core/Scaffold.tsx +0 -281
  267. package/src/core/SideEntityView.tsx +0 -38
  268. package/src/form/EntityForm.tsx +0 -720
  269. package/src/internal/useBuildCustomizationController.tsx +0 -5
  270. package/src/internal/useLocaleConfig.tsx +0 -18
  271. package/src/types/appcheck.ts +0 -29
@@ -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();
@@ -266,7 +264,8 @@ export function PopupFormFieldInternal<M extends Record<string, any>>({
266
264
  values,
267
265
  path,
268
266
  setFieldValue,
269
- save: saveValue
267
+ save: saveValue,
268
+ formex
270
269
  };
271
270
 
272
271
  const property: ResolvedProperty<any> | undefined = propertyKey && getPropertyInPath(collection.properties, propertyKey as string);
@@ -12,8 +12,7 @@ import {
12
12
  PartialEntityCollection,
13
13
  PropertyOrBuilder,
14
14
  ResolvedProperty,
15
- SaveEntityProps,
16
- SelectionController
15
+ SaveEntityProps
17
16
  } from "../../types";
18
17
  import {
19
18
  EntityCollectionRowActions,
@@ -25,7 +24,6 @@ import {
25
24
  canCreateEntity,
26
25
  canDeleteEntity,
27
26
  canEditEntity,
28
- fullPathToCollectionSegments,
29
27
  getPropertyInPath,
30
28
  mergeDeep,
31
29
  resolveCollection,
@@ -37,6 +35,7 @@ import {
37
35
  useAuthController,
38
36
  useCustomizationController,
39
37
  useDataSource,
38
+ useFireCMSContext,
40
39
  useLargeLayout,
41
40
  useNavigationController,
42
41
  useSideEntityController
@@ -46,7 +45,7 @@ import { EntityCollectionViewActions } from "./EntityCollectionViewActions";
46
45
  import {
47
46
  AddIcon,
48
47
  Button,
49
- cn,
48
+ cls,
50
49
  IconButton,
51
50
  KeyboardTabIcon,
52
51
  Markdown,
@@ -67,13 +66,11 @@ import {
67
66
  } from "../common";
68
67
  import { PopupFormField } from "../EntityCollectionTable/internal/popup_field/PopupFormField";
69
68
  import { GetPropertyForProps } from "../EntityCollectionTable/EntityCollectionTableProps";
70
- import {
71
- copyEntityAction,
72
- deleteEntityAction,
73
- editEntityAction
74
- } from "../EntityCollectionTable/internal/default_entity_actions";
69
+ import { copyEntityAction, deleteEntityAction, editEntityAction } from "../common/default_entity_actions";
75
70
  import { DeleteEntityDialog } from "../DeleteEntityDialog";
76
71
  import { useAnalyticsController } from "../../hooks/useAnalyticsController";
72
+ import { useSelectionController } from "./useSelectionController";
73
+ import { EntityCollectionViewStartActions } from "./EntityCollectionViewStartActions";
77
74
 
78
75
  const COLLECTION_GROUP_PARENT_ID = "collectionGroupParent";
79
76
 
@@ -81,10 +78,22 @@ const COLLECTION_GROUP_PARENT_ID = "collectionGroupParent";
81
78
  * @group Components
82
79
  */
83
80
  export type EntityCollectionViewProps<M extends Record<string, any>> = {
84
- fullPath: string;
81
+ /**
82
+ * Complete path where this collection is located.
83
+ * It defaults to the collection path if not provided.
84
+ */
85
+ fullPath?: string;
86
+ /**
87
+ * If this is a subcollection, specify the parent collection ids.
88
+ */
85
89
  parentCollectionIds?: string[];
90
+ /**
91
+ * Whether this is a subcollection or not.
92
+ */
86
93
  isSubCollection?: boolean;
94
+
87
95
  className?: string;
96
+
88
97
  } & EntityCollection<M>;
89
98
 
90
99
  /**
@@ -113,7 +122,7 @@ export type EntityCollectionViewProps<M extends Record<string, any>> = {
113
122
  */
114
123
  export const EntityCollectionView = React.memo(
115
124
  function EntityCollectionView<M extends Record<string, any>>({
116
- fullPath,
125
+ fullPath: fullPathProp,
117
126
  parentCollectionIds,
118
127
  isSubCollection,
119
128
  className,
@@ -121,7 +130,9 @@ export const EntityCollectionView = React.memo(
121
130
  }: EntityCollectionViewProps<M>
122
131
  ) {
123
132
 
124
- const dataSource = useDataSource();
133
+ const context = useFireCMSContext();
134
+ const fullPath = fullPathProp ?? collectionProp.path;
135
+ const dataSource = useDataSource(collectionProp);
125
136
  const navigation = useNavigationController();
126
137
  const sideEntityController = useSideEntityController();
127
138
  const authController = useAuthController();
@@ -141,7 +152,7 @@ export const EntityCollectionView = React.memo(
141
152
  collectionRef.current = collection;
142
153
  }, [collection]);
143
154
 
144
- const canCreateEntities = canCreateEntity(collection, authController, fullPathToCollectionSegments(fullPath), null);
155
+ const canCreateEntities = canCreateEntity(collection, authController, fullPath, null);
145
156
  const [selectedNavigationEntity, setSelectedNavigationEntity] = useState<Entity<M> | undefined>(undefined);
146
157
  const [deleteEntityClicked, setDeleteEntityClicked] = React.useState<Entity<M> | Entity<M>[] | undefined>(undefined);
147
158
 
@@ -160,7 +171,7 @@ export const EntityCollectionView = React.memo(
160
171
 
161
172
  const checkInlineEditing = useCallback((entity?: Entity<any>): boolean => {
162
173
  const collection = collectionRef.current;
163
- if (!canEditEntity(collection, authController, fullPathToCollectionSegments(fullPath), entity ?? null)) {
174
+ if (!canEditEntity(collection, authController, fullPath, entity ?? null)) {
164
175
  return false;
165
176
  }
166
177
  return collection.inlineEditing === undefined || collection.inlineEditing;
@@ -175,7 +186,6 @@ export const EntityCollectionView = React.memo(
175
186
  const usedSelectionController = collection.selectionController ?? selectionController;
176
187
  const {
177
188
  selectedEntities,
178
- toggleEntitySelection,
179
189
  isEntitySelected,
180
190
  setSelectedEntities
181
191
  } = usedSelectionController;
@@ -186,8 +196,7 @@ export const EntityCollectionView = React.memo(
186
196
 
187
197
  const tableController = useDataSourceEntityCollectionTableController<M>({
188
198
  fullPath,
189
- collection: collectionRef.current,
190
- entitiesDisplayedFirst: [],
199
+ collection,
191
200
  lastDeleteTimestamp
192
201
  });
193
202
 
@@ -199,6 +208,7 @@ export const EntityCollectionView = React.memo(
199
208
  }, [tableController.setPopupCell]);
200
209
 
201
210
  const onEntityClick = useCallback((clickedEntity: Entity<M>) => {
211
+ console.log("Entity clicked", clickedEntity)
202
212
  const collection = collectionRef.current;
203
213
  setSelectedNavigationEntity(clickedEntity);
204
214
  analyticsController.onAnalyticsEvent?.("edit_entity_clicked", {
@@ -210,9 +220,9 @@ export const EntityCollectionView = React.memo(
210
220
  path: clickedEntity.path,
211
221
  collection,
212
222
  updateUrl: true,
213
- onClose: unselectNavigatedEntity
223
+ onClose: unselectNavigatedEntity,
214
224
  });
215
- }, [unselectNavigatedEntity]);
225
+ }, [unselectNavigatedEntity, sideEntityController]);
216
226
 
217
227
  const onNewClick = useCallback(() => {
218
228
 
@@ -224,9 +234,9 @@ export const EntityCollectionView = React.memo(
224
234
  path: fullPath,
225
235
  collection,
226
236
  updateUrl: true,
227
- onClose: unselectNavigatedEntity
237
+ onClose: unselectNavigatedEntity,
228
238
  });
229
- }, [fullPath]);
239
+ }, [fullPath, sideEntityController]);
230
240
 
231
241
  const onMultipleDeleteClick = () => {
232
242
  analyticsController.onAnalyticsEvent?.("multiple_delete_dialog_open", {
@@ -288,7 +298,7 @@ export const EntityCollectionView = React.memo(
288
298
  onCollectionModifiedForUser(fullPath, { defaultSize: size })
289
299
  }, [onCollectionModifiedForUser, fullPath, userConfigPersistence]);
290
300
 
291
- const createEnabled = canCreateEntity(collection, authController, fullPathToCollectionSegments(fullPath), null);
301
+ const createEnabled = canCreateEntity(collection, authController, fullPath, null);
292
302
 
293
303
  const uniqueFieldValidator: UniqueFieldValidator = useCallback(
294
304
  ({
@@ -300,13 +310,11 @@ export const EntityCollectionView = React.memo(
300
310
  [fullPath]);
301
311
 
302
312
  const onValueChange: OnCellValueChange<any, any> = ({
303
- fullPath,
304
- context,
305
313
  value,
306
314
  propertyKey,
307
315
  onValueUpdated,
308
316
  setError,
309
- entity,
317
+ data: entity,
310
318
  }) => {
311
319
 
312
320
  const updatedValues = setIn({ ...entity.values }, propertyKey, value);
@@ -323,10 +331,12 @@ export const EntityCollectionView = React.memo(
323
331
  return saveEntityWithCallbacks({
324
332
  ...saveProps,
325
333
  collection,
326
- callbacks: collection.callbacks,
327
334
  dataSource,
328
335
  context,
329
- onSaveSuccess: () => onValueUpdated(),
336
+ onSaveSuccess: () => {
337
+ setError(undefined);
338
+ onValueUpdated();
339
+ },
330
340
  onSaveFailure: (e: Error) => {
331
341
  console.error("Save failure");
332
342
  console.error(e);
@@ -345,7 +355,6 @@ export const EntityCollectionView = React.memo(
345
355
 
346
356
  const getPropertyFor = useCallback(({
347
357
  propertyKey,
348
- propertyValue,
349
358
  entity
350
359
  }: GetPropertyForProps<M>) => {
351
360
  let propertyOrBuilder: PropertyOrBuilder<any, M> | undefined = getPropertyInPath<M>(collection.properties, propertyKey);
@@ -360,7 +369,6 @@ export const EntityCollectionView = React.memo(
360
369
  propertyKey,
361
370
  propertyOrBuilder,
362
371
  path: fullPath,
363
- propertyValue,
364
372
  values: entity.values,
365
373
  entityId: entity.id,
366
374
  fields: customizationController.propertyConfigs
@@ -387,7 +395,7 @@ export const EntityCollectionView = React.memo(
387
395
  entityId: entity.id,
388
396
  selectedSubPath: subcollection.id ?? subcollection.path,
389
397
  collection,
390
- updateUrl: true
398
+ updateUrl: true,
391
399
  });
392
400
  }}>
393
401
  {subcollection.name}
@@ -405,7 +413,7 @@ export const EntityCollectionView = React.memo(
405
413
  Builder: ({ entity }) => {
406
414
  const collectionsWithPath = navigation.getParentReferencesFromPath(entity.path);
407
415
  return (
408
- <>
416
+ <div className={"flex flex-col gap-2 w-full"}>
409
417
  {collectionsWithPath.map((reference) => {
410
418
  return (
411
419
  <ReferencePreview
@@ -414,7 +422,7 @@ export const EntityCollectionView = React.memo(
414
422
  size={"tiny"}/>
415
423
  );
416
424
  })}
417
- </>
425
+ </div>
418
426
  );
419
427
  }
420
428
  }]
@@ -425,7 +433,7 @@ export const EntityCollectionView = React.memo(
425
433
  ...subcollectionColumns,
426
434
  ...collectionGroupParentCollections
427
435
  ];
428
- }, [collection, fullPath]);
436
+ }, [collection, fullPath, sideEntityController]);
429
437
 
430
438
  const updateLastDeleteTimestamp = useCallback(() => {
431
439
  setLastDeleteTimestamp(Date.now());
@@ -433,11 +441,14 @@ export const EntityCollectionView = React.memo(
433
441
 
434
442
  const largeLayout = useLargeLayout();
435
443
 
436
- const getActionsForEntity = ({ entity, customEntityActions }: {
444
+ const getActionsForEntity = ({
445
+ entity,
446
+ customEntityActions
447
+ }: {
437
448
  entity?: Entity<M>,
438
449
  customEntityActions?: EntityAction[]
439
450
  }): EntityAction[] => {
440
- const deleteEnabled = entity ? canDeleteEntity(collection, authController, fullPathToCollectionSegments(fullPath), entity) : true;
451
+ const deleteEnabled = entity ? canDeleteEntity(collection, authController, fullPath, entity) : true;
441
452
  const actions: EntityAction[] = [editEntityAction];
442
453
  if (createEnabled)
443
454
  actions.push(copyEntityAction);
@@ -448,13 +459,13 @@ export const EntityCollectionView = React.memo(
448
459
  return actions;
449
460
  };
450
461
 
451
- const getIdColumnWidth = useCallback(() => {
462
+ const getIdColumnWidth = () => {
452
463
  const entityActions = getActionsForEntity({});
453
464
  const collapsedActions = entityActions.filter(a => a.collapsed !== false);
454
465
  const uncollapsedActions = entityActions.filter(a => a.collapsed === false);
455
466
  const actionsWidth = uncollapsedActions.length * (largeLayout ? 40 : 30);
456
467
  return (largeLayout ? (80 + actionsWidth) : (70 + actionsWidth)) + (collapsedActions.length > 0 ? (largeLayout ? 40 : 30) : 0);
457
- }, [largeLayout]);
468
+ };
458
469
 
459
470
  const tableRowActionsBuilder = ({
460
471
  entity,
@@ -470,7 +481,10 @@ export const EntityCollectionView = React.memo(
470
481
 
471
482
  const isSelected = isEntitySelected(entity);
472
483
 
473
- const actions = getActionsForEntity({ entity, customEntityActions: collection.entityActions });
484
+ const actions = getActionsForEntity({
485
+ entity,
486
+ customEntityActions: collection.entityActions
487
+ });
474
488
 
475
489
  return (
476
490
  <EntityCollectionRowActions
@@ -577,12 +591,13 @@ export const EntityCollectionView = React.memo(
577
591
  });
578
592
 
579
593
  return (
580
- <div className={cn("overflow-hidden h-full w-full", className)}
594
+ <div className={cls("overflow-hidden h-full w-full rounded-md", className)}
581
595
  ref={containerRef}>
582
596
  <EntityCollectionTable
583
597
  key={`collection_table_${fullPath}`}
584
598
  additionalFields={additionalFields}
585
599
  tableController={tableController}
600
+ enablePopupIcon={true}
586
601
  displayedColumnIds={displayedColumnIds}
587
602
  onSizeChanged={onSizeChanged}
588
603
  onEntityClick={onEntityClick}
@@ -599,6 +614,14 @@ export const EntityCollectionView = React.memo(
599
614
  onTextSearchClick={textSearchInitialised ? undefined : onTextSearchClick}
600
615
  textSearchLoading={textSearchLoading}
601
616
  textSearchEnabled={textSearchEnabled}
617
+ actionsStart={<EntityCollectionViewStartActions
618
+ parentCollectionIds={parentCollectionIds ?? []}
619
+ collection={collection}
620
+ tableController={tableController}
621
+ path={fullPath}
622
+ relativePath={collection.path}
623
+ selectionController={usedSelectionController}
624
+ collectionEntitiesCount={docsCount}/>}
602
625
  actions={<EntityCollectionViewActions
603
626
  parentCollectionIds={parentCollectionIds ?? []}
604
627
  collection={collection}
@@ -676,39 +699,14 @@ export const EntityCollectionView = React.memo(
676
699
  equal(a.selectionController, b.selectionController) &&
677
700
  equal(a.Actions, b.Actions) &&
678
701
  equal(a.defaultSize, b.defaultSize) &&
702
+ equal(a.initialFilter, b.initialFilter) &&
703
+ equal(a.initialSort, b.initialSort) &&
679
704
  equal(a.textSearchEnabled, b.textSearchEnabled) &&
680
705
  equal(a.additionalFields, b.additionalFields) &&
706
+ equal(a.sideDialogWidth, b.sideDialogWidth) &&
681
707
  equal(a.forceFilter, b.forceFilter);
682
708
  }) as React.FunctionComponent<EntityCollectionViewProps<any>>
683
709
 
684
- export function useSelectionController<M extends Record<string, any> = any>(
685
- onSelectionChange?: (entity: Entity<M>, selected: boolean) => void
686
- ): SelectionController<M> {
687
-
688
- const [selectedEntities, setSelectedEntities] = useState<Entity<M>[]>([]);
689
-
690
- const toggleEntitySelection = useCallback((entity: Entity<M>) => {
691
- let newValue;
692
- if (selectedEntities.map(e => e.id).includes(entity.id)) {
693
- onSelectionChange?.(entity, false);
694
- newValue = selectedEntities.filter((item: Entity<M>) => item.id !== entity.id);
695
- } else {
696
- onSelectionChange?.(entity, true);
697
- newValue = [...selectedEntities, entity];
698
- }
699
- setSelectedEntities(newValue);
700
- }, [selectedEntities]);
701
-
702
- const isEntitySelected = useCallback((entity: Entity<M>) => selectedEntities.map(e => e.id).includes(entity.id), [selectedEntities]);
703
-
704
- return {
705
- selectedEntities,
706
- setSelectedEntities,
707
- isEntitySelected,
708
- toggleEntitySelection
709
- };
710
- }
711
-
712
710
  function EntitiesCount({
713
711
  fullPath,
714
712
  collection,
@@ -723,7 +721,7 @@ function EntitiesCount({
723
721
  onCountChange?: (count: number) => void,
724
722
  }) {
725
723
 
726
- const dataSource = useDataSource();
724
+ const dataSource = useDataSource(collection);
727
725
  const navigation = useNavigationController();
728
726
  const [count, setCount] = useState<number | undefined>(undefined);
729
727
  const [error, setError] = useState<Error | undefined>(undefined);
@@ -745,6 +743,7 @@ function EntitiesCount({
745
743
 
746
744
  useEffect(() => {
747
745
  if (onCountChange) {
746
+ setError(undefined);
748
747
  onCountChange(count ?? 0);
749
748
  }
750
749
  }, [onCountChange, count]);
@@ -796,10 +795,10 @@ function EntityIdHeaderWidget({
796
795
  if (!searchString) return;
797
796
  setOpenPopup(false);
798
797
  return sideEntityController.open({
799
- entityId: searchString,
798
+ entityId: searchString.trim(),
800
799
  path,
801
800
  collection,
802
- updateUrl: true
801
+ updateUrl: true,
803
802
  });
804
803
  }}
805
804
  className={"text-gray-900 dark:text-white w-96 max-w-full"}>
@@ -809,11 +808,13 @@ function EntityIdHeaderWidget({
809
808
  autoFocus={openPopup}
810
809
  placeholder={"Find entity by ID"}
811
810
  // size={"small"}
812
- onChange={(e) => setSearchString(e.target.value)}
811
+ onChange={(e) => {
812
+ setSearchString(e.target.value);
813
+ }}
813
814
  value={searchString}
814
815
  className={"flex-grow bg-transparent outline-none p-1"}/>
815
816
  <Button variant={"outlined"}
816
- disabled={!searchString}
817
+ disabled={!(searchString.trim())}
817
818
  type={"submit"}
818
819
  >Go</Button>
819
820
  </div>
@@ -44,7 +44,7 @@ export function EntityCollectionViewActions<M extends Record<string, any>>({
44
44
 
45
45
  const selectedEntities = selectionController.selectedEntities;
46
46
 
47
- const addButton = canCreateEntity(collection, authController, fullPathToCollectionSegments(path), null) &&
47
+ const addButton = canCreateEntity(collection, authController, path, null) &&
48
48
  onNewClick && (largeLayout
49
49
  ? <Button
50
50
  id={`add_entity_${path}`}
@@ -57,14 +57,13 @@ export function EntityCollectionViewActions<M extends Record<string, any>>({
57
57
  : <Button
58
58
  id={`add_entity_${path}`}
59
59
  onClick={onNewClick}
60
- size="medium"
61
60
  variant="filled"
62
61
  color="primary"
63
62
  >
64
63
  <AddIcon/>
65
64
  </Button>);
66
65
 
67
- const multipleDeleteEnabled = canDeleteEntity(collection, authController, fullPathToCollectionSegments(path), null);
66
+ const multipleDeleteEnabled = canDeleteEntity(collection, authController, path, null);
68
67
 
69
68
  let multipleDeleteButton: React.ReactNode | undefined;
70
69
  if (selectionEnabled) {
@@ -112,11 +111,11 @@ export function EntityCollectionViewActions<M extends Record<string, any>>({
112
111
 
113
112
  if (plugins) {
114
113
  plugins.forEach((plugin, i) => {
115
- if (plugin.collections?.CollectionActions) {
116
- actions.push(...toArray(plugin.collections?.CollectionActions)
114
+ if (plugin.collectionView?.CollectionActions) {
115
+ actions.push(...toArray(plugin.collectionView?.CollectionActions)
117
116
  .map((Action, j) => (
118
117
  <ErrorBoundary key={`plugin_actions_${i}_${j}`}>
119
- <Action {...actionProps} {...plugin.collections?.collectionActionsProps}/>
118
+ <Action {...actionProps} {...plugin.collectionView?.collectionActionsProps}/>
120
119
  </ErrorBoundary>
121
120
  )));
122
121
  }
@@ -0,0 +1,68 @@
1
+ import React from "react";
2
+ import { useCustomizationController, useFireCMSContext } from "../../hooks";
3
+ import { CollectionActionsProps, EntityCollection, EntityTableController, SelectionController } from "../../types";
4
+ import { toArray } from "../../util/arrays";
5
+ import { ErrorBoundary } from "../ErrorBoundary";
6
+ import { ClearFilterSortButton } from "../ClearFilterSortButton";
7
+
8
+ export type EntityCollectionViewStartActionsProps<M extends Record<string, any>> = {
9
+ collection: EntityCollection<M>;
10
+ path: string;
11
+ relativePath: string;
12
+ parentCollectionIds: string[];
13
+ selectionController: SelectionController<M>;
14
+ tableController: EntityTableController<M>;
15
+ collectionEntitiesCount: number;
16
+ }
17
+
18
+ export function EntityCollectionViewStartActions<M extends Record<string, any>>({
19
+ collection,
20
+ relativePath,
21
+ parentCollectionIds,
22
+ path,
23
+ selectionController,
24
+ tableController,
25
+ collectionEntitiesCount
26
+ }: EntityCollectionViewStartActionsProps<M>) {
27
+
28
+ const context = useFireCMSContext();
29
+
30
+ const customizationController = useCustomizationController();
31
+ const plugins = customizationController.plugins ?? [];
32
+
33
+ const actionProps: CollectionActionsProps = {
34
+ path,
35
+ relativePath,
36
+ parentCollectionIds,
37
+ collection,
38
+ selectionController,
39
+ context,
40
+ tableController,
41
+ collectionEntitiesCount
42
+ };
43
+ const actions: React.ReactNode[] = [
44
+ <ClearFilterSortButton
45
+ key={"clear_filter"}
46
+ tableController={tableController}
47
+ enabled={!collection.forceFilter}/>
48
+ ];
49
+
50
+ if (plugins) {
51
+ plugins.forEach((plugin, i) => {
52
+ if (plugin.collectionView?.CollectionActionsStart) {
53
+ actions.push(...toArray(plugin.collectionView?.CollectionActionsStart)
54
+ .map((Action, j) => (
55
+ <ErrorBoundary key={`plugin_actions_${i}_${j}`}>
56
+ <Action {...actionProps} {...plugin.collectionView?.collectionActionsStartProps}/>
57
+ </ErrorBoundary>
58
+ )));
59
+ }
60
+ });
61
+ }
62
+
63
+ return (
64
+ <>
65
+ {actions}
66
+ </>
67
+ );
68
+ }
@@ -0,0 +1,30 @@
1
+ import { useCallback, useState } from "react";
2
+ import { Entity, SelectionController } from "../../types";
3
+
4
+ export function useSelectionController<M extends Record<string, any> = any>(
5
+ onSelectionChange?: (entity: Entity<M>, selected: boolean) => void
6
+ ): SelectionController<M> {
7
+
8
+ const [selectedEntities, setSelectedEntities] = useState<Entity<M>[]>([]);
9
+
10
+ const toggleEntitySelection = useCallback((entity: Entity<M>) => {
11
+ let newValue;
12
+ if (selectedEntities.map(e => e.id).includes(entity.id)) {
13
+ onSelectionChange?.(entity, false);
14
+ newValue = selectedEntities.filter((item: Entity<M>) => item.id !== entity.id);
15
+ } else {
16
+ onSelectionChange?.(entity, true);
17
+ newValue = [...selectedEntities, entity];
18
+ }
19
+ setSelectedEntities(newValue);
20
+ }, [selectedEntities]);
21
+
22
+ const isEntitySelected = useCallback((entity: Entity<M>) => selectedEntities.map(e => e.id).includes(entity.id), [selectedEntities]);
23
+
24
+ return {
25
+ selectedEntities,
26
+ setSelectedEntities,
27
+ isEntitySelected,
28
+ toggleEntitySelection
29
+ };
30
+ }