@firecms/collection_editor 3.0.0-3.0.0-beta.4.pre.1.0

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 (140) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -0
  3. package/dist/ConfigControllerProvider.d.ts +37 -0
  4. package/dist/index.d.ts +11 -0
  5. package/dist/index.es.js +5454 -0
  6. package/dist/index.es.js.map +1 -0
  7. package/dist/index.umd.js +4 -0
  8. package/dist/index.umd.js.map +1 -0
  9. package/dist/types/collection_editor_controller.d.ts +36 -0
  10. package/dist/types/collection_inference.d.ts +2 -0
  11. package/dist/types/config_controller.d.ts +51 -0
  12. package/dist/types/config_permissions.d.ts +19 -0
  13. package/dist/types/persisted_collection.d.ts +6 -0
  14. package/dist/ui/CollectionViewHeaderAction.d.ts +10 -0
  15. package/dist/ui/EditorCollectionAction.d.ts +2 -0
  16. package/dist/ui/HomePageEditorCollectionAction.d.ts +2 -0
  17. package/dist/ui/MissingReferenceWidget.d.ts +3 -0
  18. package/dist/ui/NewCollectionButton.d.ts +1 -0
  19. package/dist/ui/NewCollectionCard.d.ts +2 -0
  20. package/dist/ui/PropertyAddColumnComponent.d.ts +6 -0
  21. package/dist/ui/RootCollectionSuggestions.d.ts +3 -0
  22. package/dist/ui/collection_editor/CollectionDetailsForm.d.ts +10 -0
  23. package/dist/ui/collection_editor/CollectionEditorDialog.d.ts +36 -0
  24. package/dist/ui/collection_editor/CollectionEditorWelcomeView.d.ts +15 -0
  25. package/dist/ui/collection_editor/CollectionPropertiesEditorForm.d.ts +19 -0
  26. package/dist/ui/collection_editor/CollectionYupValidation.d.ts +14 -0
  27. package/dist/ui/collection_editor/EntityCustomViewsSelectDialog.d.ts +4 -0
  28. package/dist/ui/collection_editor/EnumForm.d.ts +12 -0
  29. package/dist/ui/collection_editor/GetCodeDialog.d.ts +5 -0
  30. package/dist/ui/collection_editor/PropertyEditView.d.ts +40 -0
  31. package/dist/ui/collection_editor/PropertyFieldPreview.d.ts +15 -0
  32. package/dist/ui/collection_editor/PropertySelectItem.d.ts +8 -0
  33. package/dist/ui/collection_editor/PropertyTree.d.ts +33 -0
  34. package/dist/ui/collection_editor/SubcollectionsEditTab.d.ts +12 -0
  35. package/dist/ui/collection_editor/SwitchControl.d.ts +8 -0
  36. package/dist/ui/collection_editor/UnsavedChangesDialog.d.ts +9 -0
  37. package/dist/ui/collection_editor/import/CollectionEditorImportDataPreview.d.ts +7 -0
  38. package/dist/ui/collection_editor/import/CollectionEditorImportMapping.d.ts +7 -0
  39. package/dist/ui/collection_editor/import/clean_import_data.d.ts +7 -0
  40. package/dist/ui/collection_editor/properties/BlockPropertyField.d.ts +8 -0
  41. package/dist/ui/collection_editor/properties/BooleanPropertyField.d.ts +3 -0
  42. package/dist/ui/collection_editor/properties/CommonPropertyFields.d.ts +10 -0
  43. package/dist/ui/collection_editor/properties/DateTimePropertyField.d.ts +3 -0
  44. package/dist/ui/collection_editor/properties/EnumPropertyField.d.ts +8 -0
  45. package/dist/ui/collection_editor/properties/KeyValuePropertyField.d.ts +3 -0
  46. package/dist/ui/collection_editor/properties/MapPropertyField.d.ts +8 -0
  47. package/dist/ui/collection_editor/properties/NumberPropertyField.d.ts +3 -0
  48. package/dist/ui/collection_editor/properties/ReferencePropertyField.d.ts +13 -0
  49. package/dist/ui/collection_editor/properties/RepeatPropertyField.d.ts +10 -0
  50. package/dist/ui/collection_editor/properties/StoragePropertyField.d.ts +5 -0
  51. package/dist/ui/collection_editor/properties/StringPropertyField.d.ts +5 -0
  52. package/dist/ui/collection_editor/properties/UrlPropertyField.d.ts +4 -0
  53. package/dist/ui/collection_editor/properties/advanced/AdvancedPropertyValidation.d.ts +3 -0
  54. package/dist/ui/collection_editor/properties/validation/ArrayPropertyValidation.d.ts +5 -0
  55. package/dist/ui/collection_editor/properties/validation/GeneralPropertyValidation.d.ts +4 -0
  56. package/dist/ui/collection_editor/properties/validation/NumberPropertyValidation.d.ts +3 -0
  57. package/dist/ui/collection_editor/properties/validation/StringPropertyValidation.d.ts +11 -0
  58. package/dist/ui/collection_editor/properties/validation/ValidationPanel.d.ts +2 -0
  59. package/dist/ui/collection_editor/templates/blog_template.d.ts +2 -0
  60. package/dist/ui/collection_editor/templates/pages_template.d.ts +2 -0
  61. package/dist/ui/collection_editor/templates/products_template.d.ts +2 -0
  62. package/dist/ui/collection_editor/templates/users_template.d.ts +2 -0
  63. package/dist/ui/collection_editor/util.d.ts +5 -0
  64. package/dist/ui/collection_editor/utils/strings.d.ts +1 -0
  65. package/dist/ui/collection_editor/utils/supported_fields.d.ts +3 -0
  66. package/dist/ui/collection_editor/utils/update_property_for_widget.d.ts +2 -0
  67. package/dist/ui/collection_editor/utils/useTraceUpdate.d.ts +1 -0
  68. package/dist/useCollectionEditorController.d.ts +6 -0
  69. package/dist/useCollectionEditorPlugin.d.ts +49 -0
  70. package/dist/useCollectionsConfigController.d.ts +6 -0
  71. package/dist/utils/arrays.d.ts +1 -0
  72. package/dist/utils/entities.d.ts +3 -0
  73. package/package.json +85 -0
  74. package/src/ConfigControllerProvider.tsx +338 -0
  75. package/src/index.ts +35 -0
  76. package/src/types/collection_editor_controller.tsx +43 -0
  77. package/src/types/collection_inference.ts +3 -0
  78. package/src/types/config_controller.tsx +60 -0
  79. package/src/types/config_permissions.ts +20 -0
  80. package/src/types/persisted_collection.ts +9 -0
  81. package/src/ui/CollectionViewHeaderAction.tsx +43 -0
  82. package/src/ui/EditorCollectionAction.tsx +109 -0
  83. package/src/ui/HomePageEditorCollectionAction.tsx +84 -0
  84. package/src/ui/MissingReferenceWidget.tsx +37 -0
  85. package/src/ui/NewCollectionButton.tsx +16 -0
  86. package/src/ui/NewCollectionCard.tsx +48 -0
  87. package/src/ui/PropertyAddColumnComponent.tsx +42 -0
  88. package/src/ui/RootCollectionSuggestions.tsx +63 -0
  89. package/src/ui/collection_editor/CollectionDetailsForm.tsx +365 -0
  90. package/src/ui/collection_editor/CollectionEditorDialog.tsx +801 -0
  91. package/src/ui/collection_editor/CollectionEditorWelcomeView.tsx +213 -0
  92. package/src/ui/collection_editor/CollectionPropertiesEditorForm.tsx +506 -0
  93. package/src/ui/collection_editor/CollectionYupValidation.tsx +7 -0
  94. package/src/ui/collection_editor/EntityCustomViewsSelectDialog.tsx +37 -0
  95. package/src/ui/collection_editor/EnumForm.tsx +357 -0
  96. package/src/ui/collection_editor/GetCodeDialog.tsx +110 -0
  97. package/src/ui/collection_editor/PropertyEditView.tsx +615 -0
  98. package/src/ui/collection_editor/PropertyFieldPreview.tsx +207 -0
  99. package/src/ui/collection_editor/PropertySelectItem.tsx +32 -0
  100. package/src/ui/collection_editor/PropertyTree.tsx +252 -0
  101. package/src/ui/collection_editor/SubcollectionsEditTab.tsx +262 -0
  102. package/src/ui/collection_editor/SwitchControl.tsx +39 -0
  103. package/src/ui/collection_editor/UnsavedChangesDialog.tsx +47 -0
  104. package/src/ui/collection_editor/import/CollectionEditorImportDataPreview.tsx +37 -0
  105. package/src/ui/collection_editor/import/CollectionEditorImportMapping.tsx +268 -0
  106. package/src/ui/collection_editor/import/clean_import_data.ts +53 -0
  107. package/src/ui/collection_editor/properties/BlockPropertyField.tsx +138 -0
  108. package/src/ui/collection_editor/properties/BooleanPropertyField.tsx +40 -0
  109. package/src/ui/collection_editor/properties/CommonPropertyFields.tsx +110 -0
  110. package/src/ui/collection_editor/properties/DateTimePropertyField.tsx +86 -0
  111. package/src/ui/collection_editor/properties/EnumPropertyField.tsx +114 -0
  112. package/src/ui/collection_editor/properties/KeyValuePropertyField.tsx +20 -0
  113. package/src/ui/collection_editor/properties/MapPropertyField.tsx +150 -0
  114. package/src/ui/collection_editor/properties/NumberPropertyField.tsx +38 -0
  115. package/src/ui/collection_editor/properties/ReferencePropertyField.tsx +160 -0
  116. package/src/ui/collection_editor/properties/RepeatPropertyField.tsx +109 -0
  117. package/src/ui/collection_editor/properties/StoragePropertyField.tsx +200 -0
  118. package/src/ui/collection_editor/properties/StringPropertyField.tsx +79 -0
  119. package/src/ui/collection_editor/properties/UrlPropertyField.tsx +89 -0
  120. package/src/ui/collection_editor/properties/advanced/AdvancedPropertyValidation.tsx +45 -0
  121. package/src/ui/collection_editor/properties/validation/ArrayPropertyValidation.tsx +50 -0
  122. package/src/ui/collection_editor/properties/validation/GeneralPropertyValidation.tsx +61 -0
  123. package/src/ui/collection_editor/properties/validation/NumberPropertyValidation.tsx +115 -0
  124. package/src/ui/collection_editor/properties/validation/StringPropertyValidation.tsx +150 -0
  125. package/src/ui/collection_editor/properties/validation/ValidationPanel.tsx +28 -0
  126. package/src/ui/collection_editor/templates/blog_template.ts +115 -0
  127. package/src/ui/collection_editor/templates/pages_template.ts +188 -0
  128. package/src/ui/collection_editor/templates/products_template.ts +88 -0
  129. package/src/ui/collection_editor/templates/users_template.ts +42 -0
  130. package/src/ui/collection_editor/util.ts +28 -0
  131. package/src/ui/collection_editor/utils/strings.ts +9 -0
  132. package/src/ui/collection_editor/utils/supported_fields.tsx +29 -0
  133. package/src/ui/collection_editor/utils/update_property_for_widget.ts +271 -0
  134. package/src/ui/collection_editor/utils/useTraceUpdate.tsx +23 -0
  135. package/src/useCollectionEditorController.tsx +9 -0
  136. package/src/useCollectionEditorPlugin.tsx +154 -0
  137. package/src/useCollectionsConfigController.tsx +9 -0
  138. package/src/utils/arrays.ts +3 -0
  139. package/src/utils/entities.ts +38 -0
  140. package/src/vite-env.d.ts +1 -0
@@ -0,0 +1,271 @@
1
+ import {
2
+ ArrayProperty,
3
+ BooleanProperty,
4
+ DateProperty,
5
+ MapProperty,
6
+ mergeDeep,
7
+ NumberProperty,
8
+ Property,
9
+ PropertyConfig,
10
+ StringProperty
11
+ } from "@firecms/core";
12
+
13
+ export function updatePropertyFromWidget(propertyData: any,
14
+ selectedWidgetId: string | undefined,
15
+ propertyConfigs: Record<string, PropertyConfig>): Property {
16
+
17
+ let updatedProperty;
18
+ if (selectedWidgetId === "text_field") {
19
+ updatedProperty = mergeDeep(
20
+ propertyData,
21
+ {
22
+ dataType: "string",
23
+ propertyConfig: "text_field",
24
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
25
+ storage: undefined,
26
+ multiline: undefined,
27
+ markdown: undefined,
28
+ email: undefined,
29
+ url: undefined,
30
+ enumValues: undefined
31
+ } satisfies StringProperty
32
+ );
33
+ } else if (selectedWidgetId === "multiline") {
34
+ updatedProperty = mergeDeep(
35
+ propertyData,
36
+ {
37
+ dataType: "string",
38
+ propertyConfig: "multiline",
39
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
40
+ multiline: true,
41
+ storage: undefined,
42
+ markdown: undefined,
43
+ email: undefined,
44
+ url: undefined,
45
+ enumValues: undefined
46
+ } satisfies StringProperty
47
+ );
48
+ } else if (selectedWidgetId === "markdown") {
49
+ updatedProperty = mergeDeep(
50
+ propertyData,
51
+ {
52
+ dataType: "string",
53
+ propertyConfig: "markdown",
54
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
55
+ storage: undefined,
56
+ multiline: undefined,
57
+ markdown: true,
58
+ email: undefined,
59
+ url: undefined
60
+ } satisfies StringProperty
61
+ );
62
+ } else if (selectedWidgetId === "url") {
63
+ updatedProperty = mergeDeep(
64
+ propertyData,
65
+ {
66
+ dataType: "string",
67
+ propertyConfig: "url",
68
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
69
+ storage: undefined,
70
+ multiline: undefined,
71
+ markdown: undefined,
72
+ email: undefined,
73
+ url: true,
74
+ enumValues: undefined
75
+ } satisfies StringProperty
76
+ );
77
+ } else if (selectedWidgetId === "email") {
78
+ updatedProperty = mergeDeep(
79
+ propertyData,
80
+ {
81
+ dataType: "string",
82
+ propertyConfig: "email",
83
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
84
+ storage: undefined,
85
+ multiline: undefined,
86
+ markdown: undefined,
87
+ email: true,
88
+ url: undefined,
89
+ enumValues: undefined
90
+ } satisfies StringProperty
91
+ );
92
+ } else if (selectedWidgetId === "select") {
93
+ updatedProperty = mergeDeep(
94
+ propertyData,
95
+ {
96
+ dataType: "string",
97
+ propertyConfig: "select",
98
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
99
+ storage: undefined,
100
+ multiline: undefined,
101
+ markdown: undefined,
102
+ email: undefined,
103
+ url: undefined,
104
+ enumValues: propertyData.enumValues ?? []
105
+ } satisfies StringProperty
106
+ );
107
+ } else if (selectedWidgetId === "multi_select") {
108
+ updatedProperty = mergeDeep(
109
+ propertyData,
110
+ {
111
+ dataType: "array",
112
+ propertyConfig: "multi_select",
113
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
114
+ of: {
115
+ dataType: "string",
116
+ enumValues: propertyData.of?.enumValues ?? []
117
+ }
118
+ } satisfies ArrayProperty
119
+ );
120
+ } else if (selectedWidgetId === "number_input") {
121
+ updatedProperty = mergeDeep(
122
+ propertyData,
123
+ {
124
+ dataType: "number",
125
+ propertyConfig: "number_input",
126
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
127
+ enumValues: undefined
128
+ } satisfies NumberProperty
129
+ );
130
+ } else if (selectedWidgetId === "number_select") {
131
+ updatedProperty = mergeDeep(
132
+ propertyData,
133
+ {
134
+ dataType: "number",
135
+ propertyConfig: "number_select",
136
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
137
+ enumValues: propertyData.enumValues ?? []
138
+ } satisfies NumberProperty
139
+ );
140
+ } else if (selectedWidgetId === "multi_number_select") {
141
+ updatedProperty = mergeDeep(
142
+ propertyData,
143
+ {
144
+ dataType: "array",
145
+ propertyConfig: "multi_number_select",
146
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
147
+ of: {
148
+ dataType: "number",
149
+ enumValues: propertyData.of?.enumValues ?? []
150
+ }
151
+ } satisfies ArrayProperty
152
+ );
153
+ } else if (selectedWidgetId === "file_upload") {
154
+ updatedProperty = mergeDeep(
155
+ propertyData,
156
+ {
157
+ dataType: "string",
158
+ propertyConfig: "file_upload",
159
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
160
+ storage: {
161
+ storagePath: "/"
162
+ }
163
+ } satisfies StringProperty
164
+ );
165
+ } else if (selectedWidgetId === "multi_file_upload") {
166
+ updatedProperty = mergeDeep(
167
+ propertyData,
168
+ {
169
+ dataType: "array",
170
+ propertyConfig: "multi_file_upload",
171
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
172
+ of: {
173
+ dataType: "string",
174
+ storage: propertyData.of?.storage ?? {
175
+ storagePath: "/"
176
+ }
177
+ }
178
+ } satisfies ArrayProperty
179
+ );
180
+ } else if (selectedWidgetId === "group") {
181
+ updatedProperty = mergeDeep(
182
+ propertyData,
183
+ {
184
+ dataType: "map",
185
+ propertyConfig: "group",
186
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
187
+ keyValue: false,
188
+ properties: propertyData.properties ?? {}
189
+ } satisfies MapProperty
190
+ );
191
+ } else if (selectedWidgetId === "key_value") {
192
+ updatedProperty = mergeDeep(
193
+ propertyData,
194
+ {
195
+ dataType: "map",
196
+ propertyConfig: "key_value",
197
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
198
+ keyValue: true,
199
+ properties: undefined
200
+ } satisfies MapProperty
201
+ );
202
+ } else if (selectedWidgetId === "reference") {
203
+ updatedProperty = mergeDeep(
204
+ propertyData,
205
+ {
206
+ dataType: "reference",
207
+ propertyConfig: "reference",
208
+ editable: propertyData.editable !== undefined ? propertyData.editable : true
209
+ } satisfies Property
210
+ );
211
+ } else if (selectedWidgetId === "multi_references") {
212
+ updatedProperty = mergeDeep(
213
+ propertyData,
214
+ {
215
+ dataType: "array",
216
+ propertyConfig: "multi_references",
217
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
218
+ of: {
219
+ dataType: "reference"
220
+ }
221
+ } satisfies ArrayProperty
222
+ );
223
+ } else if (selectedWidgetId === "switch") {
224
+ updatedProperty = mergeDeep(
225
+ propertyData,
226
+ {
227
+ dataType: "boolean",
228
+ propertyConfig: "switch",
229
+ editable: propertyData.editable !== undefined ? propertyData.editable : true
230
+ } satisfies BooleanProperty
231
+ );
232
+ } else if (selectedWidgetId === "date_time") {
233
+ updatedProperty = mergeDeep(
234
+ propertyData,
235
+ {
236
+ dataType: "date",
237
+ propertyConfig: "date_time",
238
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
239
+ mode: "date_time"
240
+ } satisfies DateProperty
241
+ );
242
+ } else if (selectedWidgetId === "repeat") {
243
+ updatedProperty = mergeDeep(
244
+ propertyData,
245
+ {
246
+ dataType: "array",
247
+ propertyConfig: "repeat",
248
+ editable: propertyData.editable !== undefined ? propertyData.editable : true
249
+ } satisfies ArrayProperty
250
+ );
251
+ } else if (selectedWidgetId === "block") {
252
+ updatedProperty = mergeDeep(
253
+ propertyData,
254
+ {
255
+ dataType: "array",
256
+ propertyConfig: "block",
257
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
258
+ oneOf: {
259
+ properties: {}
260
+ }
261
+ } satisfies ArrayProperty
262
+ );
263
+ } else if (selectedWidgetId && propertyConfigs[selectedWidgetId]) {
264
+ updatedProperty = {
265
+ ...propertyConfigs[selectedWidgetId].property,
266
+ propertyConfig: selectedWidgetId
267
+ };
268
+ }
269
+
270
+ return updatedProperty;
271
+ }
@@ -0,0 +1,23 @@
1
+ import { useEffect, useRef } from "react";
2
+
3
+ function printChanged(props: any, prev: any, path = "", depth = 0) {
4
+ if (depth > 10) {
5
+ return;
6
+ }
7
+ if (props && prev && typeof props === "object" && typeof prev === "object") {
8
+ Object.keys(props).forEach((key) => {
9
+ printChanged(props[key], prev[key], path + "." + key, depth + 1);
10
+ });
11
+ } else if (props !== prev) {
12
+ console.log("Changed props:", path);
13
+ }
14
+
15
+ }
16
+
17
+ export function useTraceUpdate(props: any) {
18
+ const prev = useRef(props);
19
+ useEffect(() => {
20
+ printChanged(props, prev.current, "");
21
+ prev.current = props;
22
+ });
23
+ }
@@ -0,0 +1,9 @@
1
+ import { useContext } from "react";
2
+ import { CollectionEditorController } from "./types/collection_editor_controller";
3
+ import { CollectionEditorContext } from "./ConfigControllerProvider";
4
+
5
+ /**
6
+ * Hook to access the collection editor controller.
7
+ * The methods in this controller can be used to open the collection editor dialog.
8
+ */
9
+ export const useCollectionEditorController = (): CollectionEditorController => useContext(CollectionEditorContext);
@@ -0,0 +1,154 @@
1
+ import React from "react";
2
+ import { FireCMSPlugin, useAuthController, useNavigationController, User } from "@firecms/core";
3
+ import { ConfigControllerProvider } from "./ConfigControllerProvider";
4
+ import { CollectionEditorPermissionsBuilder } from "./types/config_permissions";
5
+ import { EditorCollectionAction } from "./ui/EditorCollectionAction";
6
+ import { HomePageEditorCollectionAction } from "./ui/HomePageEditorCollectionAction";
7
+ import { NewCollectionCard } from "./ui/NewCollectionCard";
8
+ import { PersistedCollection } from "./types/persisted_collection";
9
+ import { CollectionInference } from "./types/collection_inference";
10
+ import { CollectionsConfigController } from "./types/config_controller";
11
+ import { RootCollectionSuggestions } from "./ui/RootCollectionSuggestions";
12
+ import { CollectionViewHeaderAction } from "./ui/CollectionViewHeaderAction";
13
+ import { PropertyAddColumnComponent } from "./ui/PropertyAddColumnComponent";
14
+ import { NewCollectionButton } from "./ui/NewCollectionButton";
15
+ import { AddIcon, Button, Typography } from "@firecms/ui";
16
+ import { useCollectionEditorController } from "./useCollectionEditorController";
17
+
18
+ export interface CollectionConfigControllerProps<EC extends PersistedCollection = PersistedCollection, UserType extends User = User> {
19
+
20
+ /**
21
+ * Firebase app where the configuration is saved.
22
+ */
23
+ collectionConfigController: CollectionsConfigController;
24
+
25
+ /**
26
+ * Define what actions can be performed on the configuration.
27
+ */
28
+ configPermissions?: CollectionEditorPermissionsBuilder<UserType, EC>;
29
+
30
+ /**
31
+ * The words you define here will not be allowed to be used as group
32
+ * names when creating collections.
33
+ * e.g. ["admin"]
34
+ */
35
+ reservedGroups: string[];
36
+
37
+ extraView?: {
38
+ View: React.ComponentType<{
39
+ path: string
40
+ }>,
41
+ icon: React.ReactNode
42
+ };
43
+
44
+ pathSuggestions?: (path: string) => Promise<string[]>;
45
+
46
+ collectionInference?: CollectionInference;
47
+
48
+ getData?: (path: string, parentPaths: string[]) => Promise<object[]>;
49
+
50
+ getUser: (uid: string) => UserType | null;
51
+
52
+ onAnalyticsEvent?: (event: string, params?: object) => void;
53
+
54
+ introMode?: "new_project" | "existing_project";
55
+
56
+ }
57
+
58
+ /**
59
+ * Use this hook to initialise the Collection Editor plugin.
60
+ * This is likely the only hook you will need to use.
61
+ * @param firebaseApp Firebase app where your project data lives.
62
+ * @param configPermissions
63
+ * @param reservedGroups
64
+ * @param extraView
65
+ * @param pathSuggestions
66
+ * @param getUser
67
+ * @param collectionInference
68
+ */
69
+ export function useCollectionEditorPlugin<EC extends PersistedCollection = PersistedCollection, UserType extends User = User>
70
+ ({
71
+ collectionConfigController,
72
+ introMode,
73
+ configPermissions,
74
+ reservedGroups,
75
+ extraView,
76
+ pathSuggestions,
77
+ getUser,
78
+ collectionInference,
79
+ getData,
80
+ onAnalyticsEvent
81
+ }: CollectionConfigControllerProps<EC, UserType>): FireCMSPlugin<any, any, PersistedCollection> {
82
+
83
+ return {
84
+ name: "Collection Editor",
85
+ loading: collectionConfigController.loading,
86
+ provider: {
87
+ Component: ConfigControllerProvider,
88
+ props: {
89
+ collectionConfigController,
90
+ configPermissions,
91
+ collectionInference,
92
+ reservedGroups,
93
+ extraView,
94
+ pathSuggestions,
95
+ getUser,
96
+ getData,
97
+ onAnalyticsEvent
98
+ }
99
+ },
100
+ homePage: {
101
+ additionalActions: <NewCollectionButton/>,
102
+ additionalChildrenStart: introMode ? <IntroWidget introMode={introMode}/> : undefined,
103
+ additionalChildrenEnd: <RootCollectionSuggestions introMode={introMode}/>,
104
+ CollectionActions: HomePageEditorCollectionAction,
105
+ AdditionalCards: introMode ? undefined : NewCollectionCard,
106
+ },
107
+ collectionView: {
108
+ CollectionActions: EditorCollectionAction,
109
+ HeaderAction: CollectionViewHeaderAction,
110
+ AddColumnComponent: PropertyAddColumnComponent
111
+ }
112
+ };
113
+ }
114
+
115
+ export function IntroWidget({ introMode }: {
116
+ introMode?: "new_project" | "existing_project";
117
+ }) {
118
+
119
+ const navigation = useNavigationController();
120
+ if (!navigation.topLevelNavigation)
121
+ throw Error("Navigation not ready in FireCMSHomePage");
122
+
123
+ const authController = useAuthController();
124
+
125
+ const collectionEditorController = useCollectionEditorController();
126
+ const canCreateCollections = collectionEditorController.configPermissions
127
+ ? collectionEditorController.configPermissions({
128
+ user: authController.user,
129
+ }).createCollections
130
+ : true;
131
+
132
+ return (
133
+ <div className={"mt-8 flex flex-col mt-8 p-2"}>
134
+ <Typography variant={"h4"} className="mb-4">Welcome</Typography>
135
+ <Typography paragraph={true}>Your admin panel is ready ✌️</Typography>
136
+ <Typography paragraph={true}>
137
+ Start building collections in FireCMS easily. Map them to your existing
138
+ database data, import from files, or use our templates. Simplify your data management process
139
+ now.
140
+ </Typography>
141
+ {canCreateCollections && <Button
142
+ className={"mt-4"}
143
+ onClick={collectionEditorController && canCreateCollections
144
+ ? () => collectionEditorController.createCollection({
145
+ parentCollectionIds: [],
146
+ redirect: true,
147
+ sourceClick: "new_collection_card"
148
+ })
149
+ : undefined}>
150
+ <AddIcon/>Create your first collection
151
+ </Button>}
152
+ </div>
153
+ );
154
+ }
@@ -0,0 +1,9 @@
1
+ import { useContext } from "react";
2
+ import { CollectionsConfigController } from "./types/config_controller";
3
+ import { ConfigControllerContext } from "./ConfigControllerProvider";
4
+
5
+ /**
6
+ * Use this hook to access the configuration controller.
7
+ * You can use it to get the list of collections, and to save/delete collections.
8
+ */
9
+ export const useCollectionsConfigController = (): CollectionsConfigController => useContext(ConfigControllerContext);
@@ -0,0 +1,3 @@
1
+ export function toArray<T>(input?: T | T[]):T[] {
2
+ return Array.isArray(input) ? input : (input ? [input] : []);
3
+ }
@@ -0,0 +1,38 @@
1
+ import { isPropertyBuilder, Properties, PropertiesOrBuilders, Property, PropertyOrBuilder } from "@firecms/core";
2
+
3
+ export function editableProperty(property: PropertyOrBuilder | PropertyOrBuilder): boolean {
4
+ if (isPropertyBuilder(property))
5
+ return false;
6
+ if (isPropertyBuilder(property as PropertyOrBuilder))
7
+ return false;
8
+ else {
9
+ const eProperty = property as Property;
10
+ if (eProperty.dataType === "array" && typeof eProperty.of === "function")
11
+ return false;
12
+ else if (eProperty.dataType === "array" && Array.isArray(eProperty.of))
13
+ return false;
14
+ return Boolean(eProperty.editable);
15
+ }
16
+ }
17
+
18
+ export function removeNonEditableProperties(properties: PropertiesOrBuilders<any>): Properties {
19
+ return Object.entries(properties)
20
+ .filter(([_, property]) => editableProperty(property))
21
+ .map(([key, propertyOrBuilder]) => {
22
+ const property = propertyOrBuilder as Property;
23
+ if (!editableProperty(property)) {
24
+ return undefined;
25
+ } else if (property.dataType === "map" && property.properties) {
26
+ return {
27
+ [key]: {
28
+ ...property,
29
+ properties: removeNonEditableProperties(property.properties as PropertiesOrBuilders)
30
+ }
31
+ };
32
+ } else {
33
+ return { [key]: property };
34
+ }
35
+ })
36
+ .filter((e) => Boolean(e))
37
+ .reduce((a, b) => ({ ...a, ...b }), {}) as Properties;
38
+ }
@@ -0,0 +1 @@
1
+ /// <reference types="vite/client" />