@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.
- package/LICENSE +21 -0
- package/README.md +1 -0
- package/dist/ConfigControllerProvider.d.ts +37 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.es.js +5454 -0
- package/dist/index.es.js.map +1 -0
- package/dist/index.umd.js +4 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/types/collection_editor_controller.d.ts +36 -0
- package/dist/types/collection_inference.d.ts +2 -0
- package/dist/types/config_controller.d.ts +51 -0
- package/dist/types/config_permissions.d.ts +19 -0
- package/dist/types/persisted_collection.d.ts +6 -0
- package/dist/ui/CollectionViewHeaderAction.d.ts +10 -0
- package/dist/ui/EditorCollectionAction.d.ts +2 -0
- package/dist/ui/HomePageEditorCollectionAction.d.ts +2 -0
- package/dist/ui/MissingReferenceWidget.d.ts +3 -0
- package/dist/ui/NewCollectionButton.d.ts +1 -0
- package/dist/ui/NewCollectionCard.d.ts +2 -0
- package/dist/ui/PropertyAddColumnComponent.d.ts +6 -0
- package/dist/ui/RootCollectionSuggestions.d.ts +3 -0
- package/dist/ui/collection_editor/CollectionDetailsForm.d.ts +10 -0
- package/dist/ui/collection_editor/CollectionEditorDialog.d.ts +36 -0
- package/dist/ui/collection_editor/CollectionEditorWelcomeView.d.ts +15 -0
- package/dist/ui/collection_editor/CollectionPropertiesEditorForm.d.ts +19 -0
- package/dist/ui/collection_editor/CollectionYupValidation.d.ts +14 -0
- package/dist/ui/collection_editor/EntityCustomViewsSelectDialog.d.ts +4 -0
- package/dist/ui/collection_editor/EnumForm.d.ts +12 -0
- package/dist/ui/collection_editor/GetCodeDialog.d.ts +5 -0
- package/dist/ui/collection_editor/PropertyEditView.d.ts +40 -0
- package/dist/ui/collection_editor/PropertyFieldPreview.d.ts +15 -0
- package/dist/ui/collection_editor/PropertySelectItem.d.ts +8 -0
- package/dist/ui/collection_editor/PropertyTree.d.ts +33 -0
- package/dist/ui/collection_editor/SubcollectionsEditTab.d.ts +12 -0
- package/dist/ui/collection_editor/SwitchControl.d.ts +8 -0
- package/dist/ui/collection_editor/UnsavedChangesDialog.d.ts +9 -0
- package/dist/ui/collection_editor/import/CollectionEditorImportDataPreview.d.ts +7 -0
- package/dist/ui/collection_editor/import/CollectionEditorImportMapping.d.ts +7 -0
- package/dist/ui/collection_editor/import/clean_import_data.d.ts +7 -0
- package/dist/ui/collection_editor/properties/BlockPropertyField.d.ts +8 -0
- package/dist/ui/collection_editor/properties/BooleanPropertyField.d.ts +3 -0
- package/dist/ui/collection_editor/properties/CommonPropertyFields.d.ts +10 -0
- package/dist/ui/collection_editor/properties/DateTimePropertyField.d.ts +3 -0
- package/dist/ui/collection_editor/properties/EnumPropertyField.d.ts +8 -0
- package/dist/ui/collection_editor/properties/KeyValuePropertyField.d.ts +3 -0
- package/dist/ui/collection_editor/properties/MapPropertyField.d.ts +8 -0
- package/dist/ui/collection_editor/properties/NumberPropertyField.d.ts +3 -0
- package/dist/ui/collection_editor/properties/ReferencePropertyField.d.ts +13 -0
- package/dist/ui/collection_editor/properties/RepeatPropertyField.d.ts +10 -0
- package/dist/ui/collection_editor/properties/StoragePropertyField.d.ts +5 -0
- package/dist/ui/collection_editor/properties/StringPropertyField.d.ts +5 -0
- package/dist/ui/collection_editor/properties/UrlPropertyField.d.ts +4 -0
- package/dist/ui/collection_editor/properties/advanced/AdvancedPropertyValidation.d.ts +3 -0
- package/dist/ui/collection_editor/properties/validation/ArrayPropertyValidation.d.ts +5 -0
- package/dist/ui/collection_editor/properties/validation/GeneralPropertyValidation.d.ts +4 -0
- package/dist/ui/collection_editor/properties/validation/NumberPropertyValidation.d.ts +3 -0
- package/dist/ui/collection_editor/properties/validation/StringPropertyValidation.d.ts +11 -0
- package/dist/ui/collection_editor/properties/validation/ValidationPanel.d.ts +2 -0
- package/dist/ui/collection_editor/templates/blog_template.d.ts +2 -0
- package/dist/ui/collection_editor/templates/pages_template.d.ts +2 -0
- package/dist/ui/collection_editor/templates/products_template.d.ts +2 -0
- package/dist/ui/collection_editor/templates/users_template.d.ts +2 -0
- package/dist/ui/collection_editor/util.d.ts +5 -0
- package/dist/ui/collection_editor/utils/strings.d.ts +1 -0
- package/dist/ui/collection_editor/utils/supported_fields.d.ts +3 -0
- package/dist/ui/collection_editor/utils/update_property_for_widget.d.ts +2 -0
- package/dist/ui/collection_editor/utils/useTraceUpdate.d.ts +1 -0
- package/dist/useCollectionEditorController.d.ts +6 -0
- package/dist/useCollectionEditorPlugin.d.ts +49 -0
- package/dist/useCollectionsConfigController.d.ts +6 -0
- package/dist/utils/arrays.d.ts +1 -0
- package/dist/utils/entities.d.ts +3 -0
- package/package.json +85 -0
- package/src/ConfigControllerProvider.tsx +338 -0
- package/src/index.ts +35 -0
- package/src/types/collection_editor_controller.tsx +43 -0
- package/src/types/collection_inference.ts +3 -0
- package/src/types/config_controller.tsx +60 -0
- package/src/types/config_permissions.ts +20 -0
- package/src/types/persisted_collection.ts +9 -0
- package/src/ui/CollectionViewHeaderAction.tsx +43 -0
- package/src/ui/EditorCollectionAction.tsx +109 -0
- package/src/ui/HomePageEditorCollectionAction.tsx +84 -0
- package/src/ui/MissingReferenceWidget.tsx +37 -0
- package/src/ui/NewCollectionButton.tsx +16 -0
- package/src/ui/NewCollectionCard.tsx +48 -0
- package/src/ui/PropertyAddColumnComponent.tsx +42 -0
- package/src/ui/RootCollectionSuggestions.tsx +63 -0
- package/src/ui/collection_editor/CollectionDetailsForm.tsx +365 -0
- package/src/ui/collection_editor/CollectionEditorDialog.tsx +801 -0
- package/src/ui/collection_editor/CollectionEditorWelcomeView.tsx +213 -0
- package/src/ui/collection_editor/CollectionPropertiesEditorForm.tsx +506 -0
- package/src/ui/collection_editor/CollectionYupValidation.tsx +7 -0
- package/src/ui/collection_editor/EntityCustomViewsSelectDialog.tsx +37 -0
- package/src/ui/collection_editor/EnumForm.tsx +357 -0
- package/src/ui/collection_editor/GetCodeDialog.tsx +110 -0
- package/src/ui/collection_editor/PropertyEditView.tsx +615 -0
- package/src/ui/collection_editor/PropertyFieldPreview.tsx +207 -0
- package/src/ui/collection_editor/PropertySelectItem.tsx +32 -0
- package/src/ui/collection_editor/PropertyTree.tsx +252 -0
- package/src/ui/collection_editor/SubcollectionsEditTab.tsx +262 -0
- package/src/ui/collection_editor/SwitchControl.tsx +39 -0
- package/src/ui/collection_editor/UnsavedChangesDialog.tsx +47 -0
- package/src/ui/collection_editor/import/CollectionEditorImportDataPreview.tsx +37 -0
- package/src/ui/collection_editor/import/CollectionEditorImportMapping.tsx +268 -0
- package/src/ui/collection_editor/import/clean_import_data.ts +53 -0
- package/src/ui/collection_editor/properties/BlockPropertyField.tsx +138 -0
- package/src/ui/collection_editor/properties/BooleanPropertyField.tsx +40 -0
- package/src/ui/collection_editor/properties/CommonPropertyFields.tsx +110 -0
- package/src/ui/collection_editor/properties/DateTimePropertyField.tsx +86 -0
- package/src/ui/collection_editor/properties/EnumPropertyField.tsx +114 -0
- package/src/ui/collection_editor/properties/KeyValuePropertyField.tsx +20 -0
- package/src/ui/collection_editor/properties/MapPropertyField.tsx +150 -0
- package/src/ui/collection_editor/properties/NumberPropertyField.tsx +38 -0
- package/src/ui/collection_editor/properties/ReferencePropertyField.tsx +160 -0
- package/src/ui/collection_editor/properties/RepeatPropertyField.tsx +109 -0
- package/src/ui/collection_editor/properties/StoragePropertyField.tsx +200 -0
- package/src/ui/collection_editor/properties/StringPropertyField.tsx +79 -0
- package/src/ui/collection_editor/properties/UrlPropertyField.tsx +89 -0
- package/src/ui/collection_editor/properties/advanced/AdvancedPropertyValidation.tsx +45 -0
- package/src/ui/collection_editor/properties/validation/ArrayPropertyValidation.tsx +50 -0
- package/src/ui/collection_editor/properties/validation/GeneralPropertyValidation.tsx +61 -0
- package/src/ui/collection_editor/properties/validation/NumberPropertyValidation.tsx +115 -0
- package/src/ui/collection_editor/properties/validation/StringPropertyValidation.tsx +150 -0
- package/src/ui/collection_editor/properties/validation/ValidationPanel.tsx +28 -0
- package/src/ui/collection_editor/templates/blog_template.ts +115 -0
- package/src/ui/collection_editor/templates/pages_template.ts +188 -0
- package/src/ui/collection_editor/templates/products_template.ts +88 -0
- package/src/ui/collection_editor/templates/users_template.ts +42 -0
- package/src/ui/collection_editor/util.ts +28 -0
- package/src/ui/collection_editor/utils/strings.ts +9 -0
- package/src/ui/collection_editor/utils/supported_fields.tsx +29 -0
- package/src/ui/collection_editor/utils/update_property_for_widget.ts +271 -0
- package/src/ui/collection_editor/utils/useTraceUpdate.tsx +23 -0
- package/src/useCollectionEditorController.tsx +9 -0
- package/src/useCollectionEditorPlugin.tsx +154 -0
- package/src/useCollectionsConfigController.tsx +9 -0
- package/src/utils/arrays.ts +3 -0
- package/src/utils/entities.ts +38 -0
- 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,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" />
|