@firecms/collection_editor 3.0.1 → 3.1.0-canary.768c91f

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 +6 -0
  2. package/dist/api/generateCollectionApi.d.ts +71 -0
  3. package/dist/api/index.d.ts +1 -0
  4. package/dist/index.d.ts +5 -1
  5. package/dist/index.es.js +9466 -5588
  6. package/dist/index.es.js.map +1 -1
  7. package/dist/index.umd.js +9461 -5583
  8. package/dist/index.umd.js.map +1 -1
  9. package/dist/types/collection_editor_controller.d.ts +14 -0
  10. package/dist/types/collection_inference.d.ts +8 -2
  11. package/dist/types/config_controller.d.ts +23 -2
  12. package/dist/ui/AddKanbanColumnAction.d.ts +11 -0
  13. package/dist/ui/KanbanSetupAction.d.ts +10 -0
  14. package/dist/ui/collection_editor/AICollectionGeneratorPopover.d.ts +37 -0
  15. package/dist/ui/collection_editor/AIModifiedPathsContext.d.ts +20 -0
  16. package/dist/ui/collection_editor/CollectionDetailsForm.d.ts +2 -3
  17. package/dist/ui/collection_editor/CollectionEditorDialog.d.ts +24 -0
  18. package/dist/ui/collection_editor/CollectionEditorWelcomeView.d.ts +4 -1
  19. package/dist/ui/collection_editor/CollectionJsonImportDialog.d.ts +7 -0
  20. package/dist/ui/collection_editor/CollectionYupValidation.d.ts +9 -13
  21. package/dist/ui/collection_editor/DisplaySettingsForm.d.ts +3 -0
  22. package/dist/ui/collection_editor/EntityActionsEditTab.d.ts +2 -1
  23. package/dist/ui/collection_editor/ExtendSettingsForm.d.ts +14 -0
  24. package/dist/ui/collection_editor/GeneralSettingsForm.d.ts +7 -0
  25. package/dist/ui/collection_editor/KanbanConfigSection.d.ts +4 -0
  26. package/dist/ui/collection_editor/PropertyEditView.d.ts +6 -1
  27. package/dist/ui/collection_editor/PropertyTree.d.ts +2 -1
  28. package/dist/ui/collection_editor/SubcollectionsEditTab.d.ts +2 -1
  29. package/dist/ui/collection_editor/ViewModeSwitch.d.ts +6 -0
  30. package/dist/ui/collection_editor/properties/EnumPropertyField.d.ts +2 -1
  31. package/dist/ui/collection_editor/properties/conditions/ConditionsEditor.d.ts +10 -0
  32. package/dist/ui/collection_editor/properties/conditions/ConditionsPanel.d.ts +2 -0
  33. package/dist/ui/collection_editor/properties/conditions/EnumConditionsEditor.d.ts +6 -0
  34. package/dist/ui/collection_editor/properties/conditions/index.d.ts +6 -0
  35. package/dist/ui/collection_editor/properties/conditions/property_paths.d.ts +19 -0
  36. package/dist/useCollectionEditorPlugin.d.ts +7 -1
  37. package/dist/utils/validateCollectionJson.d.ts +22 -0
  38. package/package.json +15 -15
  39. package/src/ConfigControllerProvider.tsx +82 -47
  40. package/src/api/generateCollectionApi.ts +119 -0
  41. package/src/api/index.ts +1 -0
  42. package/src/index.ts +28 -1
  43. package/src/types/collection_editor_controller.tsx +16 -3
  44. package/src/types/collection_inference.ts +15 -2
  45. package/src/types/config_controller.tsx +27 -2
  46. package/src/ui/AddKanbanColumnAction.tsx +203 -0
  47. package/src/ui/EditorCollectionActionStart.tsx +1 -2
  48. package/src/ui/HomePageEditorCollectionAction.tsx +41 -13
  49. package/src/ui/KanbanSetupAction.tsx +38 -0
  50. package/src/ui/MissingReferenceWidget.tsx +1 -1
  51. package/src/ui/NewCollectionButton.tsx +1 -1
  52. package/src/ui/PropertyAddColumnComponent.tsx +1 -1
  53. package/src/ui/collection_editor/AICollectionGeneratorPopover.tsx +242 -0
  54. package/src/ui/collection_editor/AIModifiedPathsContext.tsx +88 -0
  55. package/src/ui/collection_editor/CollectionDetailsForm.tsx +212 -259
  56. package/src/ui/collection_editor/CollectionEditorDialog.tsx +237 -169
  57. package/src/ui/collection_editor/CollectionEditorWelcomeView.tsx +133 -67
  58. package/src/ui/collection_editor/CollectionJsonImportDialog.tsx +171 -0
  59. package/src/ui/collection_editor/CollectionPropertiesEditorForm.tsx +190 -91
  60. package/src/ui/collection_editor/DisplaySettingsForm.tsx +333 -0
  61. package/src/ui/collection_editor/EntityActionsEditTab.tsx +106 -96
  62. package/src/ui/collection_editor/EntityActionsSelectDialog.tsx +6 -7
  63. package/src/ui/collection_editor/EntityCustomViewsSelectDialog.tsx +1 -3
  64. package/src/ui/collection_editor/EnumForm.tsx +147 -100
  65. package/src/ui/collection_editor/ExtendSettingsForm.tsx +93 -0
  66. package/src/ui/collection_editor/GeneralSettingsForm.tsx +337 -0
  67. package/src/ui/collection_editor/GetCodeDialog.tsx +57 -36
  68. package/src/ui/collection_editor/KanbanConfigSection.tsx +207 -0
  69. package/src/ui/collection_editor/LayoutModeSwitch.tsx +22 -41
  70. package/src/ui/collection_editor/PropertyEditView.tsx +206 -142
  71. package/src/ui/collection_editor/PropertyFieldPreview.tsx +1 -1
  72. package/src/ui/collection_editor/PropertyTree.tsx +130 -58
  73. package/src/ui/collection_editor/SubcollectionsEditTab.tsx +171 -162
  74. package/src/ui/collection_editor/UnsavedChangesDialog.tsx +0 -2
  75. package/src/ui/collection_editor/ViewModeSwitch.tsx +41 -0
  76. package/src/ui/collection_editor/properties/BlockPropertyField.tsx +0 -2
  77. package/src/ui/collection_editor/properties/BooleanPropertyField.tsx +1 -0
  78. package/src/ui/collection_editor/properties/DateTimePropertyField.tsx +117 -35
  79. package/src/ui/collection_editor/properties/EnumPropertyField.tsx +28 -21
  80. package/src/ui/collection_editor/properties/MapPropertyField.tsx +0 -2
  81. package/src/ui/collection_editor/properties/MarkdownPropertyField.tsx +115 -39
  82. package/src/ui/collection_editor/properties/StoragePropertyField.tsx +1 -1
  83. package/src/ui/collection_editor/properties/conditions/ConditionsEditor.tsx +861 -0
  84. package/src/ui/collection_editor/properties/conditions/ConditionsPanel.tsx +28 -0
  85. package/src/ui/collection_editor/properties/conditions/EnumConditionsEditor.tsx +599 -0
  86. package/src/ui/collection_editor/properties/conditions/index.ts +6 -0
  87. package/src/ui/collection_editor/properties/conditions/property_paths.ts +92 -0
  88. package/src/ui/collection_editor/properties/validation/ValidationPanel.tsx +1 -1
  89. package/src/useCollectionEditorPlugin.tsx +32 -17
  90. package/src/utils/validateCollectionJson.ts +380 -0
@@ -1,6 +1,7 @@
1
- import React from "react";
2
- import { EntityCollection, prettifyIdentifier, } from "@firecms/core";
3
- import { Card, Chip, cls, Container, Icon, Tooltip, Typography, } from "@firecms/ui";
1
+ import React, { useState } from "react";
2
+ import { AIIcon, EntityCollection, prettifyIdentifier, } from "@firecms/core";
3
+ import { Button, Card, Chip, cls, CodeIcon, Container, Icon, Tooltip, Typography, } from "@firecms/ui";
4
+ import { CollectionJsonImportDialog } from "./CollectionJsonImportDialog";
4
5
 
5
6
  import { productsCollectionTemplate } from "./templates/products_template";
6
7
  import { blogCollectionTemplate } from "./templates/blog_template";
@@ -9,17 +10,23 @@ import { ImportFileUpload } from "@firecms/data_import";
9
10
  import { pagesCollectionTemplate } from "./templates/pages_template";
10
11
  import { useFormex } from "@firecms/formex";
11
12
  import { useCollectionEditorController } from "../../useCollectionEditorController";
13
+ import { AICollectionGeneratorPopover } from "./AICollectionGeneratorPopover";
14
+ import { CollectionGenerationCallback } from "../../api/generateCollectionApi";
12
15
 
13
16
  export function CollectionEditorWelcomeView({
14
- path,
15
- parentCollection,
16
- onContinue,
17
- existingCollectionPaths
18
- }: {
17
+ path,
18
+ parentCollection,
19
+ onContinue,
20
+ existingCollectionPaths,
21
+ generateCollection,
22
+ onAnalyticsEvent
23
+ }: {
19
24
  path: string;
20
25
  parentCollection?: EntityCollection;
21
26
  onContinue: (importData?: object[], propertiesOrder?: string[]) => void;
22
27
  existingCollectionPaths?: string[];
28
+ generateCollection?: CollectionGenerationCallback;
29
+ onAnalyticsEvent?: (event: string, params?: object) => void;
23
30
  }) {
24
31
 
25
32
  const { pathSuggestions } = useCollectionEditorController();
@@ -33,6 +40,8 @@ export function CollectionEditorWelcomeView({
33
40
  submitCount
34
41
  } = useFormex<EntityCollection>();
35
42
 
43
+ const [jsonImportOpen, setJsonImportOpen] = useState(false);
44
+
36
45
  return (
37
46
  <div className={"overflow-auto my-auto"}>
38
47
  <Container maxWidth={"4xl"} className={"flex flex-col gap-4 p-8 m-auto"}>
@@ -53,22 +62,22 @@ export function CollectionEditorWelcomeView({
53
62
  {(filteredSuggestions ?? []).length > 0 && <div className={"my-2"}>
54
63
 
55
64
  <Typography variant={"caption"}
56
- color={"secondary"}>
65
+ color={"secondary"}>
57
66
  ● Use one of the existing paths in your database:
58
67
  </Typography>
59
68
  <div className={"flex flex-wrap gap-x-2 gap-y-1 items-center my-2 min-h-7"}>
60
69
 
61
70
  {filteredSuggestions?.map((suggestion, index) => (
62
71
  <Chip key={suggestion}
63
- colorScheme={"cyanLighter"}
64
- onClick={() => {
65
- setFieldValue("name", prettifyIdentifier(suggestion));
66
- setFieldValue("id", suggestion);
67
- setFieldValue("path", suggestion);
68
- setFieldValue("properties", undefined);
69
- onContinue();
70
- }}
71
- size="small">
72
+ colorScheme={"cyanLighter"}
73
+ onClick={() => {
74
+ setFieldValue("name", prettifyIdentifier(suggestion));
75
+ setFieldValue("id", suggestion);
76
+ setFieldValue("path", suggestion);
77
+ setFieldValue("properties", undefined);
78
+ onContinue();
79
+ }}
80
+ size="small">
72
81
  {suggestion}
73
82
  </Chip>
74
83
  ))}
@@ -76,61 +85,118 @@ export function CollectionEditorWelcomeView({
76
85
  </div>
77
86
 
78
87
  </div>}
88
+ <div className="flex flex-row gap-8">
79
89
 
80
- <div className={"my-2"}>
81
- <Typography variant={"caption"}
82
- color={"secondary"}>
83
- ● Select a template:
84
- </Typography>
85
-
86
- <div className={"flex gap-4"}>
87
- <TemplateButton title={"Products"}
88
- subtitle={"A collection of products with images, prices and stock"}
89
- icon={<Icon size={"small"}
90
- iconKey={productsCollectionTemplate.icon! as string}/>}
91
- onClick={() => {
92
- setValues(productsCollectionTemplate);
93
- onContinue();
94
- }}/>
95
- <TemplateButton title={"Users"}
96
- subtitle={"A collection of users with emails, names and roles"}
97
- icon={<Icon size={"small"} iconKey={usersCollectionTemplate.icon! as string}/>}
98
- onClick={() => {
99
- setValues(usersCollectionTemplate);
100
- onContinue();
101
- }}/>
102
- <TemplateButton title={"Blog posts"}
103
- subtitle={"A collection of blog posts with images, authors and complex content"}
104
- icon={<Icon size={"small"} iconKey={blogCollectionTemplate.icon! as string}/>}
105
- onClick={() => {
106
- setValues(blogCollectionTemplate);
107
- onContinue();
108
- }}/>
109
- <TemplateButton title={"Pages"}
110
- subtitle={"A collection of pages with images, authors and complex content"}
111
- icon={<Icon size={"small"} iconKey={pagesCollectionTemplate.icon! as string}/>}
112
- onClick={() => {
113
- setValues(pagesCollectionTemplate);
114
- onContinue();
115
- }}/>
90
+ {generateCollection && (
91
+ <div className={"my-2"}>
92
+ <Typography variant={"caption"}
93
+ color={"secondary"}
94
+ className={"mb-2"}>
95
+ ● Describe your collection to AI:
96
+ </Typography>
97
+
98
+ <AICollectionGeneratorPopover
99
+ onGenerated={(generatedCollection) => {
100
+ setValues(generatedCollection);
101
+ onContinue();
102
+ }}
103
+ generateCollection={generateCollection}
104
+ onAnalyticsEvent={onAnalyticsEvent}
105
+ trigger={
106
+ <Button
107
+ variant="outlined"
108
+ startIcon={<AIIcon size="small" />}
109
+ >
110
+ Generate with AI
111
+ </Button>
112
+ }
113
+ />
114
+ </div>
115
+ )}
116
+
117
+ <div className={"my-2"}>
118
+ <Typography variant={"caption"}
119
+ color={"secondary"}
120
+ className={"mb-2"}>
121
+ Create from JSON configuration:
122
+ </Typography>
123
+
124
+ <Button
125
+ variant={"outlined"}
126
+ onClick={() => setJsonImportOpen(true)}
127
+ startIcon={<CodeIcon size="small" />}
128
+ >
129
+ Paste JSON Configuration
130
+ </Button>
131
+
132
+ <CollectionJsonImportDialog
133
+ open={jsonImportOpen}
134
+ onClose={() => setJsonImportOpen(false)}
135
+ onImport={(collection) => {
136
+ setValues(collection);
137
+ onContinue();
138
+ }}
139
+ />
116
140
  </div>
117
141
 
142
+
143
+
118
144
  </div>
119
145
 
146
+
120
147
  {!parentCollection && <div>
121
148
 
122
149
  <Typography variant={"caption"}
123
- color={"secondary"}
124
- className={"mb-2"}>
150
+ color={"secondary"}
151
+ className={"mb-2"}>
125
152
  ● Create a collection from a file (csv, json, xls, xslx...)
126
153
  </Typography>
127
154
 
128
- <ImportFileUpload onDataAdded={(data, propertiesOrder) => onContinue(data, propertiesOrder)}/>
155
+ <ImportFileUpload onDataAdded={(data, propertiesOrder) => onContinue(data, propertiesOrder)} />
129
156
 
130
157
  </div>}
131
158
 
159
+ <div className={"my-2"}>
160
+ <Typography variant={"caption"}
161
+ color={"secondary"}>
162
+ ● Select a template:
163
+ </Typography>
164
+
165
+ <div className={"flex gap-2"}>
166
+ <TemplateButton title={"Products"}
167
+ subtitle={"A collection of products with images, prices and stock"}
168
+ icon={<Icon size={"small"}
169
+ iconKey={productsCollectionTemplate.icon! as string} />}
170
+ onClick={() => {
171
+ setValues(productsCollectionTemplate);
172
+ onContinue();
173
+ }} />
174
+ <TemplateButton title={"Users"}
175
+ subtitle={"A collection of users with emails, names and roles"}
176
+ icon={<Icon size={"small"} iconKey={usersCollectionTemplate.icon! as string} />}
177
+ onClick={() => {
178
+ setValues(usersCollectionTemplate);
179
+ onContinue();
180
+ }} />
181
+ <TemplateButton title={"Blog posts"}
182
+ subtitle={"A collection of blog posts with images, authors and complex content"}
183
+ icon={<Icon size={"small"} iconKey={blogCollectionTemplate.icon! as string} />}
184
+ onClick={() => {
185
+ setValues(blogCollectionTemplate);
186
+ onContinue();
187
+ }} />
188
+ <TemplateButton title={"Pages"}
189
+ subtitle={"A collection of pages with images, authors and complex content"}
190
+ icon={<Icon size={"small"} iconKey={pagesCollectionTemplate.icon! as string} />}
191
+ onClick={() => {
192
+ setValues(pagesCollectionTemplate);
193
+ onContinue();
194
+ }} />
195
+ </div>
196
+
197
+ </div>
198
+
132
199
 
133
- {/*<div style={{ height: "52px" }}/>*/}
134
200
 
135
201
  </Container>
136
202
  </div>
@@ -138,11 +204,11 @@ export function CollectionEditorWelcomeView({
138
204
  }
139
205
 
140
206
  export function TemplateButton({
141
- title,
142
- subtitle,
143
- icon,
144
- onClick
145
- }: {
207
+ title,
208
+ subtitle,
209
+ icon,
210
+ onClick
211
+ }: {
146
212
  title: string,
147
213
  icon: React.ReactNode,
148
214
  subtitle: string,
@@ -151,12 +217,12 @@ export function TemplateButton({
151
217
 
152
218
  return (
153
219
  <Tooltip title={subtitle}
154
- asChild={true}>
220
+ asChild={true}>
155
221
  <Card
156
222
  onClick={onClick}
157
223
  className={cls(
158
- "my-2 rounded-md border mx-0 p-6 px-4 focus:outline-none transition ease-in-out duration-150 flex flex-row gap-4 items-center",
159
- "text-surface-700 dark:text-surface-accent-300",
224
+ "my-2 rounded-md border px-4 py-3 focus:outline-none transition ease-in-out duration-150 flex flex-row gap-4 items-center",
225
+ "text-text-secondary dark:text-text-secondary-dark",
160
226
  "hover:border-primary-dark hover:text-primary-dark dark:hover:text-primary focus:ring-primary hover:ring-1 hover:ring-primary",
161
227
  "border-surface-400 dark:border-surface-600 "
162
228
  )}
@@ -164,7 +230,7 @@ export function TemplateButton({
164
230
  {icon}
165
231
  <div className={"flex flex-col items-start"}>
166
232
 
167
- <Typography variant={"subtitle1"}>
233
+ <Typography variant={"subtitle2"}>
168
234
  {title}
169
235
  </Typography>
170
236
 
@@ -0,0 +1,171 @@
1
+ import React, { useCallback, useState } from "react";
2
+ import {
3
+ Button,
4
+ cls,
5
+ CodeIcon,
6
+ Dialog,
7
+ DialogActions,
8
+ DialogContent,
9
+ DialogTitle,
10
+ Typography
11
+ } from "@firecms/ui";
12
+ import { EntityCollection } from "@firecms/core";
13
+ import { validateCollectionJson, CollectionValidationError } from "../../utils/validateCollectionJson";
14
+
15
+ const EXAMPLE_JSON = `{
16
+ "id": "products",
17
+ "name": "Products",
18
+ "path": "products",
19
+ "icon": "shopping_cart",
20
+ "properties": {
21
+ "name": {
22
+ "dataType": "string",
23
+ "name": "Name",
24
+ "validation": { "required": true }
25
+ },
26
+ "price": {
27
+ "dataType": "number",
28
+ "name": "Price"
29
+ },
30
+ "available": {
31
+ "dataType": "boolean",
32
+ "name": "Available"
33
+ }
34
+ }
35
+ }`;
36
+
37
+ export interface CollectionJsonImportDialogProps {
38
+ open: boolean;
39
+ onClose: () => void;
40
+ onImport: (collection: EntityCollection) => void;
41
+ }
42
+
43
+ export function CollectionJsonImportDialog({
44
+ open,
45
+ onClose,
46
+ onImport
47
+ }: CollectionJsonImportDialogProps) {
48
+ const [jsonValue, setJsonValue] = useState<string>("");
49
+ const [errors, setErrors] = useState<CollectionValidationError[]>([]);
50
+ const [touched, setTouched] = useState(false);
51
+
52
+ const handleJsonChange = useCallback((e: React.ChangeEvent<HTMLTextAreaElement>) => {
53
+ const value = e.target.value;
54
+ setJsonValue(value);
55
+ setTouched(true);
56
+
57
+ if (!value.trim()) {
58
+ setErrors([]);
59
+ return;
60
+ }
61
+
62
+ const result = validateCollectionJson(value);
63
+ setErrors(result.errors);
64
+ }, []);
65
+
66
+ const handleImport = useCallback(() => {
67
+ const result = validateCollectionJson(jsonValue);
68
+ if (result.valid && result.collection) {
69
+ onImport(result.collection);
70
+ setJsonValue("");
71
+ setErrors([]);
72
+ setTouched(false);
73
+ onClose();
74
+ }
75
+ }, [jsonValue, onImport, onClose]);
76
+
77
+ const handleClose = useCallback(() => {
78
+ setJsonValue("");
79
+ setErrors([]);
80
+ setTouched(false);
81
+ onClose();
82
+ }, [onClose]);
83
+
84
+ const isValid = touched && jsonValue.trim() && errors.length === 0;
85
+
86
+ return (
87
+ <Dialog
88
+ open={open}
89
+ onOpenChange={(open) => !open && handleClose()}
90
+ maxWidth="2xl"
91
+ >
92
+ <DialogTitle className="flex items-center gap-2">
93
+ <CodeIcon size="small" />
94
+ Import Collection from JSON
95
+ </DialogTitle>
96
+ <DialogContent className="flex flex-col gap-4">
97
+ <Typography variant="body2" color="secondary">
98
+ Paste a JSON object representing your collection configuration.
99
+ The JSON must include <code className="bg-surface-200 dark:bg-surface-700 px-1 rounded">id</code>,
100
+ <code className="bg-surface-200 dark:bg-surface-700 px-1 rounded">name</code>,
101
+ <code className="bg-surface-200 dark:bg-surface-700 px-1 rounded">path</code>, and
102
+ <code className="bg-surface-200 dark:bg-surface-700 px-1 rounded">properties</code>.
103
+ </Typography>
104
+
105
+ <textarea
106
+ value={jsonValue}
107
+ onChange={handleJsonChange}
108
+ placeholder={EXAMPLE_JSON}
109
+ rows={12}
110
+ className={cls(
111
+ "w-full p-3 font-mono text-sm rounded-md border resize-none overflow-y-auto",
112
+ "bg-surface-50 dark:bg-surface-900",
113
+ "focus:outline-none focus:ring-2 focus:ring-primary",
114
+ "h-[300px]",
115
+ errors.length > 0 && touched
116
+ ? "border-red-500 dark:border-red-400"
117
+ : "border-surface-300 dark:border-surface-600"
118
+ )}
119
+ />
120
+
121
+ {errors.length > 0 && touched && (
122
+ <div className="p-3 bg-red-50 dark:bg-red-900/20 rounded-md border border-red-200 dark:border-red-800">
123
+ <Typography variant="body2" className="font-medium text-red-700 dark:text-red-400 mb-2">
124
+ Validation errors:
125
+ </Typography>
126
+ <ul className="list-disc list-inside space-y-1">
127
+ {errors.map((error, index) => (
128
+ <li key={index} className="text-sm text-red-600 dark:text-red-400">
129
+ {error.path ? (
130
+ <>
131
+ <code className="bg-red-100 dark:bg-red-900/40 px-1 rounded">
132
+ {error.path}
133
+ </code>
134
+ : {error.message}
135
+ </>
136
+ ) : (
137
+ error.message
138
+ )}
139
+ </li>
140
+ ))}
141
+ </ul>
142
+ </div>
143
+ )}
144
+
145
+ {isValid && (
146
+ <div className="p-3 bg-green-50 dark:bg-green-900/20 rounded-md border border-green-200 dark:border-green-800">
147
+ <Typography variant="body2" className="text-green-700 dark:text-green-400">
148
+ ✓ JSON is valid and ready to import
149
+ </Typography>
150
+ </div>
151
+ )}
152
+ </DialogContent>
153
+ <DialogActions>
154
+ <Button
155
+ variant="text"
156
+ onClick={handleClose}
157
+ >
158
+ Cancel
159
+ </Button>
160
+ <Button
161
+ variant="filled"
162
+ color="primary"
163
+ onClick={handleImport}
164
+ disabled={!isValid}
165
+ >
166
+ Import Collection
167
+ </Button>
168
+ </DialogActions>
169
+ </Dialog>
170
+ );
171
+ }