@firecms/collection_editor 3.0.0-canary.99 → 3.0.0-rc.2

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 (79) hide show
  1. package/README.md +165 -1
  2. package/dist/ConfigControllerProvider.d.ts +0 -1
  3. package/dist/index.es.js +9957 -4962
  4. package/dist/index.es.js.map +1 -1
  5. package/dist/index.umd.js +9949 -4958
  6. package/dist/index.umd.js.map +1 -1
  7. package/dist/types/collection_editor_controller.d.ts +0 -1
  8. package/dist/types/collection_inference.d.ts +4 -1
  9. package/dist/types/config_controller.d.ts +3 -1
  10. package/dist/types/config_permissions.d.ts +2 -2
  11. package/dist/types/persisted_collection.d.ts +1 -1
  12. package/dist/ui/EditorEntityAction.d.ts +2 -0
  13. package/dist/ui/collection_editor/CollectionDetailsForm.d.ts +3 -1
  14. package/dist/ui/collection_editor/CollectionEditorWelcomeView.d.ts +1 -1
  15. package/dist/ui/collection_editor/CollectionPropertiesEditorForm.d.ts +1 -1
  16. package/dist/ui/collection_editor/EntityActionsEditTab.d.ts +4 -0
  17. package/dist/ui/collection_editor/EntityActionsSelectDialog.d.ts +4 -0
  18. package/dist/ui/collection_editor/LayoutModeSwitch.d.ts +5 -0
  19. package/dist/ui/collection_editor/PropertyEditView.d.ts +8 -0
  20. package/dist/ui/collection_editor/PropertyTree.d.ts +2 -3
  21. package/dist/ui/collection_editor/import/CollectionEditorImportDataPreview.d.ts +1 -1
  22. package/dist/ui/collection_editor/import/CollectionEditorImportMapping.d.ts +8 -1
  23. package/dist/ui/collection_editor/import/clean_import_data.d.ts +1 -1
  24. package/dist/ui/collection_editor/properties/MarkdownPropertyField.d.ts +4 -0
  25. package/dist/ui/collection_editor/properties/ReferencePropertyField.d.ts +2 -1
  26. package/dist/ui/collection_editor/properties/StringPropertyField.d.ts +1 -1
  27. package/dist/useCollectionEditorPlugin.d.ts +6 -6
  28. package/dist/utils/collections.d.ts +1 -1
  29. package/package.json +25 -23
  30. package/src/ConfigControllerProvider.tsx +3 -8
  31. package/src/types/collection_editor_controller.tsx +1 -2
  32. package/src/types/collection_inference.ts +4 -1
  33. package/src/types/config_controller.tsx +4 -1
  34. package/src/types/config_permissions.ts +1 -1
  35. package/src/types/persisted_collection.ts +2 -3
  36. package/src/ui/CollectionViewHeaderAction.tsx +4 -2
  37. package/src/ui/EditorCollectionAction.tsx +3 -7
  38. package/src/ui/EditorCollectionActionStart.tsx +1 -1
  39. package/src/ui/EditorEntityAction.tsx +51 -0
  40. package/src/ui/HomePageEditorCollectionAction.tsx +5 -3
  41. package/src/ui/NewCollectionButton.tsx +1 -1
  42. package/src/ui/PropertyAddColumnComponent.tsx +5 -3
  43. package/src/ui/collection_editor/CollectionDetailsForm.tsx +126 -49
  44. package/src/ui/collection_editor/CollectionEditorDialog.tsx +71 -16
  45. package/src/ui/collection_editor/CollectionEditorWelcomeView.tsx +20 -29
  46. package/src/ui/collection_editor/CollectionPropertiesEditorForm.tsx +19 -17
  47. package/src/ui/collection_editor/EntityActionsEditTab.tsx +163 -0
  48. package/src/ui/collection_editor/EntityActionsSelectDialog.tsx +41 -0
  49. package/src/ui/collection_editor/EntityCustomViewsSelectDialog.tsx +11 -7
  50. package/src/ui/collection_editor/EnumForm.tsx +11 -7
  51. package/src/ui/collection_editor/GetCodeDialog.tsx +46 -26
  52. package/src/ui/collection_editor/LayoutModeSwitch.tsx +54 -0
  53. package/src/ui/collection_editor/PropertyEditView.tsx +263 -76
  54. package/src/ui/collection_editor/PropertyFieldPreview.tsx +7 -6
  55. package/src/ui/collection_editor/PropertyTree.tsx +184 -138
  56. package/src/ui/collection_editor/SubcollectionsEditTab.tsx +24 -17
  57. package/src/ui/collection_editor/UnsavedChangesDialog.tsx +9 -7
  58. package/src/ui/collection_editor/import/CollectionEditorImportDataPreview.tsx +20 -4
  59. package/src/ui/collection_editor/import/CollectionEditorImportMapping.tsx +34 -3
  60. package/src/ui/collection_editor/import/clean_import_data.ts +1 -1
  61. package/src/ui/collection_editor/properties/BlockPropertyField.tsx +18 -12
  62. package/src/ui/collection_editor/properties/DateTimePropertyField.tsx +54 -47
  63. package/src/ui/collection_editor/properties/EnumPropertyField.tsx +2 -0
  64. package/src/ui/collection_editor/properties/MapPropertyField.tsx +3 -2
  65. package/src/ui/collection_editor/properties/MarkdownPropertyField.tsx +139 -0
  66. package/src/ui/collection_editor/properties/ReferencePropertyField.tsx +7 -3
  67. package/src/ui/collection_editor/properties/StoragePropertyField.tsx +13 -18
  68. package/src/ui/collection_editor/properties/StringPropertyField.tsx +4 -9
  69. package/src/ui/collection_editor/properties/UrlPropertyField.tsx +1 -0
  70. package/src/ui/collection_editor/properties/advanced/AdvancedPropertyValidation.tsx +2 -0
  71. package/src/ui/collection_editor/properties/validation/ValidationPanel.tsx +2 -2
  72. package/src/ui/collection_editor/templates/pages_template.ts +1 -6
  73. package/src/ui/collection_editor/utils/strings.ts +13 -6
  74. package/src/ui/collection_editor/utils/supported_fields.tsx +2 -0
  75. package/src/ui/collection_editor/utils/update_property_for_widget.ts +37 -6
  76. package/src/useCollectionEditorPlugin.tsx +20 -15
  77. package/src/utils/collections.ts +23 -7
  78. package/dist/ui/collection_editor/PropertySelectItem.d.ts +0 -8
  79. package/src/ui/collection_editor/PropertySelectItem.tsx +0 -32
@@ -5,7 +5,7 @@ import { Button, Card, Chip, CircularProgress, cls, Container, Icon, Tooltip, Ty
5
5
  import { productsCollectionTemplate } from "./templates/products_template";
6
6
  import { blogCollectionTemplate } from "./templates/blog_template";
7
7
  import { usersCollectionTemplate } from "./templates/users_template";
8
- import { ImportFileUpload } from "@firecms/data_import_export";
8
+ import { ImportFileUpload } from "@firecms/data_import";
9
9
  import { pagesCollectionTemplate } from "./templates/pages_template";
10
10
  import { useFormex } from "@firecms/formex";
11
11
 
@@ -37,18 +37,6 @@ export function CollectionEditorWelcomeView({
37
37
  }
38
38
  }, [existingCollectionPaths, path, pathSuggestions]);
39
39
 
40
- // const {
41
- // values,
42
- // setFieldValue,
43
- // setValues,
44
- // handleChange,
45
- // touched,
46
- // errors,
47
- // setFieldTouched,
48
- // isSubmitting,
49
- // submitCount
50
- // } = useFormex<EntityCollection>();
51
-
52
40
  const {
53
41
  values,
54
42
  setFieldValue,
@@ -56,6 +44,11 @@ export function CollectionEditorWelcomeView({
56
44
  submitCount
57
45
  } = useFormex<EntityCollection>();
58
46
 
47
+ const noSuggestions = !loadingPathSuggestions && (filteredPathSuggestions ?? [])?.length === 0;
48
+ if (!noSuggestions) {
49
+ return null;
50
+ }
51
+
59
52
  return (
60
53
  <div className={"overflow-auto my-auto"}>
61
54
  <Container maxWidth={"4xl"} className={"flex flex-col gap-4 p-8 m-auto"}>
@@ -96,12 +89,11 @@ export function CollectionEditorWelcomeView({
96
89
  {suggestion}
97
90
  </Chip>
98
91
  ))}
99
-
100
- {!loadingPathSuggestions && (filteredPathSuggestions ?? [])?.length === 0 &&
101
- <Typography variant={"caption"}>
102
- No suggestions
103
- </Typography>
104
- }
92
+ {(filteredPathSuggestions ?? []).length === 0 && !loadingPathSuggestions && <Typography
93
+ variant={"caption"}
94
+ color={"secondary"}>
95
+ No existing paths found
96
+ </Typography>}
105
97
 
106
98
  </div>
107
99
 
@@ -116,28 +108,29 @@ export function CollectionEditorWelcomeView({
116
108
  <div className={"flex gap-4"}>
117
109
  <TemplateButton title={"Products"}
118
110
  subtitle={"A collection of products with images, prices and stock"}
119
- icon={<Icon size={"small"} iconKey={productsCollectionTemplate.icon!}/>}
111
+ icon={<Icon size={"small"}
112
+ iconKey={productsCollectionTemplate.icon! as string}/>}
120
113
  onClick={() => {
121
114
  setValues(productsCollectionTemplate);
122
115
  onContinue();
123
116
  }}/>
124
117
  <TemplateButton title={"Users"}
125
118
  subtitle={"A collection of users with emails, names and roles"}
126
- icon={<Icon size={"small"} iconKey={usersCollectionTemplate.icon!}/>}
119
+ icon={<Icon size={"small"} iconKey={usersCollectionTemplate.icon! as string}/>}
127
120
  onClick={() => {
128
121
  setValues(usersCollectionTemplate);
129
122
  onContinue();
130
123
  }}/>
131
124
  <TemplateButton title={"Blog posts"}
132
125
  subtitle={"A collection of blog posts with images, authors and complex content"}
133
- icon={<Icon size={"small"} iconKey={blogCollectionTemplate.icon!}/>}
126
+ icon={<Icon size={"small"} iconKey={blogCollectionTemplate.icon! as string}/>}
134
127
  onClick={() => {
135
128
  setValues(blogCollectionTemplate);
136
129
  onContinue();
137
130
  }}/>
138
131
  <TemplateButton title={"Pages"}
139
132
  subtitle={"A collection of pages with images, authors and complex content"}
140
- icon={<Icon size={"small"} iconKey={pagesCollectionTemplate.icon!}/>}
133
+ icon={<Icon size={"small"} iconKey={pagesCollectionTemplate.icon! as string}/>}
141
134
  onClick={() => {
142
135
  setValues(pagesCollectionTemplate);
143
136
  onContinue();
@@ -185,14 +178,15 @@ export function TemplateButton({
185
178
  }) {
186
179
 
187
180
  return (
188
- <Tooltip title={subtitle}>
181
+ <Tooltip title={subtitle}
182
+ asChild={true}>
189
183
  <Card
190
184
  onClick={onClick}
191
185
  className={cls(
192
186
  "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",
193
- "text-gray-700 dark:text-slate-300",
187
+ "text-surface-700 dark:text-surface-accent-300",
194
188
  "hover:border-primary-dark hover:text-primary-dark dark:hover:text-primary focus:ring-primary hover:ring-1 hover:ring-primary",
195
- "border-gray-400 dark:border-gray-600 "
189
+ "border-surface-400 dark:border-surface-600 "
196
190
  )}
197
191
  >
198
192
  {icon}
@@ -201,9 +195,6 @@ export function TemplateButton({
201
195
  <Typography variant={"subtitle1"}>
202
196
  {title}
203
197
  </Typography>
204
- {/*<Typography>*/}
205
- {/* {subtitle}*/}
206
- {/*</Typography>*/}
207
198
 
208
199
  </div>
209
200
  </Card>
@@ -16,7 +16,7 @@ import {
16
16
  } from "@firecms/core";
17
17
  import {
18
18
  AddIcon,
19
- AutoAwesomeIcon,
19
+ AutorenewIcon,
20
20
  Button,
21
21
  CircularProgress,
22
22
  cls,
@@ -24,7 +24,6 @@ import {
24
24
  DebouncedTextField,
25
25
  defaultBorderMixin,
26
26
  IconButton,
27
- Paper,
28
27
  Tooltip,
29
28
  Typography,
30
29
  } from "@firecms/ui";
@@ -45,7 +44,7 @@ type CollectionEditorFormProps = {
45
44
  extraIcon: React.ReactNode;
46
45
  getUser?: (uid: string) => User | null;
47
46
  getData?: () => Promise<object[]>;
48
- doCollectionInference: (collection: PersistedCollection) => Promise<Partial<EntityCollection> | null> | undefined;
47
+ doCollectionInference?: (collection: PersistedCollection) => Promise<Partial<EntityCollection> | null> | undefined;
49
48
  propertyConfigs: Record<string, PropertyConfig>;
50
49
  collectionEditable: boolean;
51
50
  };
@@ -108,6 +107,8 @@ export function CollectionPropertiesEditorForm({
108
107
  return;
109
108
 
110
109
  setInferringProperties(true);
110
+
111
+ console.debug("CollectionEditor: inferring properties from data", doCollectionInference, values);
111
112
  // @ts-ignore
112
113
  doCollectionInference(values)
113
114
  .then((newCollection) => {
@@ -233,12 +234,6 @@ export function CollectionPropertiesEditorForm({
233
234
 
234
235
  // If the id has changed we need to a little cleanup
235
236
  if (previousId && previousId !== id) {
236
- console.debug("onPropertyChanged, id change", {
237
- id,
238
- property,
239
- previousId,
240
- namespace
241
- })
242
237
 
243
238
  const previousFullId = getFullId(previousId, namespace);
244
239
  const previousPropertyPath = idToPropertiesPath(previousFullId);
@@ -316,8 +311,9 @@ export function CollectionPropertiesEditorForm({
316
311
  };
317
312
 
318
313
  const body = (
319
- <div className={"grid grid-cols-12 gap-2 h-full bg-gray-50 dark:bg-gray-900"}>
314
+ <div className={"grid grid-cols-12 gap-2 h-full bg-white dark:bg-surface-950"}>
320
315
  <div className={cls(
316
+ "bg-surface-50 dark:bg-surface-900",
321
317
  "p-4 md:p-8 pb-20 md:pb-20",
322
318
  "col-span-12 lg:col-span-5 h-full overflow-auto",
323
319
  !asDialog && "border-r " + defaultBorderMixin
@@ -351,7 +347,8 @@ export function CollectionPropertiesEditorForm({
351
347
  </div>}
352
348
 
353
349
  <div className="ml-1 mt-2 flex flex-row gap-2">
354
- <Tooltip title={"Get the code for this collection"}>
350
+ <Tooltip title={"Get the code for this collection"}
351
+ asChild={true}>
355
352
  <IconButton
356
353
  variant={"filled"}
357
354
  disabled={inferringProperties}
@@ -359,17 +356,20 @@ export function CollectionPropertiesEditorForm({
359
356
  <CodeIcon/>
360
357
  </IconButton>
361
358
  </Tooltip>
362
- {inferPropertiesFromData && <Tooltip title={"Add new properties based on data"}>
359
+ {inferPropertiesFromData && <Tooltip title={"Add new properties based on data"}
360
+ asChild={true}>
363
361
  <IconButton
364
362
  variant={"filled"}
365
363
  disabled={inferringProperties}
366
364
  onClick={inferPropertiesFromData}>
367
- {inferringProperties ? <CircularProgress size={"small"}/> : <AutoAwesomeIcon/>}
365
+ {inferringProperties ? <CircularProgress size={"small"}/> : <AutorenewIcon/>}
368
366
  </IconButton>
369
367
  </Tooltip>}
370
- <Tooltip title={"Add new property"}>
368
+ <Tooltip title={"Add new property"}
369
+ asChild={true}>
371
370
  <Button
372
371
  variant={"outlined"}
372
+ color={"primary"}
373
373
  onClick={() => setNewPropertyDialogOpen(true)}>
374
374
  <AddIcon/>
375
375
  </Button>
@@ -404,8 +404,8 @@ export function CollectionPropertiesEditorForm({
404
404
 
405
405
  {!asDialog &&
406
406
  <div className={"col-span-12 lg:col-span-7 p-4 md:py-8 md:px-4 h-full overflow-auto pb-20 md:pb-20"}>
407
- <Paper
408
- className="sticky top-8 p-4 min-h-full border border-transparent w-full flex flex-col justify-center ">
407
+ <div
408
+ className="sticky top-8 min-h-full w-full flex flex-col justify-center">
409
409
 
410
410
  {selectedPropertyFullId &&
411
411
  selectedProperty &&
@@ -438,6 +438,7 @@ export function CollectionPropertiesEditorForm({
438
438
  : "Select a property to edit it"}
439
439
  </Typography>
440
440
  <Button variant={"outlined"}
441
+ color={"primary"}
441
442
  onClick={() => setNewPropertyDialogOpen(true)}
442
443
  >
443
444
  <AddIcon/>
@@ -449,7 +450,7 @@ export function CollectionPropertiesEditorForm({
449
450
  <Typography variant={"label"} className="flex items-center justify-center">
450
451
  {"This property is defined as a property builder in code"}
451
452
  </Typography>}
452
- </Paper>
453
+ </div>
453
454
  </div>}
454
455
 
455
456
  {asDialog && <PropertyFormDialog
@@ -471,6 +472,7 @@ export function CollectionPropertiesEditorForm({
471
472
  getData={getData}
472
473
  propertyConfigs={propertyConfigs}
473
474
  collectionEditable={collectionEditable}
475
+ onCancel={closePropertyDialog}
474
476
  onOkClicked={asDialog
475
477
  ? closePropertyDialog
476
478
  : undefined
@@ -0,0 +1,163 @@
1
+ import React from "react";
2
+ import {
3
+ ConfirmationDialog,
4
+ EntityAction,
5
+ EntityCollection,
6
+ resolveEntityAction,
7
+ useCustomizationController
8
+ } from "@firecms/core";
9
+ import {
10
+ AddIcon,
11
+ Alert,
12
+ Button,
13
+ Container,
14
+ DeleteIcon,
15
+ IconButton,
16
+ Paper,
17
+ Table,
18
+ TableBody,
19
+ TableCell,
20
+ TableRow,
21
+ Tooltip,
22
+ Typography,
23
+ } from "@firecms/ui";
24
+ import { PersistedCollection } from "../../types/persisted_collection";
25
+ import { useFormex } from "@firecms/formex";
26
+ import { EntityActionsSelectDialog } from "./EntityActionsSelectDialog";
27
+
28
+ export function EntityActionsEditTab({
29
+ collection,
30
+ }: {
31
+ collection: PersistedCollection,
32
+ }) {
33
+
34
+ const { entityActions: contextEntityActions } = useCustomizationController();
35
+
36
+ const [addEntityActionDialogOpen, setAddEntityActionDialogOpen] = React.useState<boolean>(false);
37
+ const [actionToDelete, setActionToDelete] = React.useState<string | undefined>();
38
+
39
+ const {
40
+ values,
41
+ setFieldValue
42
+ } = useFormex<EntityCollection>();
43
+
44
+ const resolvedEntityActions = values.entityActions?.filter((e): e is string => typeof e === "string")
45
+ .map(e => resolveEntityAction(e, contextEntityActions))
46
+ .filter(Boolean) as EntityAction<any>[] ?? [];
47
+ const hardCodedEntityActions = collection.entityActions?.filter((e): e is EntityAction<any> => typeof e !== "string") ?? [];
48
+ const totalEntityActions = resolvedEntityActions.length + hardCodedEntityActions.length;
49
+
50
+ return (
51
+ <div className={"overflow-auto my-auto"}>
52
+ <Container maxWidth={"2xl"} className={"flex flex-col gap-4 p-8 m-auto"}>
53
+ <div className={"flex flex-col gap-16"}>
54
+ <div className={"flex-grow flex flex-col gap-4 items-start"}>
55
+ <Typography variant={"h5"}>
56
+ Custom actions
57
+ </Typography>
58
+
59
+ {totalEntityActions === 0 &&
60
+ <Alert action={<Button variant="text"
61
+ size={"small"}
62
+ href={"https://firecms.co/docs/custom_actions"}
63
+ component={"a"}
64
+ rel="noopener noreferrer"
65
+ target="_blank">More info</Button>}>
66
+ Define your own custom actions by uploading them with the CLI.
67
+ </Alert>
68
+ }
69
+
70
+ {<>
71
+ <Paper className={"flex flex-col gap-4 p-2 w-full"}>
72
+ <Table>
73
+ <TableBody>
74
+ {resolvedEntityActions.map((action) => (
75
+ <TableRow key={action.key}>
76
+ <TableCell
77
+ align="left">
78
+ <Typography variant={"subtitle2"} className={"flex-grow"}>
79
+ {action.name}
80
+ </Typography>
81
+ </TableCell>
82
+ <TableCell
83
+ align="right">
84
+ <Tooltip title={"Remove"}
85
+ asChild={true}>
86
+ <IconButton size="small"
87
+ onClick={(e) => {
88
+ e.preventDefault();
89
+ e.stopPropagation();
90
+ setActionToDelete(action.key);
91
+ }}
92
+ color="inherit">
93
+ <DeleteIcon size={"small"}/>
94
+ </IconButton>
95
+ </Tooltip>
96
+ </TableCell>
97
+ </TableRow>
98
+ ))}
99
+ {hardCodedEntityActions.map((action) => (
100
+ <TableRow key={action.key}>
101
+ <TableCell
102
+ align="left">
103
+ <Typography variant={"subtitle2"} className={"flex-grow"}>
104
+ {action.name}
105
+ </Typography>
106
+ <Typography variant={"caption"} className={"flex-grow"}>
107
+ This action is defined in code with
108
+ key <code>{action.key}</code>
109
+ </Typography>
110
+ </TableCell>
111
+ </TableRow>
112
+ ))}
113
+ </TableBody>
114
+ </Table>
115
+
116
+ <Button
117
+ onClick={() => {
118
+ setAddEntityActionDialogOpen(true);
119
+ }}
120
+ variant={"text"}
121
+ startIcon={<AddIcon/>}>
122
+ Add custom entity action
123
+ </Button>
124
+ </Paper>
125
+
126
+ </>}
127
+
128
+
129
+ </div>
130
+
131
+ </div>
132
+ </Container>
133
+
134
+ <div style={{ height: "52px" }}/>
135
+
136
+ {actionToDelete &&
137
+ <ConfirmationDialog open={Boolean(actionToDelete)}
138
+ onAccept={() => {
139
+ setFieldValue("entityActions", values.entityActions?.filter(e => e !== actionToDelete));
140
+ setActionToDelete(undefined);
141
+ }}
142
+ onCancel={() => setActionToDelete(undefined)}
143
+ title={<>Remove this action?</>}
144
+ body={<>This will <b>not
145
+ delete any data</b>, only
146
+ the action in the CMS</>}/>}
147
+
148
+ <EntityActionsSelectDialog
149
+ open={addEntityActionDialogOpen}
150
+ onClose={(selectedActionKey) => {
151
+ if (selectedActionKey) {
152
+ console.log("Selected action key:", selectedActionKey);
153
+ const value = [...(values.entityActions ?? []), selectedActionKey]
154
+ // only actions that are defined in the registry
155
+ .filter((e): e is string => typeof e === "string" && (contextEntityActions ?? []).some(action => action.key === e));
156
+ ;
157
+ setFieldValue("entityActions", value);
158
+ }
159
+ setAddEntityActionDialogOpen(false);
160
+ }}/>
161
+ </div>
162
+ );
163
+ }
@@ -0,0 +1,41 @@
1
+ import { useCustomizationController } from "@firecms/core";
2
+ import { Button, Dialog, DialogActions, DialogContent, DialogTitle, Typography } from "@firecms/ui";
3
+ import React from "react";
4
+
5
+ export function EntityActionsSelectDialog({
6
+ open,
7
+ onClose
8
+ }: { open: boolean, onClose: (selectedActionKey?: string) => void }) {
9
+ const {
10
+ entityActions
11
+ } = useCustomizationController();
12
+
13
+ return <Dialog
14
+ maxWidth={"md"}
15
+ open={open}>
16
+ <DialogTitle>Select custom action</DialogTitle>
17
+ <DialogContent className={"flex flex-col gap-4"}>
18
+ {entityActions?.map((action) => {
19
+ return <Button
20
+ key={action.key}
21
+ onClick={() => onClose(action.key)}
22
+ fullWidth
23
+ variant={"text"}
24
+ >
25
+ {action.name} ({action.key})
26
+ </Button>;
27
+ })}
28
+ {(entityActions ?? []).length === 0 &&
29
+ <Typography variant={"body2"}>
30
+ No custom actions defined. Define your custom actions in the customization settings, before using this
31
+ dialog.
32
+ </Typography>
33
+ }
34
+ </DialogContent>
35
+ <DialogActions>
36
+ <Button variant={"outlined"}
37
+ color={"primary"}
38
+ onClick={() => onClose()}>Cancel</Button>
39
+ </DialogActions>
40
+ </Dialog>
41
+ }
@@ -1,8 +1,11 @@
1
1
  import { useCustomizationController } from "@firecms/core";
2
- import { Button, Dialog, DialogActions, DialogContent, Typography } from "@firecms/ui";
2
+ import { Button, Dialog, DialogActions, DialogContent, DialogTitle, Typography } from "@firecms/ui";
3
3
  import React from "react";
4
4
 
5
- export function EntityCustomViewsSelectDialog({ open, onClose }: { open: boolean, onClose: (selectedViewKey?: string) => void }) {
5
+ export function EntityCustomViewsSelectDialog({
6
+ open,
7
+ onClose
8
+ }: { open: boolean, onClose: (selectedViewKey?: string) => void }) {
6
9
  const {
7
10
  entityViews,
8
11
  } = useCustomizationController();
@@ -10,10 +13,8 @@ export function EntityCustomViewsSelectDialog({ open, onClose }: { open: boolean
10
13
  return <Dialog
11
14
  maxWidth={"md"}
12
15
  open={open}>
16
+ <DialogTitle>Select custom view</DialogTitle>
13
17
  <DialogContent className={"flex flex-col gap-4"}>
14
- <Typography variant={"h6"}>
15
- Select view
16
- </Typography>
17
18
  {entityViews?.map((view) => {
18
19
  return <Button
19
20
  key={view.key}
@@ -26,12 +27,15 @@ export function EntityCustomViewsSelectDialog({ open, onClose }: { open: boolean
26
27
  })}
27
28
  {(entityViews ?? []).length === 0 &&
28
29
  <Typography variant={"body2"}>
29
- No custom views defined
30
+ No custom views defined. Define your custom views in the customization settings, before using this
31
+ dialog.
30
32
  </Typography>
31
33
  }
32
34
  </DialogContent>
33
35
  <DialogActions>
34
- <Button variant={"outlined"} onClick={() => onClose()}>Cancel</Button>
36
+ <Button variant={"outlined"}
37
+ color={"primary"}
38
+ onClick={() => onClose()}>Cancel</Button>
35
39
  </DialogActions>
36
40
  </Dialog>
37
41
  }
@@ -1,9 +1,9 @@
1
1
  import React, { useEffect } from "react";
2
2
  import equal from "react-fast-compare"
3
3
 
4
- import { ArrayContainer, EnumValueConfig, EnumValues, FieldCaption, } from "@firecms/core";
4
+ import { ArrayContainer, ArrayEntryParams, EnumValueConfig, EnumValues, FieldCaption, } from "@firecms/core";
5
5
  import {
6
- AutoAwesomeIcon,
6
+ AutorenewIcon,
7
7
  Badge,
8
8
  Button,
9
9
  CircularProgress,
@@ -11,6 +11,7 @@ import {
11
11
  Dialog,
12
12
  DialogActions,
13
13
  DialogContent,
14
+ DialogTitle,
14
15
  IconButton,
15
16
  ListIcon,
16
17
  Paper,
@@ -121,7 +122,10 @@ function EnumFormFields({
121
122
  const inferredValuesRef = React.useRef(new Set());
122
123
  const inferredValues = inferredValuesRef.current;
123
124
 
124
- const buildEntry = (index: number, internalId: number) => {
125
+ const buildEntry = ({
126
+ index,
127
+ internalId
128
+ }:ArrayEntryParams) => {
125
129
  const justAdded = lastInternalIdAdded === internalId;
126
130
  const entryError = errors?.enumValues && errors?.enumValues[index];
127
131
  return <EnumEntry index={index}
@@ -179,7 +183,7 @@ function EnumFormFields({
179
183
  variant={"text"}
180
184
  size={"small"}
181
185
  onClick={inferValues}>
182
- {inferring ? <CircularProgress size={"small"}/> : <AutoAwesomeIcon/>}
186
+ {inferring ? <CircularProgress size={"smallest"}/> : <AutorenewIcon/>}
183
187
  Infer values from data
184
188
  </Button>}
185
189
  </div>
@@ -193,7 +197,7 @@ function EnumFormFields({
193
197
  size={"small"}
194
198
  buildEntry={buildEntry}
195
199
  onInternalIdAdded={setLastInternalIdAdded}
196
- includeAddButton={true}
200
+ canAddElements={true}
197
201
  onValueChange={(value) => setFieldValue(enumValuesPath, value)}
198
202
  newDefaultEntry={{ id: "", label: "" }}/>
199
203
 
@@ -263,7 +267,7 @@ const EnumEntry = React.memo(
263
267
  size="small"
264
268
  autoFocus={autoFocus}
265
269
  autoComplete="off"
266
- endAdornment={inferredEntry && <AutoAwesomeIcon size={"small"}/>}
270
+ endAdornment={inferredEntry && <AutorenewIcon size={"small"}/>}
267
271
  error={Boolean(entryError?.label)}/>
268
272
 
269
273
  {!disabled &&
@@ -324,7 +328,7 @@ function EnumEntryDialog({
324
328
  open={open}
325
329
  onOpenChange={(open) => !open ? onClose() : undefined}
326
330
  >
327
-
331
+ <DialogTitle hidden>Enum form dialog</DialogTitle>
328
332
  <DialogContent>
329
333
  {index !== undefined &&
330
334
  <div>