@firecms/core 3.0.0-canary.14 → 3.0.0-canary.141

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 (301) hide show
  1. package/README.md +3 -3
  2. package/dist/app/AppBar.d.ts +12 -0
  3. package/dist/app/Drawer.d.ts +16 -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/ArrayContainer.d.ts +16 -5
  8. package/dist/components/CircularProgressCenter.d.ts +1 -1
  9. package/dist/components/ClearFilterSortButton.d.ts +5 -0
  10. package/dist/components/{DeleteConfirmationDialog.d.ts → ConfirmationDialog.d.ts} +1 -1
  11. package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +11 -12
  12. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +1 -1
  13. package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +5 -3
  14. package/dist/components/EntityCollectionTable/PropertyTableCell.d.ts +1 -0
  15. package/dist/components/EntityCollectionTable/column_utils.d.ts +1 -2
  16. package/dist/components/EntityCollectionTable/fields/TableReferenceField.d.ts +3 -1
  17. package/dist/components/EntityCollectionTable/internal/CollectionTableToolbar.d.ts +1 -4
  18. package/dist/components/EntityCollectionTable/internal/EntityTableCell.d.ts +2 -2
  19. package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +7 -4
  20. package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +12 -2
  21. package/dist/components/EntityCollectionView/EntityCollectionViewStartActions.d.ts +11 -0
  22. package/dist/components/EntityCollectionView/utils.d.ts +3 -0
  23. package/dist/components/EntityPreview.d.ts +7 -6
  24. package/dist/components/ErrorView.d.ts +1 -1
  25. package/dist/components/HomePage/DefaultHomePage.d.ts +1 -1
  26. package/dist/components/HomePage/NavigationCardBinding.d.ts +1 -1
  27. package/dist/components/PropertyConfigBadge.d.ts +2 -1
  28. package/dist/components/PropertyIdCopyTooltip.d.ts +8 -0
  29. package/dist/components/ReferenceWidget.d.ts +3 -1
  30. package/dist/components/SelectableTable/SelectableTable.d.ts +1 -1
  31. package/dist/components/SelectableTable/filters/ReferenceFilterField.d.ts +2 -1
  32. package/dist/components/VirtualTable/VirtualTableProps.d.ts +15 -12
  33. package/dist/components/VirtualTable/types.d.ts +3 -3
  34. package/dist/components/{EntityCollectionTable/internal → common}/default_entity_actions.d.ts +1 -1
  35. package/dist/components/common/index.d.ts +1 -0
  36. package/dist/components/common/table_height.d.ts +5 -0
  37. package/dist/components/common/types.d.ts +4 -6
  38. package/dist/components/common/useColumnsIds.d.ts +2 -1
  39. package/dist/components/common/useDataSourceEntityCollectionTableController.d.ts +3 -0
  40. package/dist/components/index.d.ts +4 -2
  41. package/dist/{components/FireCMSAppBar.d.ts → core/DefaultAppBar.d.ts} +6 -9
  42. package/dist/core/DefaultDrawer.d.ts +19 -0
  43. package/dist/core/DrawerNavigationItem.d.ts +10 -0
  44. package/dist/core/EntityEditView.d.ts +18 -4
  45. package/dist/core/FireCMS.d.ts +1 -1
  46. package/dist/core/NavigationRoutes.d.ts +3 -3
  47. package/dist/core/index.d.ts +3 -4
  48. package/dist/form/PropertyFieldBinding.d.ts +1 -1
  49. package/dist/form/components/ErrorFocus.d.ts +1 -1
  50. package/dist/form/components/FieldHelperText.d.ts +3 -3
  51. package/dist/form/components/LabelWithIcon.d.ts +1 -1
  52. package/dist/form/components/LabelWithIconAndTooltip.d.ts +15 -0
  53. package/dist/form/components/StorageItemPreview.d.ts +4 -4
  54. package/dist/form/components/index.d.ts +1 -1
  55. package/dist/form/field_bindings/ArrayCustomShapedFieldBinding.d.ts +1 -1
  56. package/dist/form/field_bindings/ArrayOfReferencesFieldBinding.d.ts +1 -1
  57. package/dist/form/field_bindings/BlockFieldBinding.d.ts +1 -1
  58. package/dist/form/field_bindings/KeyValueFieldBinding.d.ts +1 -1
  59. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  60. package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +11 -0
  61. package/dist/form/field_bindings/{MultiSelectBinding.d.ts → MultiSelectFieldBinding.d.ts} +1 -1
  62. package/dist/form/field_bindings/ReadOnlyFieldBinding.d.ts +1 -1
  63. package/dist/form/field_bindings/ReferenceFieldBinding.d.ts +2 -2
  64. package/dist/form/field_bindings/RepeatFieldBinding.d.ts +1 -1
  65. package/dist/form/field_bindings/SelectFieldBinding.d.ts +1 -1
  66. package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +3 -5
  67. package/dist/form/field_bindings/TextFieldBinding.d.ts +1 -1
  68. package/dist/form/index.d.ts +3 -5
  69. package/dist/form/useClearRestoreValue.d.ts +2 -2
  70. package/dist/hooks/data/save.d.ts +1 -2
  71. package/dist/hooks/index.d.ts +1 -0
  72. package/dist/hooks/useBuildNavigationController.d.ts +1 -2
  73. package/dist/hooks/useProjectLog.d.ts +8 -2
  74. package/dist/hooks/useValidateAuthenticator.d.ts +4 -8
  75. package/dist/index.d.ts +1 -0
  76. package/dist/index.es.js +16760 -13321
  77. package/dist/index.es.js.map +1 -1
  78. package/dist/index.umd.js +20120 -587
  79. package/dist/index.umd.js.map +1 -1
  80. package/dist/internal/useBuildDataSource.d.ts +1 -16
  81. package/dist/preview/PropertyPreviewProps.d.ts +6 -1
  82. package/dist/preview/components/EnumValuesChip.d.ts +1 -1
  83. package/dist/preview/components/ReferencePreview.d.ts +3 -2
  84. package/dist/preview/components/StorageThumbnail.d.ts +2 -1
  85. package/dist/preview/components/UrlComponentPreview.d.ts +2 -1
  86. package/dist/types/auth.d.ts +3 -3
  87. package/dist/types/collections.d.ts +41 -6
  88. package/dist/types/datasource.d.ts +55 -35
  89. package/dist/types/entities.d.ts +6 -1
  90. package/dist/types/entity_actions.d.ts +14 -0
  91. package/dist/types/entity_overrides.d.ts +2 -2
  92. package/dist/types/fields.d.ts +63 -41
  93. package/dist/types/firecms.d.ts +4 -0
  94. package/dist/types/index.d.ts +0 -1
  95. package/dist/types/navigation.d.ts +6 -5
  96. package/dist/types/plugins.d.ts +14 -4
  97. package/dist/types/properties.d.ts +34 -21
  98. package/dist/types/property_config.d.ts +0 -2
  99. package/dist/types/side_dialogs_controller.d.ts +10 -0
  100. package/dist/types/storage.d.ts +86 -3
  101. package/dist/util/entities.d.ts +2 -2
  102. package/dist/util/icon_list.d.ts +5 -1
  103. package/dist/util/icon_synonyms.d.ts +1 -97
  104. package/dist/util/icons.d.ts +3 -2
  105. package/dist/util/index.d.ts +1 -0
  106. package/dist/util/navigation_utils.d.ts +2 -2
  107. package/dist/util/objects.d.ts +2 -1
  108. package/dist/util/plurals.d.ts +0 -2
  109. package/dist/util/property_utils.d.ts +3 -3
  110. package/dist/util/resolutions.d.ts +30 -16
  111. package/dist/util/storage.d.ts +23 -2
  112. package/dist/util/useStorageUploadController.d.ts +3 -3
  113. package/package.json +128 -119
  114. package/src/app/AppBar.tsx +18 -0
  115. package/src/app/Drawer.tsx +24 -0
  116. package/src/app/Scaffold.tsx +243 -0
  117. package/src/app/index.ts +4 -0
  118. package/src/app/useApp.tsx +32 -0
  119. package/src/components/ArrayContainer.tsx +51 -24
  120. package/src/components/CircularProgressCenter.tsx +1 -1
  121. package/src/components/ClearFilterSortButton.tsx +41 -0
  122. package/src/components/{DeleteConfirmationDialog.tsx → ConfirmationDialog.tsx} +1 -1
  123. package/src/components/DeleteEntityDialog.tsx +1 -1
  124. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +12 -19
  125. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +21 -20
  126. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +10 -6
  127. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +47 -39
  128. package/src/components/EntityCollectionTable/column_utils.tsx +3 -3
  129. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +31 -16
  130. package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +14 -6
  131. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +29 -34
  132. package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +32 -30
  133. package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +19 -7
  134. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +72 -67
  135. package/src/components/EntityCollectionView/EntityCollectionView.tsx +138 -86
  136. package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +68 -0
  137. package/src/components/EntityCollectionView/useSelectionController.tsx +19 -7
  138. package/src/components/EntityCollectionView/utils.ts +19 -0
  139. package/src/components/EntityPreview.tsx +43 -39
  140. package/src/components/EntityView.tsx +6 -6
  141. package/src/components/ErrorView.tsx +1 -1
  142. package/src/components/HomePage/DefaultHomePage.tsx +25 -19
  143. package/src/components/HomePage/NavigationCard.tsx +3 -3
  144. package/src/components/HomePage/NavigationCardBinding.tsx +1 -1
  145. package/src/components/HomePage/NavigationGroup.tsx +1 -1
  146. package/src/components/HomePage/SmallNavigationCard.tsx +5 -6
  147. package/src/components/PropertyConfigBadge.tsx +9 -3
  148. package/src/components/PropertyIdCopyTooltip.tsx +48 -0
  149. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +8 -7
  150. package/src/components/ReferenceWidget.tsx +22 -12
  151. package/src/components/SearchIconsView.tsx +10 -7
  152. package/src/components/SelectableTable/SelectableTable.tsx +7 -7
  153. package/src/components/SelectableTable/filters/BooleanFilterField.tsx +2 -3
  154. package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +22 -7
  155. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +28 -6
  156. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +88 -21
  157. package/src/components/VirtualTable/VirtualTable.tsx +77 -46
  158. package/src/components/VirtualTable/VirtualTableCell.tsx +1 -9
  159. package/src/components/VirtualTable/VirtualTableHeader.tsx +4 -4
  160. package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +2 -2
  161. package/src/components/VirtualTable/VirtualTableProps.tsx +18 -14
  162. package/src/components/VirtualTable/VirtualTableRow.tsx +4 -5
  163. package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +4 -4
  164. package/src/components/VirtualTable/fields/VirtualTableInput.tsx +2 -1
  165. package/src/components/VirtualTable/fields/VirtualTableNumberInput.tsx +2 -1
  166. package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +14 -28
  167. package/src/components/VirtualTable/types.tsx +2 -3
  168. package/src/components/{EntityCollectionTable/internal → common}/default_entity_actions.tsx +8 -4
  169. package/src/components/common/index.ts +1 -0
  170. package/src/components/{VirtualTable/common.tsx → common/table_height.tsx} +5 -2
  171. package/src/components/common/types.tsx +4 -6
  172. package/src/components/common/useColumnsIds.tsx +23 -2
  173. package/src/components/common/useDataSourceEntityCollectionTableController.tsx +23 -12
  174. package/src/components/common/useTableSearchHelper.ts +53 -12
  175. package/src/components/index.tsx +4 -2
  176. package/src/contexts/DialogsProvider.tsx +2 -2
  177. package/src/core/DefaultAppBar.tsx +176 -0
  178. package/src/core/DefaultDrawer.tsx +183 -0
  179. package/src/core/DrawerNavigationItem.tsx +66 -0
  180. package/src/core/EntityEditView.tsx +716 -153
  181. package/src/core/EntitySidePanel.tsx +1 -2
  182. package/src/core/FireCMS.tsx +53 -52
  183. package/src/core/NavigationRoutes.tsx +7 -8
  184. package/src/core/SideDialogs.tsx +1 -0
  185. package/src/core/field_configs.tsx +7 -8
  186. package/src/core/index.tsx +3 -4
  187. package/src/form/PropertyFieldBinding.tsx +74 -35
  188. package/src/form/components/CustomIdField.tsx +4 -2
  189. package/src/form/components/FieldHelperText.tsx +4 -4
  190. package/src/form/components/LabelWithIcon.tsx +27 -19
  191. package/src/form/components/LabelWithIconAndTooltip.tsx +28 -0
  192. package/src/form/components/StorageItemPreview.tsx +21 -11
  193. package/src/form/components/StorageUploadProgress.tsx +3 -4
  194. package/src/form/components/index.tsx +1 -1
  195. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +29 -17
  196. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +45 -35
  197. package/src/form/field_bindings/BlockFieldBinding.tsx +51 -32
  198. package/src/form/field_bindings/DateTimeFieldBinding.tsx +17 -14
  199. package/src/form/field_bindings/KeyValueFieldBinding.tsx +54 -45
  200. package/src/form/field_bindings/MapFieldBinding.tsx +65 -48
  201. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +150 -0
  202. package/src/form/field_bindings/{MultiSelectBinding.tsx → MultiSelectFieldBinding.tsx} +25 -20
  203. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +11 -16
  204. package/src/form/field_bindings/ReferenceFieldBinding.tsx +42 -31
  205. package/src/form/field_bindings/RepeatFieldBinding.tsx +52 -34
  206. package/src/form/field_bindings/SelectFieldBinding.tsx +20 -13
  207. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +36 -46
  208. package/src/form/field_bindings/SwitchFieldBinding.tsx +9 -5
  209. package/src/form/field_bindings/TextFieldBinding.tsx +26 -23
  210. package/src/form/index.tsx +4 -9
  211. package/src/form/useClearRestoreValue.tsx +2 -2
  212. package/src/form/validation.ts +1 -17
  213. package/src/hooks/data/delete.ts +2 -1
  214. package/src/hooks/data/save.ts +9 -5
  215. package/src/hooks/data/useDataSource.tsx +11 -3
  216. package/src/hooks/index.tsx +1 -0
  217. package/src/hooks/useBuildLocalConfigurationPersistence.tsx +8 -10
  218. package/src/hooks/useBuildModeController.tsx +11 -5
  219. package/src/hooks/useBuildNavigationController.tsx +91 -31
  220. package/src/hooks/useProjectLog.tsx +32 -10
  221. package/src/hooks/useResolvedNavigationFrom.tsx +1 -1
  222. package/src/hooks/useValidateAuthenticator.tsx +21 -41
  223. package/src/index.ts +1 -0
  224. package/src/internal/useBuildDataSource.ts +72 -82
  225. package/src/internal/useBuildSideDialogsController.tsx +1 -0
  226. package/src/internal/useBuildSideEntityController.tsx +102 -22
  227. package/src/internal/useUnsavedChangesDialog.tsx +3 -1
  228. package/src/preview/PropertyPreview.tsx +11 -18
  229. package/src/preview/PropertyPreviewProps.tsx +7 -1
  230. package/src/preview/components/BooleanPreview.tsx +2 -2
  231. package/src/preview/components/EnumValuesChip.tsx +2 -2
  232. package/src/preview/components/ImagePreview.tsx +25 -35
  233. package/src/preview/components/ReferencePreview.tsx +23 -34
  234. package/src/preview/components/StorageThumbnail.tsx +5 -1
  235. package/src/preview/components/UrlComponentPreview.tsx +44 -11
  236. package/src/preview/property_previews/ArrayOfMapsPreview.tsx +2 -3
  237. package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +4 -3
  238. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +2 -3
  239. package/src/preview/property_previews/ArrayOfStringsPreview.tsx +1 -2
  240. package/src/preview/property_previews/ArrayOneOfPreview.tsx +4 -5
  241. package/src/preview/property_previews/ArrayPropertyPreview.tsx +4 -5
  242. package/src/preview/property_previews/MapPropertyPreview.tsx +6 -6
  243. package/src/preview/property_previews/SkeletonPropertyComponent.tsx +2 -2
  244. package/src/preview/property_previews/StringPropertyPreview.tsx +3 -3
  245. package/src/preview/util.ts +2 -2
  246. package/src/types/auth.tsx +3 -3
  247. package/src/types/collections.ts +50 -8
  248. package/src/types/customization_controller.tsx +0 -1
  249. package/src/types/datasource.ts +65 -43
  250. package/src/types/entities.ts +11 -1
  251. package/src/types/entity_actions.tsx +16 -3
  252. package/src/types/entity_overrides.tsx +2 -2
  253. package/src/types/fields.tsx +69 -45
  254. package/src/types/firecms.tsx +5 -0
  255. package/src/types/index.ts +0 -1
  256. package/src/types/navigation.ts +7 -7
  257. package/src/types/plugins.tsx +16 -6
  258. package/src/types/properties.ts +39 -22
  259. package/src/types/property_config.tsx +0 -2
  260. package/src/types/side_dialogs_controller.tsx +13 -0
  261. package/src/types/storage.ts +94 -3
  262. package/src/util/entities.ts +6 -5
  263. package/src/util/enums.ts +1 -1
  264. package/src/util/icon_list.ts +15 -10
  265. package/src/util/icon_synonyms.ts +3 -99
  266. package/src/util/icons.tsx +8 -2
  267. package/src/util/index.ts +1 -0
  268. package/src/util/make_properties_editable.ts +13 -5
  269. package/src/util/navigation_utils.ts +6 -6
  270. package/src/util/objects.ts +45 -28
  271. package/src/util/permissions.ts +1 -0
  272. package/src/util/plurals.ts +0 -2
  273. package/src/util/property_utils.tsx +11 -4
  274. package/src/util/references.ts +3 -0
  275. package/src/util/resolutions.ts +79 -46
  276. package/src/util/storage.ts +79 -21
  277. package/src/util/strings.ts +2 -2
  278. package/src/util/useStorageUploadController.tsx +33 -7
  279. package/src/util/useTraceUpdate.tsx +1 -0
  280. package/dist/components/PropertyIdCopyTooltipContent.d.ts +0 -3
  281. package/dist/components/VirtualTable/common.d.ts +0 -2
  282. package/dist/core/Drawer.d.ts +0 -23
  283. package/dist/core/Scaffold.d.ts +0 -55
  284. package/dist/core/SideEntityView.d.ts +0 -7
  285. package/dist/form/EntityForm.d.ts +0 -77
  286. package/dist/form/components/FormikArrayContainer.d.ts +0 -18
  287. package/dist/form/field_bindings/MarkdownFieldBinding.d.ts +0 -9
  288. package/dist/internal/useBuildCustomizationController.d.ts +0 -2
  289. package/dist/internal/useLocaleConfig.d.ts +0 -1
  290. package/dist/types/appcheck.d.ts +0 -26
  291. package/src/components/FireCMSAppBar.tsx +0 -165
  292. package/src/components/PropertyIdCopyTooltipContent.tsx +0 -28
  293. package/src/core/Drawer.tsx +0 -191
  294. package/src/core/Scaffold.tsx +0 -281
  295. package/src/core/SideEntityView.tsx +0 -38
  296. package/src/form/EntityForm.tsx +0 -728
  297. package/src/form/components/FormikArrayContainer.tsx +0 -44
  298. package/src/form/field_bindings/MarkdownFieldBinding.tsx +0 -695
  299. package/src/internal/useBuildCustomizationController.tsx +0 -5
  300. package/src/internal/useLocaleConfig.tsx +0 -18
  301. package/src/types/appcheck.ts +0 -29
@@ -1,6 +1,9 @@
1
- import { VirtualTableSize } from "./VirtualTableProps";
1
+ /**
2
+ * @group Components
3
+ */
4
+ export type TableSize = "xs" | "s" | "m" | "l" | "xl";
2
5
 
3
- export function getRowHeight(size: VirtualTableSize): number {
6
+ export function getRowHeight(size: TableSize): number {
4
7
  switch (size) {
5
8
  case "xl":
6
9
  return 400;
@@ -1,4 +1,4 @@
1
- import { CollectionSize, Entity, FireCMSContext, ResolvedProperty, SelectedCellProps } from "../../types";
1
+ import { CollectionSize, ResolvedProperty, SelectedCellProps } from "../../types";
2
2
 
3
3
  export type EntityCollectionTableController<M extends Record<string, any>> = {
4
4
 
@@ -31,14 +31,12 @@ export type EntityCollectionTableController<M extends Record<string, any>> = {
31
31
  * Props passed in a callback when the content of a cell in a table has been edited
32
32
  * @group Collection components
33
33
  */
34
- export interface OnCellValueChangeParams<T = any, M extends Record<string, any> = any> {
34
+ export interface OnCellValueChangeParams<T = any, D = any> {
35
35
  value: T,
36
36
  propertyKey: string,
37
- entity: Entity<M>,
37
+ data?: D,
38
38
  onValueUpdated: () => void
39
- setError: (e: Error) => void
40
- fullPath: string
41
- context: FireCMSContext
39
+ setError: (e: Error | undefined) => void
42
40
  }
43
41
 
44
42
  /**
@@ -7,8 +7,16 @@ const COLLECTION_GROUP_PARENT_ID = "collectionGroupParent";
7
7
 
8
8
  export function useColumnIds<M extends Record<string, any>>(collection: ResolvedEntityCollection<M>, includeSubcollections: boolean): PropertyColumnConfig[] {
9
9
  return useMemo(() => {
10
- if (collection.propertiesOrder)
11
- return hideAndExpandKeys(collection, collection.propertiesOrder);
10
+ if (collection.propertiesOrder) {
11
+ const propertyColumnConfigs = hideAndExpandKeys(collection, collection.propertiesOrder);
12
+ if (collection.collectionGroup) {
13
+ propertyColumnConfigs.push({
14
+ key: COLLECTION_GROUP_PARENT_ID,
15
+ disabled: true
16
+ });
17
+ }
18
+ return propertyColumnConfigs;
19
+ }
12
20
  return getDefaultColumnKeys(collection, includeSubcollections);
13
21
  }, [collection, includeSubcollections]);
14
22
  }
@@ -98,3 +106,16 @@ export function getColumnKeysForProperty(property: ResolvedProperty, key: string
98
106
  disabled: disabled || Boolean(property.disabled) || Boolean(property.readOnly)
99
107
  }];
100
108
  }
109
+
110
+ export function getFormFieldKeys(collection: EntityCollection): string[] {
111
+ const propertyKeys = Object.keys(collection.properties);
112
+ const additionalFields = collection.additionalFields ?? [];
113
+ const allKeys = [
114
+ ...propertyKeys,
115
+ ...additionalFields.map((field) => field.key)
116
+ ];
117
+ if (collection.propertiesOrder) {
118
+ return collection.propertiesOrder.filter(key => allKeys.includes(key));
119
+ }
120
+ return allKeys;
121
+ }
@@ -12,6 +12,7 @@ import {
12
12
  User
13
13
  } from "../../types";
14
14
  import { useDebouncedData } from "./useDebouncedData";
15
+ import equal from "react-fast-compare"
15
16
 
16
17
  const DEFAULT_PAGE_SIZE = 50;
17
18
 
@@ -31,6 +32,10 @@ export type DataSourceEntityCollectionTableControllerProps<M extends Record<stri
31
32
  entitiesDisplayedFirst?: Entity<M>[];
32
33
 
33
34
  lastDeleteTimestamp?: number;
35
+
36
+ /**
37
+ * Force filter to be applied to the table.
38
+ */
34
39
  forceFilter?: FilterValues<string>;
35
40
  }
36
41
 
@@ -75,6 +80,18 @@ export function useDataSourceEntityCollectionTableController<M extends Record<st
75
80
  const [searchString, setSearchString] = React.useState<string | undefined>();
76
81
  const [itemCount, setItemCount] = React.useState<number | undefined>(paginationEnabled ? pageSize : undefined);
77
82
 
83
+ const checkFilterCombination = useCallback((filterValues: FilterValues<any>,
84
+ sortBy?: [string, "asc" | "desc"]) => {
85
+ if (!dataSource.isFilterCombinationValid)
86
+ return true;
87
+ return dataSource.isFilterCombinationValid({
88
+ path: resolvedPath,
89
+ collection,
90
+ filterValues,
91
+ sortBy
92
+ })
93
+ }, []);
94
+
78
95
  const initialSortInternal = useMemo(() => {
79
96
  if (initialSort && forceFilter && !checkFilterCombination(forceFilter, initialSort)) {
80
97
  console.warn("Initial sort is not compatible with the force filter. Ignoring initial sort");
@@ -83,6 +100,12 @@ export function useDataSourceEntityCollectionTableController<M extends Record<st
83
100
  return initialSort;
84
101
  }, [initialSort, forceFilter]);
85
102
 
103
+ useEffect(() => {
104
+ if (!equal(forceFilter, filterValues)) {
105
+ setFilterValues(forceFilter)
106
+ }
107
+ }, [forceFilter]);
108
+
86
109
  const [filterValues, setFilterValues] = React.useState<FilterValues<Extract<keyof M, string>> | undefined>(forceFilter ?? initialFilter ?? undefined);
87
110
  const [sortBy, setSortBy] = React.useState<[Extract<keyof M, string>, "asc" | "desc"] | undefined>(initialSortInternal);
88
111
 
@@ -97,18 +120,6 @@ export function useDataSourceEntityCollectionTableController<M extends Record<st
97
120
  const [dataLoadingError, setDataLoadingError] = useState<Error | undefined>();
98
121
  const [noMoreToLoad, setNoMoreToLoad] = useState<boolean>(false);
99
122
 
100
- const checkFilterCombination = useCallback((filterValues: FilterValues<any>,
101
- sortBy?: [string, "asc" | "desc"]) => {
102
- if (!dataSource.isFilterCombinationValid)
103
- return true;
104
- return dataSource.isFilterCombinationValid({
105
- path: resolvedPath,
106
- collection,
107
- filterValues,
108
- sortBy
109
- })
110
- }, []);
111
-
112
123
  const clearFilter = useCallback(() => setFilterValues(forceFilter ?? undefined), [forceFilter]);
113
124
 
114
125
  const updateFilterValues = useCallback((updatedFilter: FilterValues<Extract<keyof M, string>> | undefined) => {
@@ -1,7 +1,7 @@
1
1
  import { useState } from "react";
2
2
 
3
3
  import { EntityCollection } from "../../types";
4
- import { useCustomizationController, useFireCMSContext } from "../../hooks";
4
+ import { useCustomizationController, useDataSource, useFireCMSContext } from "../../hooks";
5
5
 
6
6
  export interface UseTableSearchHelperParams<M extends Record<string, any>> {
7
7
  collection: EntityCollection<M>;
@@ -9,27 +9,58 @@ export interface UseTableSearchHelperParams<M extends Record<string, any>> {
9
9
  parentCollectionIds?: string[];
10
10
  }
11
11
 
12
- export function useTableSearchHelper<M extends Record<string, any>>({ collection, fullPath, parentCollectionIds }: UseTableSearchHelperParams<M>) {
12
+ export function useTableSearchHelper<M extends Record<string, any>>({
13
+ collection,
14
+ fullPath,
15
+ parentCollectionIds
16
+ }: UseTableSearchHelperParams<M>) {
13
17
 
14
18
  const context = useFireCMSContext();
15
19
  const customizationController = useCustomizationController();
20
+ const dataSource = useDataSource();
16
21
 
17
22
  const [textSearchLoading, setTextSearchLoading] = useState<boolean>(false);
18
23
  const [textSearchInitialised, setTextSearchInitialised] = useState<boolean>(false);
24
+
19
25
  let onTextSearchClick: (() => void) | undefined;
20
26
  let textSearchEnabled = Boolean(collection.textSearchEnabled);
21
- if (customizationController?.plugins) {
22
- const addTextSearchClickListener = customizationController.plugins?.find(p => Boolean(p.collectionView?.onTextSearchClick));
27
+
28
+ const props = {
29
+ context,
30
+ path: fullPath,
31
+ databaseId: collection.databaseId,
32
+ collection,
33
+ parentCollectionIds
34
+ };
35
+
36
+ const searchBlocked = customizationController.plugins?.find(p => {
37
+ return p.collectionView?.blockSearch?.(props);
38
+ });
39
+
40
+ const addTextSearchClickListener = Boolean(dataSource?.initTextSearch) || customizationController.plugins?.find(p => Boolean(p.collectionView?.onTextSearchClick));
41
+
42
+ if (addTextSearchClickListener) {
23
43
 
24
44
  onTextSearchClick = addTextSearchClickListener
25
45
  ? () => {
26
46
  setTextSearchLoading(true);
27
- Promise.all(customizationController.plugins?.map(p => {
28
- if (p.collectionView?.onTextSearchClick)
29
- return p.collectionView.onTextSearchClick({ context, path: fullPath, collection, parentCollectionIds });
30
- return Promise.resolve(true);
31
- }) as Promise<boolean>[])
32
- .then((res) => {
47
+ const promises: Promise<boolean>[] = [];
48
+ if (dataSource?.initTextSearch && !searchBlocked) {
49
+ promises.push(dataSource.initTextSearch(props));
50
+ }
51
+ if (searchBlocked) {
52
+ customizationController.plugins?.forEach(p => {
53
+ if (p.collectionView?.onTextSearchClick)
54
+ promises.push(p.collectionView.onTextSearchClick({
55
+ context,
56
+ path: fullPath,
57
+ collection,
58
+ parentCollectionIds
59
+ }));
60
+ })
61
+ }
62
+ return Promise.all(promises)
63
+ .then((res: boolean[]) => {
33
64
  if (res.every(Boolean)) setTextSearchInitialised(true);
34
65
  })
35
66
  .finally(() => setTextSearchLoading(false));
@@ -39,9 +70,19 @@ export function useTableSearchHelper<M extends Record<string, any>>({ collection
39
70
  customizationController.plugins?.forEach(p => {
40
71
  if (!textSearchEnabled)
41
72
  if (p.collectionView?.showTextSearchBar) {
42
- textSearchEnabled = p.collectionView.showTextSearchBar({ context, path: fullPath, collection, parentCollectionIds });
73
+ textSearchEnabled = p.collectionView.showTextSearchBar({
74
+ context,
75
+ path: fullPath,
76
+ collection,
77
+ parentCollectionIds
78
+ });
43
79
  }
44
80
  })
45
81
  }
46
- return { textSearchLoading, textSearchInitialised, onTextSearchClick, textSearchEnabled };
82
+ return {
83
+ textSearchLoading,
84
+ textSearchInitialised,
85
+ onTextSearchClick,
86
+ textSearchEnabled
87
+ };
47
88
  }
@@ -13,22 +13,24 @@ export * from "./common";
13
13
 
14
14
  export * from "./HomePage";
15
15
  export * from "./SelectableTable/SelectableTable";
16
+ export * from "./SelectableTable/SelectableTableContext";
16
17
  export * from "./EntityCollectionView/EntityCollectionView";
17
18
  export * from "./EntityCollectionView/EntityCollectionViewActions";
18
19
  export * from "./EntityCollectionView/useSelectionController";
19
20
 
20
21
  export * from "./PropertyConfigBadge";
22
+ export * from "./PropertyIdCopyTooltip";
21
23
 
22
24
  export * from "./EntityCollectionTable";
23
25
  export * from "./NotFoundPage";
24
26
 
25
27
  export * from "./VirtualTable";
26
28
  export * from "./ErrorBoundary";
27
- export * from "./DeleteConfirmationDialog";
29
+ export * from "./ConfirmationDialog";
28
30
 
29
31
  export * from "./FireCMSLogo";
30
32
 
31
- export * from "./FireCMSAppBar";
33
+ export * from "../core/DefaultAppBar";
32
34
 
33
35
  export * from "./ArrayContainer";
34
36
  export * from "./ReferenceWidget";
@@ -18,14 +18,14 @@ export const DialogsProvider: React.FC<PropsWithChildren<{}>> = ({ children }) =
18
18
  if (dialogEntries.length === 0)
19
19
  return;
20
20
 
21
- const updatedPanels = [...dialogEntries.slice(0, -1)];
21
+ const updatedPanels = [...dialogEntriesRef.current.slice(0, -1)];
22
22
  updateDialogEntries(updatedPanels);
23
23
 
24
24
  }, [dialogEntries]);
25
25
 
26
26
  const open = useCallback((dialogEntry: DialogControllerEntryProps) => {
27
27
 
28
- const updatedPanels = [...dialogEntries, dialogEntry];
28
+ const updatedPanels = [...dialogEntriesRef.current, dialogEntry];
29
29
  updateDialogEntries(updatedPanels);
30
30
 
31
31
  return {
@@ -0,0 +1,176 @@
1
+ import React from "react";
2
+
3
+ import { Link as ReactLink, useNavigate } from "react-router-dom";
4
+ import { ErrorBoundary, FireCMSLogo } from "../components";
5
+ import {
6
+ Avatar,
7
+ cls,
8
+ DarkModeIcon,
9
+ IconButton,
10
+ LightModeIcon,
11
+ LogoutIcon,
12
+ Menu,
13
+ MenuItem,
14
+ Skeleton,
15
+ Typography
16
+ } from "@firecms/ui";
17
+ import { useAuthController, useLargeLayout, useModeController, useNavigationController } from "../hooks";
18
+ import { User } from "../types";
19
+ import { useApp } from "../app/useApp";
20
+
21
+ export type DefaultAppBarProps<ADDITIONAL_PROPS = object> = {
22
+
23
+ title?: React.ReactNode;
24
+ /**
25
+ * A component that gets rendered on the upper side of the main toolbar
26
+ */
27
+ endAdornment?: React.ReactNode;
28
+
29
+ startAdornment?: React.ReactNode;
30
+
31
+ dropDownActions?: React.ReactNode;
32
+
33
+ includeModeToggle?: boolean;
34
+
35
+ className?: string;
36
+
37
+ style?: React.CSSProperties;
38
+
39
+ logo?: string;
40
+
41
+ user?: User;
42
+ } & ADDITIONAL_PROPS;
43
+
44
+ /**
45
+ * This component renders the main app bar of FireCMS.
46
+ * You will likely not need to use this component directly.
47
+ *
48
+
49
+ */
50
+ export const DefaultAppBar = function DefaultAppBar({
51
+ title,
52
+ endAdornment,
53
+ startAdornment,
54
+ dropDownActions,
55
+ includeModeToggle = true,
56
+ className,
57
+ style,
58
+ user: userProp
59
+ }: DefaultAppBarProps) {
60
+
61
+ const {
62
+ hasDrawer,
63
+ drawerOpen,
64
+ logo
65
+ } = useApp();
66
+ const navigation = useNavigationController();
67
+
68
+ const authController = useAuthController();
69
+ const {
70
+ mode,
71
+ toggleMode
72
+ } = useModeController();
73
+
74
+ const navigate = useNavigate();
75
+
76
+ const largeLayout = useLargeLayout();
77
+
78
+ const user = userProp ?? authController.user;
79
+
80
+ let avatarComponent: JSX.Element;
81
+ if (user && user.photoURL) {
82
+ avatarComponent = <Avatar
83
+ src={user.photoURL}/>;
84
+ } else if (user === undefined || authController.initialLoading) {
85
+ avatarComponent = <div className={"p-1 flex justify-center"}>
86
+ <Skeleton className={"w-10 h-10 rounded-full"}/>
87
+ </div>;
88
+ } else {
89
+ const initial = user?.displayName
90
+ ? user.displayName[0].toUpperCase()
91
+ : (user?.email ? user.email[0].toUpperCase() : "A");
92
+ avatarComponent = <Avatar>{initial}</Avatar>;
93
+ }
94
+
95
+ return (
96
+ <div
97
+ style={style}
98
+ className={cls("w-full h-16 transition-all ease-in duration-75 absolute top-0 max-w-full overflow-x-auto no-scrollbar",
99
+ "flex flex-row gap-2 px-4 items-center",
100
+ {
101
+ "pl-[19rem]": drawerOpen && largeLayout,
102
+ "pl-24": hasDrawer && !(drawerOpen && largeLayout),
103
+ "z-10": largeLayout,
104
+ "duration-100": drawerOpen && largeLayout,
105
+ },
106
+ className)}>
107
+
108
+
109
+ {navigation && <div className="mr-8 hidden lg:block">
110
+ <ReactLink
111
+ className="visited:text-inherit visited:dark:text-inherit"
112
+ to={navigation?.basePath ?? "/"}
113
+ >
114
+ <div className={"flex flex-row gap-4"}>
115
+ {!hasDrawer && (logo
116
+ ? <img src={logo}
117
+ alt="Logo"
118
+ className={cls("w-[32px] h-[32px] object-contain")}/>
119
+ : <FireCMSLogo width={"32px"} height={"32px"}/>)}
120
+
121
+ {typeof title === "string"
122
+ ? <Typography variant="subtitle1"
123
+ noWrap
124
+ className={cls("transition-all", drawerOpen ? "ml-2" : "")}>
125
+ {title}
126
+ </Typography>
127
+ : title}
128
+ </div>
129
+ </ReactLink>
130
+ </div>}
131
+
132
+ {startAdornment}
133
+
134
+ <div className={"flex-grow"}/>
135
+
136
+ {endAdornment &&
137
+ <ErrorBoundary>
138
+ {endAdornment}
139
+ </ErrorBoundary>}
140
+
141
+ {includeModeToggle && <IconButton
142
+ color="inherit"
143
+ aria-label="Open drawer"
144
+ onClick={toggleMode}
145
+ size="large">
146
+ {mode === "dark"
147
+ ? <DarkModeIcon/>
148
+ : <LightModeIcon/>}
149
+ </IconButton>}
150
+
151
+ <Menu trigger={avatarComponent}>
152
+ {user && <div className={"px-4 py-2 mb-2"}>
153
+ {user.displayName && <Typography variant={"body1"} color={"secondary"}>
154
+ {user.displayName}
155
+ </Typography>}
156
+ {user.email && <Typography variant={"body2"} color={"secondary"}>
157
+ {user.email}
158
+ </Typography>}
159
+ </div>}
160
+
161
+ {dropDownActions}
162
+
163
+ {!dropDownActions && <MenuItem onClick={async () => {
164
+ await authController.signOut();
165
+ // replace current route with home
166
+ navigate("/");
167
+ }}>
168
+ <LogoutIcon/>
169
+ Log Out
170
+ </MenuItem>}
171
+
172
+ </Menu>
173
+
174
+ </div>
175
+ );
176
+ }
@@ -0,0 +1,183 @@
1
+ import React, { useCallback } from "react";
2
+
3
+ import { useLargeLayout, useNavigationController } from "../hooks";
4
+
5
+ import { Link, useNavigate } from "react-router-dom";
6
+ import { CMSAnalyticsEvent, TopNavigationEntry, TopNavigationResult } from "../types";
7
+ import { IconForView } from "../util";
8
+ import { cls, IconButton, Menu, MenuItem, MoreVertIcon, Tooltip, Typography } from "@firecms/ui";
9
+ import { useAnalyticsController } from "../hooks/useAnalyticsController";
10
+ import { DrawerNavigationItem } from "./DrawerNavigationItem";
11
+ import { FireCMSLogo } from "../components";
12
+ import { useApp } from "../app/useApp";
13
+
14
+ /**
15
+ * Default drawer used in the CMS
16
+ * @group Core
17
+ */
18
+ export function DefaultDrawer({
19
+ className,
20
+ style,
21
+ }: {
22
+ className?: string
23
+ style?: React.CSSProperties,
24
+ }) {
25
+
26
+ const {
27
+ drawerHovered,
28
+ drawerOpen,
29
+ closeDrawer,
30
+ logo
31
+ } = useApp();
32
+
33
+ const [adminMenuOpen, setAdminMenuOpen] = React.useState(false);
34
+
35
+ const analyticsController = useAnalyticsController();
36
+ const navigation = useNavigationController();
37
+
38
+ const tooltipsOpen = drawerHovered && !drawerOpen && !adminMenuOpen;
39
+ const largeLayout = useLargeLayout();
40
+ const navigate = useNavigate();
41
+
42
+ if (!navigation.topLevelNavigation)
43
+ throw Error("Navigation not ready in Drawer");
44
+
45
+ const {
46
+ navigationEntries,
47
+ groups
48
+ }: TopNavigationResult = navigation.topLevelNavigation;
49
+
50
+ const adminViews = navigationEntries.filter(e => e.type === "admin") ?? [];
51
+ const groupsWithoutAdmin = groups.filter(g => g !== "Admin");
52
+
53
+ const buildGroupHeader = useCallback((group?: string) => {
54
+ if (!drawerOpen) return <div className="w-full"/>;
55
+ return <div
56
+ className="pl-6 pr-8 py-4 flex flex-row items-center">
57
+ <Typography variant={"caption"}
58
+ color={"secondary"}
59
+ className="font-medium flex-grow line-clamp-1">
60
+ {group ? group.toUpperCase() : "Views".toUpperCase()}
61
+ </Typography>
62
+
63
+ </div>;
64
+ }, [drawerOpen]);
65
+
66
+ const onClick = (view: TopNavigationEntry) => {
67
+ const eventName: CMSAnalyticsEvent = view.type === "collection"
68
+ ? "drawer_navigate_to_collection"
69
+ : (view.type === "view" ? "drawer_navigate_to_view" : "unmapped_event");
70
+ analyticsController.onAnalyticsEvent?.(eventName, { url: view.url });
71
+ if (!largeLayout)
72
+ closeDrawer();
73
+ };
74
+
75
+ return (
76
+ <>
77
+ <div className={cls("flex flex-col h-full relative flex-grow w-full", className)} style={style}>
78
+
79
+ <DrawerLogo logo={logo}/>
80
+
81
+ <div className={"mt-4 flex-grow overflow-scroll no-scrollbar"}
82
+ style={{
83
+ maskImage: "linear-gradient(to bottom, transparent 0, black 20px, black calc(100% - 20px), transparent 100%)",
84
+ }}>
85
+
86
+ {groupsWithoutAdmin.map((group) => (
87
+ <div
88
+ className={"bg-gray-50 dark:bg-gray-800 dark:bg-opacity-30 my-4 rounded-lg ml-4"}
89
+ key={`drawer_group_${group}`}>
90
+ {buildGroupHeader(group)}
91
+ {Object.values(navigationEntries)
92
+ .filter(e => e.group === group)
93
+ .map((view, index) =>
94
+ <DrawerNavigationItem
95
+ key={`navigation_${index}`}
96
+ icon={<IconForView collectionOrView={view.collection ?? view.view} size={"small"}/>}
97
+ tooltipsOpen={tooltipsOpen}
98
+ adminMenuOpen={adminMenuOpen}
99
+ drawerOpen={drawerOpen}
100
+ onClick={() => onClick(view)}
101
+ url={view.url}
102
+ name={view.name}/>)}
103
+ </div>
104
+ ))}
105
+
106
+ </div>
107
+
108
+ {adminViews.length > 0 && <Menu
109
+ side={"right"}
110
+ open={adminMenuOpen}
111
+ onOpenChange={setAdminMenuOpen}
112
+ trigger={
113
+ <IconButton
114
+ shape={"square"}
115
+ className={"m-4 text-gray-900 dark:text-white w-fit"}>
116
+ <Tooltip title={"Admin"}
117
+ open={tooltipsOpen}
118
+ side={"right"} sideOffset={28}>
119
+ <MoreVertIcon/>
120
+ </Tooltip>
121
+ {drawerOpen && <div
122
+ className={cls(
123
+ drawerOpen ? "opacity-100" : "opacity-0 hidden",
124
+ "mx-4 font-inherit text-inherit"
125
+ )}>
126
+ ADMIN
127
+ </div>}
128
+ </IconButton>}
129
+ >
130
+ {adminViews.map((entry, index) =>
131
+ <MenuItem
132
+ onClick={(event) => {
133
+ event.preventDefault();
134
+ navigate(entry.path);
135
+ }}
136
+ key={`navigation_${index}`}>
137
+ {<IconForView collectionOrView={entry.view}/>}
138
+ {entry.name}
139
+ </MenuItem>)}
140
+
141
+ </Menu>}
142
+ </div>
143
+
144
+ </>
145
+ );
146
+ }
147
+
148
+ /**
149
+ * This is the logo displayed in the drawer
150
+ * It expands when the drawer is open.
151
+ *
152
+ * @param logo
153
+
154
+ */
155
+ export function DrawerLogo({ logo }: {
156
+ logo?: string;
157
+ }) {
158
+
159
+ const navigation = useNavigationController();
160
+ const { drawerOpen } = useApp();
161
+ return <div
162
+ style={{
163
+ transition: "padding 100ms cubic-bezier(0.4, 0, 0.6, 1) 0ms",
164
+ padding: drawerOpen ? "32px 144px 0px 24px" : "72px 12px 0px 12px"
165
+ }}
166
+ className={cls("cursor-pointer ml-4")}>
167
+
168
+ <Tooltip title={"Home"}
169
+ sideOffset={20}
170
+ side="right">
171
+ <Link
172
+ to={navigation.basePath}>
173
+ {logo
174
+ ? <img src={logo}
175
+ alt="Logo"
176
+ className={cls("max-w-full max-h-full",
177
+ drawerOpen ?? "w-[112px] h-[112px]")}/>
178
+ : <FireCMSLogo/>}
179
+
180
+ </Link>
181
+ </Tooltip>
182
+ </div>;
183
+ }