@firecms/collection_editor 3.0.0-alpha.16 → 3.0.0-alpha.18

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 (90) hide show
  1. package/dist/ConfigControllerProvider.d.ts +1 -1
  2. package/dist/components/RootCollectionSuggestions.d.ts +1 -0
  3. package/dist/components/collection_editor/CollectionEditorDialog.d.ts +7 -3
  4. package/dist/components/collection_editor/CollectionPropertiesEditorForm.d.ts +5 -3
  5. package/dist/components/collection_editor/EntityCustomViewsSelectDialog.d.ts +4 -0
  6. package/dist/components/collection_editor/PropertyEditView.d.ts +5 -4
  7. package/dist/components/collection_editor/PropertyFieldPreview.d.ts +4 -3
  8. package/dist/components/collection_editor/PropertySelectItem.d.ts +2 -2
  9. package/dist/components/collection_editor/PropertyTree.d.ts +6 -5
  10. package/dist/components/collection_editor/import/CollectionEditorImportMapping.d.ts +3 -1
  11. package/dist/components/collection_editor/properties/BlockPropertyField.d.ts +3 -1
  12. package/dist/components/collection_editor/properties/MapPropertyField.d.ts +3 -1
  13. package/dist/components/collection_editor/properties/RepeatPropertyField.d.ts +3 -1
  14. package/dist/components/collection_editor/utils/update_property_for_widget.d.ts +2 -3
  15. package/dist/index.d.ts +0 -1
  16. package/dist/index.es.js +2221 -1889
  17. package/dist/index.es.js.map +1 -1
  18. package/dist/index.umd.js +1 -1
  19. package/dist/index.umd.js.map +1 -1
  20. package/dist/types/collection_editor_controller.d.ts +6 -1
  21. package/dist/types/config_controller.d.ts +2 -2
  22. package/dist/types/persisted_collection.d.ts +3 -2
  23. package/dist/utils/entities.d.ts +3 -4
  24. package/dist/utils/icons.d.ts +1 -2
  25. package/dist/utils/join_collections.d.ts +14 -0
  26. package/package.json +10 -5
  27. package/src/ConfigControllerProvider.tsx +177 -0
  28. package/src/components/EditorCollectionAction.tsx +95 -0
  29. package/src/components/HomePageEditorCollectionAction.tsx +81 -0
  30. package/src/components/NewCollectionCard.tsx +45 -0
  31. package/src/components/RootCollectionSuggestions.tsx +53 -0
  32. package/src/components/collection_editor/CollectionDetailsForm.tsx +312 -0
  33. package/src/components/collection_editor/CollectionEditorDialog.tsx +640 -0
  34. package/src/components/collection_editor/CollectionEditorWelcomeView.tsx +212 -0
  35. package/src/components/collection_editor/CollectionPropertiesEditorForm.tsx +450 -0
  36. package/src/components/collection_editor/CollectionYupValidation.tsx +6 -0
  37. package/src/components/collection_editor/EntityCustomViewsSelectDialog.tsx +29 -0
  38. package/src/components/collection_editor/EnumForm.tsx +354 -0
  39. package/src/components/collection_editor/PropertyEditView.tsx +535 -0
  40. package/src/components/collection_editor/PropertyFieldPreview.tsx +205 -0
  41. package/src/components/collection_editor/PropertySelectItem.tsx +31 -0
  42. package/src/components/collection_editor/PropertyTree.tsx +228 -0
  43. package/src/components/collection_editor/SelectIcons.tsx +72 -0
  44. package/src/components/collection_editor/SubcollectionsEditTab.tsx +239 -0
  45. package/src/components/collection_editor/UnsavedChangesDialog.tsx +47 -0
  46. package/src/components/collection_editor/import/CollectionEditorImportDataPreview.tsx +37 -0
  47. package/src/components/collection_editor/import/CollectionEditorImportMapping.tsx +236 -0
  48. package/src/components/collection_editor/import/clean_import_data.ts +53 -0
  49. package/src/components/collection_editor/properties/BlockPropertyField.tsx +131 -0
  50. package/src/components/collection_editor/properties/BooleanPropertyField.tsx +36 -0
  51. package/src/components/collection_editor/properties/CommonPropertyFields.tsx +112 -0
  52. package/src/components/collection_editor/properties/DateTimePropertyField.tsx +86 -0
  53. package/src/components/collection_editor/properties/EnumPropertyField.tsx +116 -0
  54. package/src/components/collection_editor/properties/FieldHelperView.tsx +13 -0
  55. package/src/components/collection_editor/properties/KeyValuePropertyField.tsx +20 -0
  56. package/src/components/collection_editor/properties/MapPropertyField.tsx +154 -0
  57. package/src/components/collection_editor/properties/NumberPropertyField.tsx +38 -0
  58. package/src/components/collection_editor/properties/ReferencePropertyField.tsx +184 -0
  59. package/src/components/collection_editor/properties/RepeatPropertyField.tsx +115 -0
  60. package/src/components/collection_editor/properties/StoragePropertyField.tsx +194 -0
  61. package/src/components/collection_editor/properties/StringPropertyField.tsx +85 -0
  62. package/src/components/collection_editor/properties/advanced/AdvancedPropertyValidation.tsx +36 -0
  63. package/src/components/collection_editor/properties/validation/ArrayPropertyValidation.tsx +50 -0
  64. package/src/components/collection_editor/properties/validation/GeneralPropertyValidation.tsx +49 -0
  65. package/src/components/collection_editor/properties/validation/NumberPropertyValidation.tsx +99 -0
  66. package/src/components/collection_editor/properties/validation/StringPropertyValidation.tsx +131 -0
  67. package/src/components/collection_editor/properties/validation/ValidationPanel.tsx +28 -0
  68. package/src/components/collection_editor/templates/blog_template.ts +115 -0
  69. package/src/components/collection_editor/templates/products_template.ts +89 -0
  70. package/src/components/collection_editor/templates/users_template.ts +34 -0
  71. package/src/components/collection_editor/util.ts +21 -0
  72. package/src/components/collection_editor/utils/supported_fields.tsx +28 -0
  73. package/src/components/collection_editor/utils/update_property_for_widget.ts +258 -0
  74. package/src/components/collection_editor/utils/useTraceUpdate.tsx +23 -0
  75. package/src/index.ts +31 -0
  76. package/src/types/collection_editor_controller.tsx +31 -0
  77. package/src/types/collection_inference.ts +3 -0
  78. package/src/types/config_controller.tsx +30 -0
  79. package/src/types/config_permissions.ts +20 -0
  80. package/src/types/persisted_collection.ts +7 -0
  81. package/src/useCollectionEditorController.tsx +9 -0
  82. package/src/useCollectionEditorPlugin.tsx +103 -0
  83. package/src/useCollectionsConfigController.tsx +9 -0
  84. package/src/utils/arrays.ts +3 -0
  85. package/src/utils/entities.ts +38 -0
  86. package/src/utils/icons.ts +17 -0
  87. package/src/utils/join_collections.ts +144 -0
  88. package/src/utils/synonyms.ts +1952 -0
  89. package/src/vite-env.d.ts +1 -0
  90. package/dist/types/editable_properties.d.ts +0 -10
@@ -0,0 +1,258 @@
1
+ import { buildProperty, FieldConfig, mergeDeep, Property } from "@firecms/core";
2
+
3
+ export function updatePropertyFromWidget(propertyData: any,
4
+ selectedWidgetId: string | undefined,
5
+ customFields: Record<string, FieldConfig>): Property {
6
+
7
+ let updatedProperty;
8
+ if (selectedWidgetId === "text_field") {
9
+ updatedProperty = mergeDeep(
10
+ propertyData,
11
+ buildProperty({
12
+ dataType: "string",
13
+ fieldConfig: "text_field",
14
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
15
+ storage: undefined,
16
+ multiline: undefined,
17
+ markdown: undefined,
18
+ email: undefined,
19
+ url: undefined,
20
+ enumValues: undefined
21
+ })
22
+ );
23
+ } else if (selectedWidgetId === "multiline") {
24
+ updatedProperty = mergeDeep(
25
+ propertyData,
26
+ buildProperty({
27
+ dataType: "string",
28
+ fieldConfig: "multiline",
29
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
30
+ multiline: true,
31
+ storage: undefined,
32
+ markdown: undefined,
33
+ email: undefined,
34
+ url: undefined,
35
+ enumValues: undefined
36
+ })
37
+ );
38
+ } else if (selectedWidgetId === "markdown") {
39
+ updatedProperty = mergeDeep(
40
+ propertyData,
41
+ buildProperty({
42
+ dataType: "string",
43
+ fieldConfig: "markdown",
44
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
45
+ storage: undefined,
46
+ multiline: undefined,
47
+ markdown: true,
48
+ email: undefined,
49
+ url: undefined
50
+ })
51
+ );
52
+ } else if (selectedWidgetId === "url") {
53
+ updatedProperty = mergeDeep(
54
+ propertyData,
55
+ buildProperty({
56
+ dataType: "string",
57
+ fieldConfig: "url",
58
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
59
+ storage: undefined,
60
+ multiline: undefined,
61
+ markdown: undefined,
62
+ email: undefined,
63
+ url: true,
64
+ enumValues: undefined
65
+ })
66
+ );
67
+ } else if (selectedWidgetId === "email") {
68
+ updatedProperty = mergeDeep(
69
+ propertyData,
70
+ buildProperty({
71
+ dataType: "string",
72
+ fieldConfig: "email",
73
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
74
+ storage: undefined,
75
+ multiline: undefined,
76
+ markdown: undefined,
77
+ email: true,
78
+ url: undefined,
79
+ enumValues: undefined
80
+ })
81
+ );
82
+ } else if (selectedWidgetId === "select") {
83
+ updatedProperty = mergeDeep(
84
+ propertyData,
85
+ buildProperty({
86
+ dataType: "string",
87
+ fieldConfig: "select",
88
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
89
+ storage: undefined,
90
+ multiline: undefined,
91
+ markdown: undefined,
92
+ email: undefined,
93
+ url: undefined,
94
+ enumValues: propertyData.enumValues ?? []
95
+ })
96
+ );
97
+ } else if (selectedWidgetId === "multi_select") {
98
+ updatedProperty = mergeDeep(
99
+ propertyData,
100
+ buildProperty({
101
+ dataType: "array",
102
+ fieldConfig: "multi_select",
103
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
104
+ of: {
105
+ dataType: "string",
106
+ enumValues: propertyData.of?.enumValues ?? []
107
+ }
108
+ })
109
+ );
110
+ } else if (selectedWidgetId === "number_input") {
111
+ updatedProperty = mergeDeep(
112
+ propertyData,
113
+ buildProperty({
114
+ dataType: "number",
115
+ fieldConfig: "number_input",
116
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
117
+ enumValues: undefined
118
+ })
119
+ );
120
+ } else if (selectedWidgetId === "number_select") {
121
+ updatedProperty = mergeDeep(
122
+ propertyData,
123
+ buildProperty({
124
+ dataType: "number",
125
+ fieldConfig: "number_select",
126
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
127
+ enumValues: propertyData.enumValues ?? []
128
+ })
129
+ );
130
+ } else if (selectedWidgetId === "multi_number_select") {
131
+ updatedProperty = mergeDeep(
132
+ propertyData,
133
+ buildProperty({
134
+ dataType: "array",
135
+ fieldConfig: "multi_number_select",
136
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
137
+ of: {
138
+ dataType: "number",
139
+ enumValues: propertyData.of?.enumValues ?? []
140
+ }
141
+ })
142
+ );
143
+ } else if (selectedWidgetId === "file_upload") {
144
+ updatedProperty = mergeDeep(
145
+ propertyData,
146
+ buildProperty({
147
+ dataType: "string",
148
+ fieldConfig: "file_upload",
149
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
150
+ storage: {
151
+ storagePath: "/"
152
+ }
153
+ })
154
+ );
155
+ } else if (selectedWidgetId === "multi_file_upload") {
156
+ updatedProperty = mergeDeep(
157
+ propertyData,
158
+ buildProperty({
159
+ dataType: "array",
160
+ fieldConfig: "multi_file_upload",
161
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
162
+ of: {
163
+ dataType: "string",
164
+ storage: propertyData.of?.storage ?? {
165
+ storagePath: "/"
166
+ }
167
+ }
168
+ })
169
+ );
170
+ } else if (selectedWidgetId === "group") {
171
+ updatedProperty = mergeDeep(
172
+ propertyData,
173
+ buildProperty({
174
+ dataType: "map",
175
+ fieldConfig: "group",
176
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
177
+ keyValue: false,
178
+ properties: propertyData.properties ?? {}
179
+ })
180
+ );
181
+ } else if (selectedWidgetId === "key_value") {
182
+ updatedProperty = mergeDeep(
183
+ propertyData,
184
+ buildProperty({
185
+ dataType: "map",
186
+ fieldConfig: "key_value",
187
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
188
+ keyValue: true,
189
+ properties: undefined
190
+ })
191
+ );
192
+ } else if (selectedWidgetId === "reference") {
193
+ updatedProperty = mergeDeep(
194
+ propertyData,
195
+ buildProperty({
196
+ dataType: "reference",
197
+ fieldConfig: "reference",
198
+ editable: propertyData.editable !== undefined ? propertyData.editable : true
199
+ })
200
+ );
201
+ } else if (selectedWidgetId === "multi_references") {
202
+ updatedProperty = mergeDeep(
203
+ propertyData,
204
+ buildProperty({
205
+ dataType: "array",
206
+ fieldConfig: "multi_references",
207
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
208
+ of: {
209
+ dataType: "reference"
210
+ }
211
+ })
212
+ );
213
+ } else if (selectedWidgetId === "switch") {
214
+ updatedProperty = mergeDeep(
215
+ propertyData,
216
+ buildProperty({
217
+ dataType: "boolean",
218
+ fieldConfig: "switch",
219
+ editable: propertyData.editable !== undefined ? propertyData.editable : true
220
+ })
221
+ );
222
+ } else if (selectedWidgetId === "date_time") {
223
+ updatedProperty = mergeDeep(
224
+ propertyData,
225
+ buildProperty({
226
+ dataType: "date",
227
+ fieldConfig: "date_time",
228
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
229
+ mode: "date_time"
230
+ })
231
+ );
232
+ } else if (selectedWidgetId === "repeat") {
233
+ updatedProperty = mergeDeep(
234
+ propertyData,
235
+ buildProperty({
236
+ dataType: "array",
237
+ fieldConfig: "repeat",
238
+ editable: propertyData.editable !== undefined ? propertyData.editable : true
239
+ })
240
+ );
241
+ } else if (selectedWidgetId === "block") {
242
+ updatedProperty = mergeDeep(
243
+ propertyData,
244
+ buildProperty({
245
+ dataType: "array",
246
+ fieldConfig: "block",
247
+ editable: propertyData.editable !== undefined ? propertyData.editable : true,
248
+ oneOf: {
249
+ properties: {}
250
+ }
251
+ })
252
+ );
253
+ } else if (selectedWidgetId && customFields[selectedWidgetId]) {
254
+ updatedProperty = { ...customFields[selectedWidgetId].property, fieldConfig: selectedWidgetId };
255
+ }
256
+
257
+ return updatedProperty;
258
+ }
@@ -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
+ }
package/src/index.ts ADDED
@@ -0,0 +1,31 @@
1
+ export {
2
+ useCollectionEditorPlugin
3
+ } from "./useCollectionEditorPlugin";
4
+
5
+ export {
6
+ useCollectionEditorController
7
+ } from "./useCollectionEditorController";
8
+ export {
9
+ useCollectionsConfigController
10
+ } from "./useCollectionsConfigController";
11
+
12
+ export {
13
+ editableProperty, removeNonEditableProperties
14
+ } from "./utils/entities";
15
+
16
+ export type {
17
+ CollectionsConfigController, DeleteCollectionParams, SaveCollectionParams
18
+ } from "./types/config_controller";
19
+ export type {
20
+ CollectionEditorController
21
+ } from "./types/collection_editor_controller";
22
+ export type {
23
+ CollectionEditorPermissions, CollectionEditorPermissionsBuilder
24
+ } from "./types/config_permissions";
25
+ export type {
26
+ PersistedCollection
27
+ } from "./types/persisted_collection";
28
+
29
+ export type {
30
+ CollectionInference
31
+ } from "./types/collection_inference";
@@ -0,0 +1,31 @@
1
+ import { CollectionEditorPermissionsBuilder } from "./config_permissions";
2
+ import { EntityCollection } from "@firecms/core";
3
+
4
+ /**
5
+ * Controller to open the collection editor dialog.
6
+ * @category Hooks and utilities
7
+ */
8
+ export interface CollectionEditorController {
9
+
10
+ editCollection: (props: {
11
+ path?: string,
12
+ fullPath?: string,
13
+ parentPathSegments: string[],
14
+ parentCollection?: EntityCollection<any, any, any>
15
+ }) => void;
16
+
17
+ createCollection: (props: {
18
+ initialValues?: {
19
+ group?: string,
20
+ path?: string,
21
+ name?: string
22
+ },
23
+ parentPathSegments: string[],
24
+ parentCollection?: EntityCollection<any, any, any>
25
+ }) => void;
26
+
27
+ configPermissions: CollectionEditorPermissionsBuilder;
28
+
29
+ rootPathSuggestions?: string[];
30
+
31
+ }
@@ -0,0 +1,3 @@
1
+ import { EntityCollection } from "@firecms/core";
2
+
3
+ export type CollectionInference = (path: string, collectionGroup: boolean, parentPathSegments: string[]) => Promise<EntityCollection | null>;
@@ -0,0 +1,30 @@
1
+ import { CMSType, EntityCollection } from "@firecms/core";
2
+ import { PersistedCollection } from "./persisted_collection";
3
+
4
+ /**
5
+ * Use this controller to access the configuration that is stored externally,
6
+ * and not defined in code.
7
+ */
8
+ export interface CollectionsConfigController {
9
+
10
+ loading: boolean;
11
+
12
+ collections?: PersistedCollection[];
13
+
14
+ saveCollection: <M extends { [Key: string]: CMSType }>(params:SaveCollectionParams<M>) => Promise<void>;
15
+
16
+ deleteCollection: (props: DeleteCollectionParams) => Promise<void>;
17
+
18
+ }
19
+
20
+ export type SaveCollectionParams<M extends Record<string, any>> = {
21
+ path: string,
22
+ collectionData: PersistedCollection<M>,
23
+ previousPath?: string,
24
+ parentPathSegments?: string[]
25
+ }
26
+
27
+ export type DeleteCollectionParams = {
28
+ path: string,
29
+ parentPathSegments?: string[]
30
+ }
@@ -0,0 +1,20 @@
1
+ import { EntityCollection } from "@firecms/core";
2
+
3
+ export type CollectionEditorPermissionsBuilder<UserType = any, EC extends EntityCollection = EntityCollection> = (params: { user: UserType | null, collection?: EC }) => CollectionEditorPermissions;
4
+
5
+ export type CollectionEditorPermissions = {
6
+ /**
7
+ * Is the user allowed to create new collections.
8
+ */
9
+ createCollections: boolean;
10
+
11
+ /**
12
+ * Is the user allowed to modify this collection
13
+ */
14
+ editCollections: boolean;
15
+
16
+ /**
17
+ * Is the user allowed to delete this collection
18
+ */
19
+ deleteCollections: boolean;
20
+ }
@@ -0,0 +1,7 @@
1
+ import { EntityCollection, Properties, User } from "@firecms/core";
2
+
3
+ export type PersistedCollection<M extends Record<string, any> = any, AdditionalKey extends string = string, UserType extends User = User>
4
+ = Omit<EntityCollection<M, AdditionalKey, UserType>, "properties"> & {
5
+ properties: Properties<M>;
6
+ ownerId: string;
7
+ }
@@ -0,0 +1,9 @@
1
+ import React, { 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,103 @@
1
+ import React, { useCallback } from "react";
2
+ import { EntityCollection, FireCMSPlugin, User } from "@firecms/core";
3
+ import { ConfigControllerProvider } from "./ConfigControllerProvider";
4
+ import { CollectionEditorPermissionsBuilder } from "./types/config_permissions";
5
+ import { EditorCollectionAction } from "./components/EditorCollectionAction";
6
+ import { HomePageEditorCollectionAction } from "./components/HomePageEditorCollectionAction";
7
+ import { NewCollectionCard } from "./components/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 "./components/RootCollectionSuggestions";
12
+ import { joinCollectionLists } from "./utils/join_collections";
13
+
14
+ export interface CollectionConfigControllerProps<EC extends PersistedCollection = PersistedCollection, UserType extends User = User> {
15
+
16
+ /**
17
+ * Firebase app where the configuration is saved.
18
+ */
19
+ collectionConfigController: CollectionsConfigController;
20
+
21
+ /**
22
+ * Define what actions can be performed on the configuration.
23
+ */
24
+ configPermissions?: CollectionEditorPermissionsBuilder<UserType, EC>;
25
+
26
+ /**
27
+ * The words you define here will not be allowed to be used as group
28
+ * names when creating collections.
29
+ * e.g. ["admin"]
30
+ */
31
+ reservedGroups: string[];
32
+
33
+ extraView?: {
34
+ View: React.ComponentType<{
35
+ path: string
36
+ }>,
37
+ icon: React.ReactNode
38
+ };
39
+
40
+ pathSuggestions?: (path: string) => Promise<string[]>;
41
+
42
+ collectionInference?: CollectionInference;
43
+
44
+ getData?: (path: string) => Promise<object[]>;
45
+
46
+ getUser: (uid: string) => UserType | null;
47
+
48
+ }
49
+
50
+ /**
51
+ * Use this hook to initialise the Collection Editor plugin.
52
+ * This is likely the only hook you will need to use.
53
+ * @param firebaseApp Firebase app where your project data lives.
54
+ * @param configPermissions
55
+ * @param reservedGroups
56
+ * @param extraView
57
+ * @param pathSuggestions
58
+ * @param getUser
59
+ * @param collectionInference
60
+ */
61
+ export function useCollectionEditorPlugin<EC extends PersistedCollection = PersistedCollection, UserType extends User = User>
62
+ ({
63
+ collectionConfigController,
64
+ configPermissions,
65
+ reservedGroups,
66
+ extraView,
67
+ pathSuggestions,
68
+ getUser,
69
+ collectionInference,
70
+ getData
71
+ }: CollectionConfigControllerProps<EC, UserType>): FireCMSPlugin {
72
+
73
+ const injectCollections = useCallback(
74
+ (collections: EntityCollection[]) => joinCollectionLists(collectionConfigController.collections ?? [], collections),
75
+ [collectionConfigController.collections]);
76
+
77
+ return {
78
+ name: "Collection Editor",
79
+ loading: collectionConfigController.loading,
80
+ collections: {
81
+ injectCollections,
82
+ CollectionActions: EditorCollectionAction
83
+ },
84
+ provider: {
85
+ Component: ConfigControllerProvider,
86
+ props: {
87
+ collectionConfigController,
88
+ configPermissions,
89
+ collectionInference,
90
+ reservedGroups,
91
+ extraView,
92
+ pathSuggestions,
93
+ getUser,
94
+ getData
95
+ }
96
+ },
97
+ homePage: {
98
+ additionalChildrenStart: <RootCollectionSuggestions/>,
99
+ CollectionActions: HomePageEditorCollectionAction,
100
+ AdditionalCards: NewCollectionCard,
101
+ }
102
+ };
103
+ }
@@ -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,17 @@
1
+ import synonyms from "./synonyms";
2
+ import { iconKeys } from "@firecms/core";
3
+
4
+ // @ts-ignore
5
+ import * as JsSearch from "js-search";
6
+
7
+ export const iconsSearch = new JsSearch.Search("key");
8
+ iconsSearch.addIndex("synonyms");
9
+
10
+ iconsSearch.addDocuments(iconKeys
11
+ .map((importName) => {
12
+ return {
13
+ key: importName,
14
+ // @ts-ignore
15
+ synonyms: synonyms[importName] ?? [],
16
+ }
17
+ }));