@firecms/collection_editor 3.0.0-beta.2-pre.2 → 3.0.0-beta.2-pre.3
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/dist/form/Field.d.ts +53 -0
- package/dist/form/Formex.d.ts +4 -0
- package/dist/form/index.d.ts +5 -0
- package/dist/form/types.d.ts +25 -0
- package/dist/form/useCreateFormex.d.ts +9 -0
- package/dist/form/utils.d.ts +44 -0
- package/dist/index.es.js +2612 -2328
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +2 -2
- package/dist/index.umd.js.map +1 -1
- package/dist/types/collection_editor_controller.d.ts +3 -2
- package/dist/types/config_controller.d.ts +3 -3
- package/dist/ui/collection_editor/CollectionEditorDialog.d.ts +3 -5
- package/dist/ui/collection_editor/CollectionEditorWelcomeView.d.ts +2 -2
- package/dist/ui/collection_editor/CollectionPropertiesEditorForm.d.ts +1 -2
- package/dist/ui/collection_editor/EnumForm.d.ts +1 -2
- package/dist/ui/collection_editor/PropertyEditView.d.ts +5 -5
- package/dist/ui/collection_editor/PropertyTree.d.ts +14 -13
- package/dist/ui/collection_editor/SwitchControl.d.ts +8 -0
- package/dist/ui/collection_editor/properties/CommonPropertyFields.d.ts +0 -1
- package/dist/ui/collection_editor/util.d.ts +1 -0
- package/package.json +5 -5
- package/src/ConfigControllerProvider.tsx +23 -21
- package/src/form/Field.tsx +162 -0
- package/src/form/Formex.tsx +8 -0
- package/src/form/README.md +165 -0
- package/src/form/index.ts +5 -0
- package/src/form/types.ts +27 -0
- package/src/form/useCreateFormex.tsx +137 -0
- package/src/form/utils.ts +169 -0
- package/src/types/collection_editor_controller.tsx +4 -3
- package/src/types/config_controller.tsx +3 -3
- package/src/ui/CollectionViewHeaderAction.tsx +1 -1
- package/src/ui/EditorCollectionAction.tsx +3 -3
- package/src/ui/HomePageEditorCollectionAction.tsx +2 -2
- package/src/ui/MissingReferenceWidget.tsx +2 -1
- package/src/ui/NewCollectionButton.tsx +3 -3
- package/src/ui/NewCollectionCard.tsx +2 -1
- package/src/ui/PropertyAddColumnComponent.tsx +1 -1
- package/src/ui/RootCollectionSuggestions.tsx +2 -1
- package/src/ui/collection_editor/CollectionDetailsForm.tsx +2 -2
- package/src/ui/collection_editor/CollectionEditorDialog.tsx +422 -374
- package/src/ui/collection_editor/CollectionEditorWelcomeView.tsx +19 -12
- package/src/ui/collection_editor/CollectionPropertiesEditorForm.tsx +26 -18
- package/src/ui/collection_editor/EnumForm.tsx +118 -114
- package/src/ui/collection_editor/GetCodeDialog.tsx +1 -1
- package/src/ui/collection_editor/PropertyEditView.tsx +198 -142
- package/src/ui/collection_editor/PropertyFieldPreview.tsx +5 -1
- package/src/ui/collection_editor/PropertyTree.tsx +132 -113
- package/src/ui/collection_editor/SubcollectionsEditTab.tsx +18 -11
- package/src/ui/collection_editor/SwitchControl.tsx +39 -0
- package/src/ui/collection_editor/import/CollectionEditorImportMapping.tsx +10 -2
- package/src/ui/collection_editor/properties/BlockPropertyField.tsx +2 -2
- package/src/ui/collection_editor/properties/BooleanPropertyField.tsx +13 -9
- package/src/ui/collection_editor/properties/CommonPropertyFields.tsx +11 -37
- package/src/ui/collection_editor/properties/DateTimePropertyField.tsx +2 -2
- package/src/ui/collection_editor/properties/EnumPropertyField.tsx +3 -6
- package/src/ui/collection_editor/properties/MapPropertyField.tsx +2 -2
- package/src/ui/collection_editor/properties/NumberPropertyField.tsx +2 -2
- package/src/ui/collection_editor/properties/ReferencePropertyField.tsx +11 -14
- package/src/ui/collection_editor/properties/RepeatPropertyField.tsx +10 -9
- package/src/ui/collection_editor/properties/StoragePropertyField.tsx +15 -9
- package/src/ui/collection_editor/properties/StringPropertyField.tsx +2 -2
- package/src/ui/collection_editor/properties/UrlPropertyField.tsx +2 -2
- package/src/ui/collection_editor/properties/advanced/AdvancedPropertyValidation.tsx +27 -18
- package/src/ui/collection_editor/properties/validation/ArrayPropertyValidation.tsx +2 -2
- package/src/ui/collection_editor/properties/validation/GeneralPropertyValidation.tsx +27 -16
- package/src/ui/collection_editor/properties/validation/NumberPropertyValidation.tsx +33 -18
- package/src/ui/collection_editor/properties/validation/StringPropertyValidation.tsx +99 -80
- package/src/ui/collection_editor/util.ts +7 -0
- package/src/ui/collection_editor/utils/strings.ts +2 -1
|
@@ -2,7 +2,6 @@ import * as React from "react";
|
|
|
2
2
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
3
3
|
import {
|
|
4
4
|
CircularProgressCenter,
|
|
5
|
-
CMSType,
|
|
6
5
|
EntityCollection,
|
|
7
6
|
ErrorView,
|
|
8
7
|
isPropertyBuilder,
|
|
@@ -36,9 +35,8 @@ import {
|
|
|
36
35
|
IconButton,
|
|
37
36
|
LoadingButton,
|
|
38
37
|
Tab,
|
|
39
|
-
Tabs
|
|
38
|
+
Tabs
|
|
40
39
|
} from "@firecms/ui";
|
|
41
|
-
import { Form, Formik, FormikHelpers } from "formik";
|
|
42
40
|
import { YupSchema } from "./CollectionYupValidation";
|
|
43
41
|
import { CollectionDetailsForm } from "./CollectionDetailsForm";
|
|
44
42
|
import { CollectionPropertiesEditorForm } from "./CollectionPropertiesEditorForm";
|
|
@@ -53,6 +51,8 @@ import { CollectionEditorImportMapping } from "./import/CollectionEditorImportMa
|
|
|
53
51
|
import { CollectionEditorImportDataPreview } from "./import/CollectionEditorImportDataPreview";
|
|
54
52
|
import { cleanPropertiesFromImport } from "./import/clean_import_data";
|
|
55
53
|
import { PersistedCollection } from "../../types/persisted_collection";
|
|
54
|
+
import { Formex, FormexController, useCreateFormex } from "../../form";
|
|
55
|
+
import { getFullIdPath } from "./util";
|
|
56
56
|
|
|
57
57
|
export interface CollectionEditorDialogProps {
|
|
58
58
|
open: boolean;
|
|
@@ -62,7 +62,7 @@ export interface CollectionEditorDialogProps {
|
|
|
62
62
|
path?: string,
|
|
63
63
|
name?: string,
|
|
64
64
|
}
|
|
65
|
-
|
|
65
|
+
editedCollectionId?: string;
|
|
66
66
|
fullPath?: string; // full path of this particular collection, like `products/123/locales`
|
|
67
67
|
parentCollectionIds?: string[]; // path ids of the parent collection, like [`products`]
|
|
68
68
|
handleClose: (collection?: EntityCollection) => void;
|
|
@@ -112,9 +112,9 @@ export function CollectionEditorDialog(props: CollectionEditorDialogProps) {
|
|
|
112
112
|
maxWidth={"7xl"}
|
|
113
113
|
onOpenChange={(open) => !open ? handleCancel() : undefined}
|
|
114
114
|
>
|
|
115
|
-
{open && <
|
|
116
|
-
|
|
117
|
-
|
|
115
|
+
{open && <CollectionEditor {...props}
|
|
116
|
+
handleCancel={handleCancel}
|
|
117
|
+
setFormDirty={setFormDirty}/>}
|
|
118
118
|
|
|
119
119
|
<UnsavedChangesDialog
|
|
120
120
|
open={unsavedChangesDialogOpen}
|
|
@@ -136,45 +136,41 @@ type EditorView = "welcome"
|
|
|
136
136
|
| "extra_view"
|
|
137
137
|
| "subcollections";
|
|
138
138
|
|
|
139
|
-
export function
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
initialValues: initialValuesProp,
|
|
144
|
-
configController,
|
|
145
|
-
editedCollectionPath,
|
|
146
|
-
parentCollectionIds,
|
|
147
|
-
fullPath,
|
|
148
|
-
collectionInference,
|
|
149
|
-
handleClose,
|
|
150
|
-
reservedGroups,
|
|
151
|
-
extraView,
|
|
152
|
-
handleCancel,
|
|
153
|
-
setFormDirty,
|
|
154
|
-
pathSuggestions,
|
|
155
|
-
getUser,
|
|
156
|
-
parentCollection,
|
|
157
|
-
getData
|
|
158
|
-
}: CollectionEditorDialogProps & {
|
|
159
|
-
handleCancel: () => void,
|
|
160
|
-
setFormDirty: (dirty: boolean) => void
|
|
161
|
-
}
|
|
162
|
-
) {
|
|
163
|
-
|
|
139
|
+
export function CollectionEditor<M extends Record<string, any>>(props: CollectionEditorDialogProps & {
|
|
140
|
+
handleCancel: () => void,
|
|
141
|
+
setFormDirty: (dirty: boolean) => void
|
|
142
|
+
}) {
|
|
164
143
|
const { propertyConfigs } = useCustomizationController();
|
|
165
144
|
const navigation = useNavigationController();
|
|
145
|
+
const authController = useAuthController();
|
|
146
|
+
|
|
166
147
|
const {
|
|
167
148
|
topLevelNavigation,
|
|
168
149
|
collections
|
|
169
150
|
} = navigation;
|
|
170
151
|
|
|
171
|
-
const
|
|
172
|
-
const
|
|
152
|
+
const initialValuesProp = props.initialValues;
|
|
153
|
+
const includeTemplates = !initialValuesProp?.path && (props.parentCollectionIds ?? []).length === 0;
|
|
154
|
+
const collectionsInThisLevel = (props.parentCollection ? props.parentCollection.subcollections : collections) ?? [];
|
|
173
155
|
const existingPaths = collectionsInThisLevel.map(col => col.path.trim().toLowerCase());
|
|
174
156
|
const existingIds = collectionsInThisLevel.map(col => col.id?.trim().toLowerCase()).filter(Boolean) as string[];
|
|
157
|
+
const [collection, setCollection] = React.useState<PersistedCollection<M> | undefined>();
|
|
158
|
+
const [initialLoadingCompleted, setInitialLoadingCompleted] = React.useState(false);
|
|
175
159
|
|
|
176
|
-
|
|
177
|
-
|
|
160
|
+
useEffect(() => {
|
|
161
|
+
try {
|
|
162
|
+
if (navigation.initialised) {
|
|
163
|
+
if (props.editedCollectionId) {
|
|
164
|
+
setCollection(navigation.getCollectionFromPaths<PersistedCollection<M>>([...(props.parentCollectionIds ?? []), props.editedCollectionId]));
|
|
165
|
+
} else {
|
|
166
|
+
setCollection(undefined);
|
|
167
|
+
}
|
|
168
|
+
setInitialLoadingCompleted(true);
|
|
169
|
+
}
|
|
170
|
+
} catch (e) {
|
|
171
|
+
console.error(e);
|
|
172
|
+
}
|
|
173
|
+
}, [navigation.getCollectionFromPaths, props.editedCollectionId, props.parentCollectionIds, navigation.initialised]);
|
|
178
174
|
if (!topLevelNavigation) {
|
|
179
175
|
throw Error("Internal: Navigation not ready in collection editor");
|
|
180
176
|
}
|
|
@@ -183,8 +179,88 @@ export function CollectionEditorDialogInternal<M extends {
|
|
|
183
179
|
groups
|
|
184
180
|
}: TopNavigationResult = topLevelNavigation;
|
|
185
181
|
|
|
182
|
+
const initialCollection = collection
|
|
183
|
+
? {
|
|
184
|
+
...collection,
|
|
185
|
+
id: collection.id ?? collection.path ?? randomString(16)
|
|
186
|
+
}
|
|
187
|
+
: undefined;
|
|
188
|
+
|
|
189
|
+
const initialValues: PersistedCollection<M> = initialCollection
|
|
190
|
+
? applyPropertyConfigs(initialCollection, propertyConfigs)
|
|
191
|
+
: {
|
|
192
|
+
id: initialValuesProp?.path ?? randomString(16),
|
|
193
|
+
path: initialValuesProp?.path ?? "",
|
|
194
|
+
name: initialValuesProp?.name ?? "",
|
|
195
|
+
group: initialValuesProp?.group ?? "",
|
|
196
|
+
properties: {} as PropertiesOrBuilders<M>,
|
|
197
|
+
propertiesOrder: [],
|
|
198
|
+
icon: coolIconKeys[Math.floor(Math.random() * coolIconKeys.length)],
|
|
199
|
+
ownerId: authController.user?.uid ?? ""
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
if (!initialLoadingCompleted) {
|
|
203
|
+
return <CircularProgressCenter/>;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (!props.isNewCollection && (!navigation.initialised || !initialLoadingCompleted)) {
|
|
207
|
+
return <CircularProgressCenter/>;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return <CollectionEditorInternal
|
|
211
|
+
{...props}
|
|
212
|
+
initialValues={initialValues}
|
|
213
|
+
existingPaths={existingPaths}
|
|
214
|
+
existingIds={existingIds}
|
|
215
|
+
includeTemplates={includeTemplates}
|
|
216
|
+
collection={collection}
|
|
217
|
+
setCollection={setCollection}
|
|
218
|
+
groups={groups}
|
|
219
|
+
propertyConfigs={propertyConfigs}/>
|
|
220
|
+
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function CollectionEditorInternal<M extends Record<string, any>>({
|
|
224
|
+
isNewCollection,
|
|
225
|
+
configController,
|
|
226
|
+
editedCollectionId,
|
|
227
|
+
parentCollectionIds,
|
|
228
|
+
fullPath,
|
|
229
|
+
collectionInference,
|
|
230
|
+
handleClose,
|
|
231
|
+
reservedGroups,
|
|
232
|
+
extraView,
|
|
233
|
+
handleCancel,
|
|
234
|
+
setFormDirty,
|
|
235
|
+
pathSuggestions,
|
|
236
|
+
getUser,
|
|
237
|
+
parentCollection,
|
|
238
|
+
getData,
|
|
239
|
+
existingPaths,
|
|
240
|
+
existingIds,
|
|
241
|
+
includeTemplates,
|
|
242
|
+
collection,
|
|
243
|
+
setCollection,
|
|
244
|
+
initialValues,
|
|
245
|
+
propertyConfigs,
|
|
246
|
+
groups
|
|
247
|
+
}: CollectionEditorDialogProps & {
|
|
248
|
+
handleCancel: () => void,
|
|
249
|
+
setFormDirty: (dirty: boolean) => void,
|
|
250
|
+
initialValues: PersistedCollection<M>,
|
|
251
|
+
existingPaths: string[],
|
|
252
|
+
existingIds: string[],
|
|
253
|
+
includeTemplates: boolean,
|
|
254
|
+
collection: PersistedCollection<M> | undefined,
|
|
255
|
+
setCollection: (collection: PersistedCollection<M>) => void,
|
|
256
|
+
propertyConfigs: Record<string, PropertyConfig<any>>,
|
|
257
|
+
groups: string[],
|
|
258
|
+
}
|
|
259
|
+
) {
|
|
260
|
+
|
|
261
|
+
const importConfig = useImportConfig();
|
|
262
|
+
const navigation = useNavigationController();
|
|
186
263
|
const snackbarController = useSnackbarController();
|
|
187
|
-
const authController = useAuthController();
|
|
188
264
|
|
|
189
265
|
// Use this ref to store which properties have errors
|
|
190
266
|
const propertyErrorsRef = useRef({});
|
|
@@ -194,32 +270,12 @@ export function CollectionEditorDialogInternal<M extends {
|
|
|
194
270
|
|
|
195
271
|
const [error, setError] = React.useState<Error | undefined>();
|
|
196
272
|
|
|
197
|
-
const [collection, setCollection] = React.useState<PersistedCollection<M> | undefined>();
|
|
198
|
-
const [initialLoadingCompleted, setInitialLoadingCompleted] = React.useState(false);
|
|
199
|
-
const [initialError, setInitialError] = React.useState<Error | undefined>();
|
|
200
|
-
|
|
201
|
-
useEffect(() => {
|
|
202
|
-
try {
|
|
203
|
-
if (navigation.initialised) {
|
|
204
|
-
if (editedCollectionPath) {
|
|
205
|
-
setCollection(navigation.getCollectionFromPaths<PersistedCollection<M>>([...(parentCollectionIds ?? []), editedCollectionPath]));
|
|
206
|
-
} else {
|
|
207
|
-
setCollection(undefined);
|
|
208
|
-
}
|
|
209
|
-
setInitialLoadingCompleted(true);
|
|
210
|
-
}
|
|
211
|
-
} catch (e) {
|
|
212
|
-
console.error(e);
|
|
213
|
-
setInitialError(initialError);
|
|
214
|
-
}
|
|
215
|
-
}, [navigation.getCollectionFromPaths, editedCollectionPath, initialError, navigation.initialised]);
|
|
216
|
-
|
|
217
273
|
const saveCollection = (updatedCollection: PersistedCollection<M>): Promise<boolean> => {
|
|
218
|
-
const
|
|
274
|
+
const id = updatedCollection.id || updatedCollection.path;
|
|
219
275
|
return configController.saveCollection({
|
|
220
|
-
id
|
|
276
|
+
id,
|
|
221
277
|
collectionData: updatedCollection,
|
|
222
|
-
|
|
278
|
+
previousId: editedCollectionId,
|
|
223
279
|
parentCollectionIds
|
|
224
280
|
})
|
|
225
281
|
.then(() => {
|
|
@@ -237,26 +293,6 @@ export function CollectionEditorDialogInternal<M extends {
|
|
|
237
293
|
});
|
|
238
294
|
};
|
|
239
295
|
|
|
240
|
-
const initialCollection = collection
|
|
241
|
-
? {
|
|
242
|
-
...collection,
|
|
243
|
-
id: collection.id ?? collection.path ?? randomString(16)
|
|
244
|
-
}
|
|
245
|
-
: undefined;
|
|
246
|
-
|
|
247
|
-
const initialValues: PersistedCollection<M> = initialCollection
|
|
248
|
-
? applyPropertyConfigs(initialCollection, propertyConfigs)
|
|
249
|
-
: {
|
|
250
|
-
id: initialValuesProp?.path ?? randomString(16),
|
|
251
|
-
path: initialValuesProp?.path ?? "",
|
|
252
|
-
name: initialValuesProp?.name ?? "",
|
|
253
|
-
group: initialValuesProp?.group ?? "",
|
|
254
|
-
properties: {} as PropertiesOrBuilders<M>,
|
|
255
|
-
propertiesOrder: [],
|
|
256
|
-
icon: coolIconKeys[Math.floor(Math.random() * coolIconKeys.length)],
|
|
257
|
-
ownerId: authController.user?.uid ?? ""
|
|
258
|
-
};
|
|
259
|
-
|
|
260
296
|
const setNextMode = useCallback(() => {
|
|
261
297
|
if (currentView === "details") {
|
|
262
298
|
if (importConfig.inUse) {
|
|
@@ -316,7 +352,7 @@ export function CollectionEditorDialogInternal<M extends {
|
|
|
316
352
|
}
|
|
317
353
|
|
|
318
354
|
setCollection(values);
|
|
319
|
-
console.
|
|
355
|
+
console.debug("Inferred collection", {
|
|
320
356
|
newCollection: newCollection ?? {},
|
|
321
357
|
values
|
|
322
358
|
});
|
|
@@ -331,13 +367,13 @@ export function CollectionEditorDialogInternal<M extends {
|
|
|
331
367
|
}
|
|
332
368
|
}, [parentCollectionIds, doCollectionInference]);
|
|
333
369
|
|
|
334
|
-
const onSubmit = (newCollectionState: PersistedCollection<M>,
|
|
370
|
+
const onSubmit = (newCollectionState: PersistedCollection<M>, formexController: FormexController<PersistedCollection<M>>) => {
|
|
371
|
+
console.log("Submitting collection", newCollectionState);
|
|
335
372
|
try {
|
|
336
373
|
|
|
337
|
-
console.log("Submitting collection", newCollectionState)
|
|
338
374
|
if (!isNewCollection) {
|
|
339
375
|
saveCollection(newCollectionState).then(() => {
|
|
340
|
-
|
|
376
|
+
formexController.resetForm({ values: initialValues });
|
|
341
377
|
// setNextMode();
|
|
342
378
|
handleClose(newCollectionState);
|
|
343
379
|
});
|
|
@@ -346,15 +382,15 @@ export function CollectionEditorDialogInternal<M extends {
|
|
|
346
382
|
|
|
347
383
|
if (currentView === "welcome") {
|
|
348
384
|
setNextMode();
|
|
349
|
-
|
|
385
|
+
formexController.resetForm({ values: newCollectionState });
|
|
350
386
|
} else if (currentView === "details") {
|
|
351
387
|
if (extraView || importConfig.inUse) {
|
|
352
|
-
|
|
388
|
+
formexController.resetForm({ values: newCollectionState });
|
|
353
389
|
setNextMode();
|
|
354
390
|
} else if (isNewCollection) {
|
|
355
391
|
inferCollectionFromData(newCollectionState)
|
|
356
392
|
.then((values) => {
|
|
357
|
-
|
|
393
|
+
formexController.resetForm({
|
|
358
394
|
values: values ?? newCollectionState,
|
|
359
395
|
touched: {
|
|
360
396
|
path: true,
|
|
@@ -365,25 +401,25 @@ export function CollectionEditorDialogInternal<M extends {
|
|
|
365
401
|
setNextMode();
|
|
366
402
|
});
|
|
367
403
|
} else {
|
|
368
|
-
|
|
404
|
+
formexController.resetForm({ values: newCollectionState });
|
|
369
405
|
setNextMode();
|
|
370
406
|
}
|
|
371
407
|
} else if (currentView === "extra_view") {
|
|
372
408
|
setNextMode();
|
|
373
|
-
|
|
409
|
+
formexController.resetForm({ values: newCollectionState });
|
|
374
410
|
} else if (currentView === "import_data_mapping") {
|
|
375
411
|
setNextMode();
|
|
376
412
|
} else if (currentView === "import_data_preview") {
|
|
377
413
|
setNextMode();
|
|
378
414
|
} else if (currentView === "properties") {
|
|
379
415
|
saveCollection(newCollectionState).then(() => {
|
|
380
|
-
|
|
416
|
+
formexController.resetForm({ values: initialValues });
|
|
381
417
|
setNextMode();
|
|
382
418
|
handleClose(newCollectionState);
|
|
383
419
|
});
|
|
384
420
|
} else {
|
|
385
421
|
setNextMode();
|
|
386
|
-
|
|
422
|
+
formexController.resetForm({ values: newCollectionState });
|
|
387
423
|
}
|
|
388
424
|
} catch (e: any) {
|
|
389
425
|
snackbarController.open({
|
|
@@ -391,298 +427,310 @@ export function CollectionEditorDialogInternal<M extends {
|
|
|
391
427
|
message: "Error persisting collection: " + (e.message ?? "Details in the console")
|
|
392
428
|
});
|
|
393
429
|
console.error(e);
|
|
394
|
-
|
|
430
|
+
formexController.resetForm({ values: newCollectionState });
|
|
395
431
|
}
|
|
396
432
|
};
|
|
397
433
|
|
|
398
|
-
|
|
399
|
-
|
|
434
|
+
const validation = (col: PersistedCollection) => {
|
|
435
|
+
|
|
436
|
+
let errors: Record<string, any> = {};
|
|
437
|
+
const schema = (currentView === "properties" || currentView === "subcollections" || currentView === "details") && YupSchema;
|
|
438
|
+
if (schema) {
|
|
439
|
+
try {
|
|
440
|
+
schema.validateSync(col, { abortEarly: false });
|
|
441
|
+
} catch (e: any) {
|
|
442
|
+
e.inner.forEach((err: any) => {
|
|
443
|
+
errors[err.path] = err.message;
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
if (currentView === "properties") {
|
|
448
|
+
errors = { ...errors, ...propertyErrorsRef.current };
|
|
449
|
+
}
|
|
450
|
+
if (currentView === "details") {
|
|
451
|
+
const pathError = validatePath(col.path, isNewCollection, existingPaths, col.id);
|
|
452
|
+
if (pathError) {
|
|
453
|
+
errors.path = pathError;
|
|
454
|
+
}
|
|
455
|
+
const idError = validateId(col.id, isNewCollection, existingPaths, existingIds);
|
|
456
|
+
if (idError) {
|
|
457
|
+
errors.id = idError;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
return errors;
|
|
461
|
+
};
|
|
462
|
+
|
|
463
|
+
const formController = useCreateFormex<PersistedCollection<M>>({
|
|
464
|
+
initialValues,
|
|
465
|
+
onSubmit,
|
|
466
|
+
validation
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
const {
|
|
470
|
+
values,
|
|
471
|
+
setFieldValue,
|
|
472
|
+
isSubmitting,
|
|
473
|
+
dirty,
|
|
474
|
+
submitCount
|
|
475
|
+
} = formController;
|
|
476
|
+
|
|
477
|
+
const path = values.path ?? editedCollectionId;
|
|
478
|
+
const updatedFullPath = fullPath?.includes("/") ? fullPath?.split("/").slice(0, -1).join("/") + "/" + path : path; // TODO: this path is wrong
|
|
479
|
+
const pathError = validatePath(path, isNewCollection, existingPaths, values.id);
|
|
480
|
+
|
|
481
|
+
const parentPaths = !pathError && parentCollectionIds ? navigation.convertIdsToPaths(parentCollectionIds) : undefined;
|
|
482
|
+
const resolvedPath = !pathError ? navigation.resolveAliasesFrom(updatedFullPath) : undefined;
|
|
483
|
+
const getDataWithPath = resolvedPath && getData ? () => getData(resolvedPath, parentPaths ?? []) : undefined;
|
|
484
|
+
|
|
485
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
486
|
+
useEffect(() => {
|
|
487
|
+
setFormDirty(dirty);
|
|
488
|
+
}, [dirty]);
|
|
489
|
+
|
|
490
|
+
function onImportDataSet(data: object[]) {
|
|
491
|
+
importConfig.setInUse(true);
|
|
492
|
+
buildEntityPropertiesFromData(data, getInferenceType)
|
|
493
|
+
.then((properties) => {
|
|
494
|
+
const res = cleanPropertiesFromImport(properties);
|
|
495
|
+
|
|
496
|
+
setFieldValue("properties", res.properties);
|
|
497
|
+
setFieldValue("propertiesOrder", Object.keys(res.properties));
|
|
498
|
+
|
|
499
|
+
importConfig.setIdColumn(res.idColumn);
|
|
500
|
+
importConfig.setImportData(data);
|
|
501
|
+
importConfig.setHeadersMapping(res.headersMapping);
|
|
502
|
+
importConfig.setOriginProperties(res.properties);
|
|
503
|
+
});
|
|
400
504
|
}
|
|
401
505
|
|
|
506
|
+
const validValues = Boolean(values.name) && Boolean(values.id);
|
|
507
|
+
|
|
508
|
+
const onImportMappingComplete = () => {
|
|
509
|
+
const updatedProperties = { ...values.properties };
|
|
510
|
+
if (importConfig.idColumn)
|
|
511
|
+
delete updatedProperties[importConfig.idColumn];
|
|
512
|
+
setFieldValue("properties", updatedProperties);
|
|
513
|
+
// setFieldValue("propertiesOrder", Object.values(importConfig.headersMapping));
|
|
514
|
+
setNextMode();
|
|
515
|
+
};
|
|
516
|
+
|
|
517
|
+
const editable = collection?.editable === undefined || collection?.editable === true;
|
|
518
|
+
const collectionEditable = editable || isNewCollection;
|
|
519
|
+
|
|
402
520
|
return <DialogContent fullHeight={true}>
|
|
403
|
-
<
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
521
|
+
<Formex value={formController}>
|
|
522
|
+
|
|
523
|
+
<>
|
|
524
|
+
{!isNewCollection && <Tabs value={currentView}
|
|
525
|
+
className={cn(defaultBorderMixin, "justify-end bg-gray-50 dark:bg-gray-950 border-b")}
|
|
526
|
+
onValueChange={(v) => setCurrentView(v as EditorView)}>
|
|
527
|
+
<Tab value={"details"}>
|
|
528
|
+
Details
|
|
529
|
+
</Tab>
|
|
530
|
+
<Tab value={"properties"}>
|
|
531
|
+
Properties
|
|
532
|
+
</Tab>
|
|
533
|
+
<Tab value={"subcollections"}>
|
|
534
|
+
Additional views
|
|
535
|
+
</Tab>
|
|
536
|
+
</Tabs>}
|
|
537
|
+
|
|
538
|
+
<form noValidate
|
|
539
|
+
onSubmit={formController.submitForm}
|
|
540
|
+
className={cn(
|
|
541
|
+
isNewCollection ? "h-full" : "h-[calc(100%-48px)]",
|
|
542
|
+
"flex-grow flex flex-col relative")}>
|
|
543
|
+
|
|
544
|
+
{currentView === "loading" &&
|
|
545
|
+
<CircularProgressCenter/>}
|
|
546
|
+
|
|
547
|
+
{currentView === "extra_view" &&
|
|
548
|
+
path &&
|
|
549
|
+
extraView?.View &&
|
|
550
|
+
<extraView.View path={path}/>}
|
|
551
|
+
|
|
552
|
+
{currentView === "welcome" &&
|
|
553
|
+
<CollectionEditorWelcomeView
|
|
554
|
+
path={path}
|
|
555
|
+
onContinue={(data) => {
|
|
556
|
+
if (data) {
|
|
557
|
+
onImportDataSet(data);
|
|
558
|
+
setCurrentView("import_data_mapping");
|
|
559
|
+
} else {
|
|
560
|
+
setCurrentView("details");
|
|
561
|
+
}
|
|
562
|
+
}}
|
|
563
|
+
existingCollectionPaths={existingPaths}
|
|
564
|
+
parentCollection={parentCollection}
|
|
565
|
+
pathSuggestions={pathSuggestions}/>}
|
|
566
|
+
|
|
567
|
+
{currentView === "import_data_mapping" && importConfig &&
|
|
568
|
+
<CollectionEditorImportMapping importConfig={importConfig}
|
|
569
|
+
collectionEditable={collectionEditable}
|
|
570
|
+
propertyConfigs={propertyConfigs}/>}
|
|
571
|
+
|
|
572
|
+
{currentView === "import_data_preview" && importConfig &&
|
|
573
|
+
<CollectionEditorImportDataPreview importConfig={importConfig}
|
|
574
|
+
properties={values.properties as Properties}
|
|
575
|
+
propertiesOrder={values.propertiesOrder as string[]}/>}
|
|
576
|
+
|
|
577
|
+
{currentView === "import_data_saving" && importConfig &&
|
|
578
|
+
<ImportSaveInProgress importConfig={importConfig}
|
|
579
|
+
collection={values}
|
|
580
|
+
onImportSuccess={(importedCollection) => {
|
|
581
|
+
handleClose(importedCollection);
|
|
582
|
+
snackbarController.open({
|
|
583
|
+
type: "info",
|
|
584
|
+
message: "Data imported successfully"
|
|
585
|
+
});
|
|
586
|
+
}}
|
|
587
|
+
/>}
|
|
588
|
+
|
|
589
|
+
{currentView === "details" &&
|
|
590
|
+
<CollectionDetailsForm
|
|
591
|
+
existingPaths={existingPaths}
|
|
592
|
+
existingIds={existingIds}
|
|
593
|
+
groups={groups}
|
|
594
|
+
parentCollectionIds={parentCollectionIds}
|
|
595
|
+
parentCollection={parentCollection}
|
|
596
|
+
isNewCollection={isNewCollection}/>}
|
|
597
|
+
|
|
598
|
+
{currentView === "subcollections" && collection &&
|
|
599
|
+
<SubcollectionsEditTab
|
|
600
|
+
parentCollection={parentCollection}
|
|
601
|
+
configController={configController}
|
|
602
|
+
getUser={getUser}
|
|
603
|
+
collectionInference={collectionInference}
|
|
604
|
+
parentCollectionIds={parentCollectionIds}
|
|
605
|
+
collection={collection}/>}
|
|
606
|
+
|
|
607
|
+
{currentView === "properties" &&
|
|
608
|
+
<CollectionPropertiesEditorForm
|
|
609
|
+
showErrors={submitCount > 0}
|
|
610
|
+
isNewCollection={isNewCollection}
|
|
611
|
+
reservedGroups={reservedGroups}
|
|
612
|
+
onPropertyError={(propertyKey, namespace, error) => {
|
|
613
|
+
console.debug("!!!onPropertyError", { propertyKey, namespace, error })
|
|
614
|
+
const current = removeUndefined({
|
|
615
|
+
...propertyErrorsRef.current,
|
|
616
|
+
[getFullIdPath(propertyKey, namespace)]: removeUndefined(error, true)
|
|
617
|
+
}, true);
|
|
618
|
+
console.debug("aa!!!onPropertyError", { current })
|
|
619
|
+
propertyErrorsRef.current = current;
|
|
620
|
+
formController.validate();
|
|
621
|
+
}}
|
|
622
|
+
getUser={getUser}
|
|
623
|
+
getData={getDataWithPath}
|
|
624
|
+
doCollectionInference={doCollectionInference}
|
|
625
|
+
propertyConfigs={propertyConfigs}
|
|
626
|
+
collectionEditable={collectionEditable}
|
|
627
|
+
extraIcon={extraView?.icon &&
|
|
628
|
+
<IconButton
|
|
629
|
+
color={"primary"}
|
|
630
|
+
onClick={() => setCurrentView("extra_view")}>
|
|
631
|
+
{extraView.icon}
|
|
632
|
+
</IconButton>}/>
|
|
420
633
|
}
|
|
421
|
-
}
|
|
422
|
-
return errors;
|
|
423
|
-
}}
|
|
424
|
-
onSubmit={onSubmit}
|
|
425
|
-
>
|
|
426
|
-
{(formikHelpers) => {
|
|
427
|
-
const {
|
|
428
|
-
values,
|
|
429
|
-
errors,
|
|
430
|
-
setFieldValue,
|
|
431
|
-
isSubmitting,
|
|
432
|
-
dirty,
|
|
433
|
-
submitCount
|
|
434
|
-
} = formikHelpers;
|
|
435
|
-
|
|
436
|
-
const path = values.path ?? editedCollectionPath;
|
|
437
|
-
const updatedFullPath = fullPath?.includes("/") ? fullPath?.split("/").slice(0, -1).join("/") + "/" + path : path; // TODO: this path is wrong
|
|
438
|
-
const pathError = validatePath(path, isNewCollection, existingPaths, values.id);
|
|
439
|
-
|
|
440
|
-
const parentPaths = !pathError && parentCollectionIds ? navigation.convertIdsToPaths(parentCollectionIds) : undefined;
|
|
441
|
-
const resolvedPath = !pathError ? navigation.resolveAliasesFrom(updatedFullPath) : undefined;
|
|
442
|
-
const getDataWithPath = resolvedPath && getData ? () => getData(resolvedPath, parentPaths ?? []) : undefined;
|
|
443
|
-
|
|
444
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
445
|
-
useEffect(() => {
|
|
446
|
-
setFormDirty(dirty);
|
|
447
|
-
}, [dirty]);
|
|
448
|
-
|
|
449
|
-
function onImportDataSet(data: object[]) {
|
|
450
|
-
importConfig.setInUse(true);
|
|
451
|
-
buildEntityPropertiesFromData(data, getInferenceType)
|
|
452
|
-
.then((properties) => {
|
|
453
|
-
const res = cleanPropertiesFromImport(properties);
|
|
454
|
-
|
|
455
|
-
setFieldValue("properties", res.properties);
|
|
456
|
-
setFieldValue("propertiesOrder", Object.keys(res.properties));
|
|
457
|
-
|
|
458
|
-
importConfig.setIdColumn(res.idColumn);
|
|
459
|
-
importConfig.setImportData(data);
|
|
460
|
-
importConfig.setHeadersMapping(res.headersMapping);
|
|
461
|
-
importConfig.setOriginProperties(res.properties);
|
|
462
|
-
});
|
|
463
|
-
}
|
|
464
634
|
|
|
465
|
-
|
|
635
|
+
{currentView !== "welcome" && <DialogActions
|
|
636
|
+
position={"absolute"}>
|
|
637
|
+
{error && <ErrorView error={error}/>}
|
|
638
|
+
|
|
639
|
+
{isNewCollection && includeTemplates && currentView === "import_data_mapping" &&
|
|
640
|
+
<Button variant={"text"}
|
|
641
|
+
type="button"
|
|
642
|
+
onClick={() => {
|
|
643
|
+
importConfig.setInUse(false);
|
|
644
|
+
return setCurrentView("welcome");
|
|
645
|
+
}}>
|
|
646
|
+
<ArrowBackIcon/>
|
|
647
|
+
Back
|
|
648
|
+
</Button>}
|
|
649
|
+
|
|
650
|
+
{isNewCollection && includeTemplates && currentView === "import_data_preview" &&
|
|
651
|
+
<Button variant={"text"}
|
|
652
|
+
type="button"
|
|
653
|
+
onClick={() => {
|
|
654
|
+
saveCollection(values);
|
|
655
|
+
setCurrentView("import_data_mapping");
|
|
656
|
+
}}>
|
|
657
|
+
<ArrowBackIcon/>
|
|
658
|
+
Back
|
|
659
|
+
</Button>}
|
|
660
|
+
|
|
661
|
+
{isNewCollection && includeTemplates && currentView === "details" &&
|
|
662
|
+
<Button variant={"text"}
|
|
663
|
+
type="button"
|
|
664
|
+
onClick={() => setCurrentView("welcome")}>
|
|
665
|
+
<ArrowBackIcon/>
|
|
666
|
+
Back
|
|
667
|
+
</Button>}
|
|
668
|
+
|
|
669
|
+
{isNewCollection && currentView === "properties" && <Button variant={"text"}
|
|
670
|
+
type="button"
|
|
671
|
+
onClick={() => setCurrentView("details")}>
|
|
672
|
+
<ArrowBackIcon/>
|
|
673
|
+
Back
|
|
674
|
+
</Button>}
|
|
675
|
+
|
|
676
|
+
<Button variant={"text"}
|
|
677
|
+
onClick={() => {
|
|
678
|
+
handleCancel();
|
|
679
|
+
}}>
|
|
680
|
+
Cancel
|
|
681
|
+
</Button>
|
|
682
|
+
|
|
683
|
+
{isNewCollection && currentView === "import_data_mapping" &&
|
|
684
|
+
<Button
|
|
685
|
+
variant={"filled"}
|
|
686
|
+
color="primary"
|
|
687
|
+
onClick={onImportMappingComplete}
|
|
688
|
+
>
|
|
689
|
+
Next
|
|
690
|
+
</Button>}
|
|
691
|
+
|
|
692
|
+
{isNewCollection && currentView === "import_data_preview" &&
|
|
693
|
+
<Button
|
|
694
|
+
variant={"filled"}
|
|
695
|
+
color="primary"
|
|
696
|
+
onClick={() => {
|
|
697
|
+
setNextMode();
|
|
698
|
+
}}
|
|
699
|
+
>
|
|
700
|
+
Next
|
|
701
|
+
</Button>}
|
|
702
|
+
|
|
703
|
+
{isNewCollection && (currentView === "details" || currentView === "properties") &&
|
|
704
|
+
<LoadingButton
|
|
705
|
+
variant={"filled"}
|
|
706
|
+
color="primary"
|
|
707
|
+
type="submit"
|
|
708
|
+
loading={isSubmitting}
|
|
709
|
+
disabled={isSubmitting || (currentView === "details" && !validValues)}
|
|
710
|
+
startIcon={currentView === "properties"
|
|
711
|
+
? <DoneIcon/>
|
|
712
|
+
: undefined}
|
|
713
|
+
>
|
|
714
|
+
{currentView === "details" && "Next"}
|
|
715
|
+
{currentView === "properties" && "Create collection"}
|
|
716
|
+
</LoadingButton>}
|
|
717
|
+
|
|
718
|
+
{!isNewCollection && <LoadingButton
|
|
719
|
+
variant="filled"
|
|
720
|
+
color="primary"
|
|
721
|
+
type="submit"
|
|
722
|
+
loading={isSubmitting}
|
|
723
|
+
// disabled={isSubmitting || !dirty}
|
|
724
|
+
>
|
|
725
|
+
Update collection
|
|
726
|
+
</LoadingButton>}
|
|
727
|
+
|
|
728
|
+
</DialogActions>}
|
|
729
|
+
</form>
|
|
730
|
+
</>
|
|
731
|
+
|
|
732
|
+
</Formex>
|
|
466
733
|
|
|
467
|
-
const onImportMappingComplete = () => {
|
|
468
|
-
const updatedProperties = { ...values.properties };
|
|
469
|
-
if (importConfig.idColumn)
|
|
470
|
-
delete updatedProperties[importConfig.idColumn];
|
|
471
|
-
setFieldValue("properties", updatedProperties);
|
|
472
|
-
// setFieldValue("propertiesOrder", Object.values(importConfig.headersMapping));
|
|
473
|
-
setNextMode();
|
|
474
|
-
};
|
|
475
|
-
|
|
476
|
-
const editable = collection?.editable === undefined || collection?.editable === true;
|
|
477
|
-
const collectionEditable = editable || isNewCollection;
|
|
478
|
-
return (
|
|
479
|
-
<>
|
|
480
|
-
{!isNewCollection && <Tabs value={currentView}
|
|
481
|
-
className={cn(defaultBorderMixin, "justify-end bg-gray-50 dark:bg-gray-950 border-b")}
|
|
482
|
-
onValueChange={(v) => setCurrentView(v as EditorView)}>
|
|
483
|
-
<Tab value={"details"}>
|
|
484
|
-
Details
|
|
485
|
-
</Tab>
|
|
486
|
-
<Tab value={"properties"}>
|
|
487
|
-
Properties
|
|
488
|
-
</Tab>
|
|
489
|
-
<Tab value={"subcollections"}>
|
|
490
|
-
Additional views
|
|
491
|
-
</Tab>
|
|
492
|
-
</Tabs>}
|
|
493
|
-
|
|
494
|
-
<Form noValidate
|
|
495
|
-
className={cn(
|
|
496
|
-
isNewCollection ? "h-full" : "h-[calc(100%-48px)]",
|
|
497
|
-
"flex-grow flex flex-col relative")}>
|
|
498
|
-
|
|
499
|
-
{currentView === "loading" &&
|
|
500
|
-
<CircularProgressCenter/>}
|
|
501
|
-
|
|
502
|
-
{currentView === "extra_view" &&
|
|
503
|
-
path &&
|
|
504
|
-
extraView?.View &&
|
|
505
|
-
<extraView.View path={path}/>}
|
|
506
|
-
|
|
507
|
-
{currentView === "welcome" &&
|
|
508
|
-
<CollectionEditorWelcomeView
|
|
509
|
-
path={path}
|
|
510
|
-
onContinue={(data) => {
|
|
511
|
-
if (data) {
|
|
512
|
-
onImportDataSet(data);
|
|
513
|
-
setCurrentView("import_data_mapping");
|
|
514
|
-
} else {
|
|
515
|
-
setCurrentView("details");
|
|
516
|
-
}
|
|
517
|
-
}}
|
|
518
|
-
collections={collections}
|
|
519
|
-
parentCollection={parentCollection}
|
|
520
|
-
pathSuggestions={pathSuggestions}/>}
|
|
521
|
-
|
|
522
|
-
{currentView === "import_data_mapping" && importConfig &&
|
|
523
|
-
<CollectionEditorImportMapping importConfig={importConfig}
|
|
524
|
-
collectionEditable={collectionEditable}
|
|
525
|
-
propertyConfigs={propertyConfigs}/>}
|
|
526
|
-
|
|
527
|
-
{currentView === "import_data_preview" && importConfig &&
|
|
528
|
-
<CollectionEditorImportDataPreview importConfig={importConfig}
|
|
529
|
-
properties={values.properties as Properties}
|
|
530
|
-
propertiesOrder={values.propertiesOrder as string[]}/>}
|
|
531
|
-
|
|
532
|
-
{currentView === "import_data_saving" && importConfig &&
|
|
533
|
-
<ImportSaveInProgress importConfig={importConfig}
|
|
534
|
-
collection={values}
|
|
535
|
-
onImportSuccess={(importedCollection) => {
|
|
536
|
-
handleClose(importedCollection);
|
|
537
|
-
snackbarController.open({
|
|
538
|
-
type: "info",
|
|
539
|
-
message: "Data imported successfully"
|
|
540
|
-
});
|
|
541
|
-
}}
|
|
542
|
-
/>}
|
|
543
|
-
|
|
544
|
-
{currentView === "details" &&
|
|
545
|
-
<CollectionDetailsForm
|
|
546
|
-
existingPaths={existingPaths}
|
|
547
|
-
existingIds={existingIds}
|
|
548
|
-
groups={groups}
|
|
549
|
-
parentCollectionIds={parentCollectionIds}
|
|
550
|
-
parentCollection={parentCollection}
|
|
551
|
-
isNewCollection={isNewCollection}/>}
|
|
552
|
-
|
|
553
|
-
{currentView === "subcollections" && collection &&
|
|
554
|
-
<SubcollectionsEditTab
|
|
555
|
-
parentCollection={parentCollection}
|
|
556
|
-
configController={configController}
|
|
557
|
-
getUser={getUser}
|
|
558
|
-
collectionInference={collectionInference}
|
|
559
|
-
parentCollectionIds={parentCollectionIds}
|
|
560
|
-
collection={collection}/>}
|
|
561
|
-
|
|
562
|
-
{currentView === "properties" &&
|
|
563
|
-
<CollectionPropertiesEditorForm
|
|
564
|
-
showErrors={submitCount > 0}
|
|
565
|
-
isNewCollection={isNewCollection}
|
|
566
|
-
reservedGroups={reservedGroups}
|
|
567
|
-
onPropertyError={(propertyKey, namespace, error) => {
|
|
568
|
-
propertyErrorsRef.current = removeUndefined({
|
|
569
|
-
...propertyErrorsRef.current,
|
|
570
|
-
[propertyKey]: error
|
|
571
|
-
}, true);
|
|
572
|
-
}}
|
|
573
|
-
getUser={getUser}
|
|
574
|
-
getData={getDataWithPath}
|
|
575
|
-
doCollectionInference={doCollectionInference}
|
|
576
|
-
propertyConfigs={propertyConfigs}
|
|
577
|
-
collectionEditable={collectionEditable}
|
|
578
|
-
extraIcon={extraView?.icon &&
|
|
579
|
-
<IconButton
|
|
580
|
-
color={"primary"}
|
|
581
|
-
onClick={() => setCurrentView("extra_view")}>
|
|
582
|
-
{extraView.icon}
|
|
583
|
-
</IconButton>}/>
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
{currentView !== "welcome" && <DialogActions
|
|
587
|
-
position={"absolute"}>
|
|
588
|
-
{error && <ErrorView error={error}/>}
|
|
589
|
-
|
|
590
|
-
{isNewCollection && includeTemplates && currentView === "import_data_mapping" &&
|
|
591
|
-
<Button variant={"text"}
|
|
592
|
-
type="button"
|
|
593
|
-
onClick={() => {
|
|
594
|
-
importConfig.setInUse(false);
|
|
595
|
-
return setCurrentView("welcome");
|
|
596
|
-
}}>
|
|
597
|
-
<ArrowBackIcon/>
|
|
598
|
-
Back
|
|
599
|
-
</Button>}
|
|
600
|
-
|
|
601
|
-
{isNewCollection && includeTemplates && currentView === "import_data_preview" &&
|
|
602
|
-
<Button variant={"text"}
|
|
603
|
-
type="button"
|
|
604
|
-
onClick={() => {
|
|
605
|
-
saveCollection(values);
|
|
606
|
-
setCurrentView("import_data_mapping");
|
|
607
|
-
}}>
|
|
608
|
-
<ArrowBackIcon/>
|
|
609
|
-
Back
|
|
610
|
-
</Button>}
|
|
611
|
-
|
|
612
|
-
{isNewCollection && includeTemplates && currentView === "details" &&
|
|
613
|
-
<Button variant={"text"}
|
|
614
|
-
type="button"
|
|
615
|
-
onClick={() => setCurrentView("welcome")}>
|
|
616
|
-
<ArrowBackIcon/>
|
|
617
|
-
Back
|
|
618
|
-
</Button>}
|
|
619
|
-
|
|
620
|
-
{isNewCollection && currentView === "properties" && <Button variant={"text"}
|
|
621
|
-
type="button"
|
|
622
|
-
onClick={() => setCurrentView("details")}>
|
|
623
|
-
<ArrowBackIcon/>
|
|
624
|
-
Back
|
|
625
|
-
</Button>}
|
|
626
|
-
|
|
627
|
-
<Button variant={"text"}
|
|
628
|
-
onClick={() => {
|
|
629
|
-
handleCancel();
|
|
630
|
-
}}>
|
|
631
|
-
Cancel
|
|
632
|
-
</Button>
|
|
633
|
-
|
|
634
|
-
{isNewCollection && currentView === "import_data_mapping" &&
|
|
635
|
-
<Button
|
|
636
|
-
variant={"filled"}
|
|
637
|
-
color="primary"
|
|
638
|
-
onClick={onImportMappingComplete}
|
|
639
|
-
>
|
|
640
|
-
Next
|
|
641
|
-
</Button>}
|
|
642
|
-
|
|
643
|
-
{isNewCollection && currentView === "import_data_preview" &&
|
|
644
|
-
<Button
|
|
645
|
-
variant={"filled"}
|
|
646
|
-
color="primary"
|
|
647
|
-
onClick={() => {
|
|
648
|
-
setNextMode();
|
|
649
|
-
}}
|
|
650
|
-
>
|
|
651
|
-
Next
|
|
652
|
-
</Button>}
|
|
653
|
-
|
|
654
|
-
{isNewCollection && (currentView === "details" || currentView === "properties") &&
|
|
655
|
-
<LoadingButton
|
|
656
|
-
variant={"filled"}
|
|
657
|
-
color="primary"
|
|
658
|
-
type="submit"
|
|
659
|
-
loading={isSubmitting}
|
|
660
|
-
disabled={isSubmitting || (currentView === "details" && !validValues)}
|
|
661
|
-
startIcon={currentView === "properties"
|
|
662
|
-
? <DoneIcon/>
|
|
663
|
-
: undefined}
|
|
664
|
-
>
|
|
665
|
-
{currentView === "details" && "Next"}
|
|
666
|
-
{currentView === "properties" && "Create collection"}
|
|
667
|
-
</LoadingButton>}
|
|
668
|
-
|
|
669
|
-
{!isNewCollection && <LoadingButton
|
|
670
|
-
variant="filled"
|
|
671
|
-
color="primary"
|
|
672
|
-
type="submit"
|
|
673
|
-
loading={isSubmitting}
|
|
674
|
-
// disabled={isSubmitting || !dirty}
|
|
675
|
-
>
|
|
676
|
-
Update collection
|
|
677
|
-
</LoadingButton>}
|
|
678
|
-
|
|
679
|
-
</DialogActions>}
|
|
680
|
-
</Form>
|
|
681
|
-
</>
|
|
682
|
-
);
|
|
683
|
-
}}
|
|
684
|
-
|
|
685
|
-
</Formik>
|
|
686
734
|
</DialogContent>
|
|
687
735
|
|
|
688
736
|
}
|