@firecms/collection_editor 3.0.0-canary.29 → 3.0.0-canary.290

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 (94) hide show
  1. package/LICENSE +114 -21
  2. package/README.md +165 -1
  3. package/dist/ConfigControllerProvider.d.ts +1 -2
  4. package/dist/index.d.ts +1 -0
  5. package/dist/index.es.js +11093 -4800
  6. package/dist/index.es.js.map +1 -1
  7. package/dist/index.umd.js +11750 -3
  8. package/dist/index.umd.js.map +1 -1
  9. package/dist/types/collection_editor_controller.d.ts +3 -2
  10. package/dist/types/collection_inference.d.ts +4 -1
  11. package/dist/types/config_controller.d.ts +3 -1
  12. package/dist/types/config_permissions.d.ts +2 -2
  13. package/dist/types/persisted_collection.d.ts +1 -1
  14. package/dist/ui/CollectionViewHeaderAction.d.ts +3 -2
  15. package/dist/ui/EditorCollectionActionStart.d.ts +2 -0
  16. package/dist/ui/EditorEntityAction.d.ts +2 -0
  17. package/dist/ui/PropertyAddColumnComponent.d.ts +3 -1
  18. package/dist/ui/collection_editor/CollectionDetailsForm.d.ts +3 -1
  19. package/dist/ui/collection_editor/CollectionEditorDialog.d.ts +3 -2
  20. package/dist/ui/collection_editor/CollectionEditorWelcomeView.d.ts +2 -2
  21. package/dist/ui/collection_editor/CollectionPropertiesEditorForm.d.ts +2 -2
  22. package/dist/ui/collection_editor/EntityActionsEditTab.d.ts +4 -0
  23. package/dist/ui/collection_editor/EntityActionsSelectDialog.d.ts +4 -0
  24. package/dist/ui/collection_editor/LayoutModeSwitch.d.ts +5 -0
  25. package/dist/ui/collection_editor/PropertyEditView.d.ts +8 -0
  26. package/dist/ui/collection_editor/PropertyTree.d.ts +11 -12
  27. package/dist/ui/collection_editor/SubcollectionsEditTab.d.ts +1 -1
  28. package/dist/ui/collection_editor/import/CollectionEditorImportDataPreview.d.ts +1 -1
  29. package/dist/ui/collection_editor/import/CollectionEditorImportMapping.d.ts +8 -1
  30. package/dist/ui/collection_editor/import/clean_import_data.d.ts +1 -1
  31. package/dist/ui/collection_editor/properties/MarkdownPropertyField.d.ts +4 -0
  32. package/dist/ui/collection_editor/properties/ReferencePropertyField.d.ts +2 -1
  33. package/dist/ui/collection_editor/properties/StringPropertyField.d.ts +1 -1
  34. package/dist/useCollectionEditorPlugin.d.ts +8 -11
  35. package/dist/utils/collections.d.ts +6 -0
  36. package/dist/utils/entities.d.ts +1 -1
  37. package/package.json +25 -37
  38. package/src/ConfigControllerProvider.tsx +64 -66
  39. package/src/index.ts +1 -0
  40. package/src/types/collection_editor_controller.tsx +6 -5
  41. package/src/types/collection_inference.ts +4 -1
  42. package/src/types/config_controller.tsx +4 -1
  43. package/src/types/config_permissions.ts +1 -1
  44. package/src/types/persisted_collection.ts +2 -3
  45. package/src/ui/CollectionViewHeaderAction.tsx +10 -5
  46. package/src/ui/EditorCollectionAction.tsx +12 -70
  47. package/src/ui/EditorCollectionActionStart.tsx +87 -0
  48. package/src/ui/EditorEntityAction.tsx +51 -0
  49. package/src/ui/HomePageEditorCollectionAction.tsx +21 -14
  50. package/src/ui/NewCollectionButton.tsx +1 -1
  51. package/src/ui/NewCollectionCard.tsx +3 -3
  52. package/src/ui/PropertyAddColumnComponent.tsx +11 -6
  53. package/src/ui/collection_editor/CollectionDetailsForm.tsx +170 -50
  54. package/src/ui/collection_editor/CollectionEditorDialog.tsx +119 -39
  55. package/src/ui/collection_editor/CollectionEditorWelcomeView.tsx +24 -33
  56. package/src/ui/collection_editor/CollectionPropertiesEditorForm.tsx +46 -49
  57. package/src/ui/collection_editor/EntityActionsEditTab.tsx +163 -0
  58. package/src/ui/collection_editor/EntityActionsSelectDialog.tsx +41 -0
  59. package/src/ui/collection_editor/EntityCustomViewsSelectDialog.tsx +11 -7
  60. package/src/ui/collection_editor/EnumForm.tsx +11 -7
  61. package/src/ui/collection_editor/GetCodeDialog.tsx +60 -28
  62. package/src/ui/collection_editor/LayoutModeSwitch.tsx +54 -0
  63. package/src/ui/collection_editor/PropertyEditView.tsx +269 -81
  64. package/src/ui/collection_editor/PropertyFieldPreview.tsx +12 -14
  65. package/src/ui/collection_editor/PropertyTree.tsx +184 -138
  66. package/src/ui/collection_editor/SubcollectionsEditTab.tsx +26 -19
  67. package/src/ui/collection_editor/UnsavedChangesDialog.tsx +9 -7
  68. package/src/ui/collection_editor/import/CollectionEditorImportDataPreview.tsx +41 -9
  69. package/src/ui/collection_editor/import/CollectionEditorImportMapping.tsx +43 -10
  70. package/src/ui/collection_editor/import/clean_import_data.ts +1 -1
  71. package/src/ui/collection_editor/properties/BlockPropertyField.tsx +32 -20
  72. package/src/ui/collection_editor/properties/DateTimePropertyField.tsx +54 -47
  73. package/src/ui/collection_editor/properties/EnumPropertyField.tsx +3 -1
  74. package/src/ui/collection_editor/properties/MapPropertyField.tsx +8 -7
  75. package/src/ui/collection_editor/properties/MarkdownPropertyField.tsx +139 -0
  76. package/src/ui/collection_editor/properties/ReferencePropertyField.tsx +7 -3
  77. package/src/ui/collection_editor/properties/RepeatPropertyField.tsx +0 -1
  78. package/src/ui/collection_editor/properties/StoragePropertyField.tsx +165 -20
  79. package/src/ui/collection_editor/properties/StringPropertyField.tsx +4 -9
  80. package/src/ui/collection_editor/properties/UrlPropertyField.tsx +1 -0
  81. package/src/ui/collection_editor/properties/advanced/AdvancedPropertyValidation.tsx +2 -0
  82. package/src/ui/collection_editor/properties/validation/ValidationPanel.tsx +3 -3
  83. package/src/ui/collection_editor/templates/blog_template.ts +1 -4
  84. package/src/ui/collection_editor/templates/pages_template.ts +1 -6
  85. package/src/ui/collection_editor/utils/strings.ts +13 -6
  86. package/src/ui/collection_editor/utils/supported_fields.tsx +2 -0
  87. package/src/ui/collection_editor/utils/update_property_for_widget.ts +37 -6
  88. package/src/useCollectionEditorPlugin.tsx +38 -32
  89. package/src/utils/collections.ts +45 -0
  90. package/src/utils/entities.ts +6 -9
  91. package/dist/ui/RootCollectionSuggestions.d.ts +0 -3
  92. package/dist/ui/collection_editor/PropertySelectItem.d.ts +0 -8
  93. package/src/ui/RootCollectionSuggestions.tsx +0 -63
  94. package/src/ui/collection_editor/PropertySelectItem.tsx +0 -32
@@ -1,12 +1,12 @@
1
1
  import {
2
- DeleteConfirmationDialog,
2
+ ConfirmationDialog,
3
3
  PluginHomePageActionsProps,
4
4
  useAuthController,
5
5
  useSnackbarController
6
6
  } from "@firecms/core";
7
7
  import { DeleteIcon, IconButton, Menu, MenuItem, MoreVertIcon, SettingsIcon, } from "@firecms/ui";
8
8
  import { useCollectionEditorController } from "../useCollectionEditorController";
9
- import { useCallback, useState } from "react";
9
+ import { useState } from "react";
10
10
  import { useCollectionsConfigController } from "../useCollectionsConfigController";
11
11
 
12
12
  export function HomePageEditorCollectionAction({
@@ -14,6 +14,7 @@ export function HomePageEditorCollectionAction({
14
14
  collection
15
15
  }: PluginHomePageActionsProps) {
16
16
 
17
+
17
18
  const snackbarController = useSnackbarController();
18
19
  const authController = useAuthController();
19
20
  const configController = useCollectionsConfigController();
@@ -24,13 +25,16 @@ export function HomePageEditorCollectionAction({
24
25
  collection
25
26
  });
26
27
 
27
- const onEditCollectionClicked = useCallback(() => {
28
- collectionEditorController?.editCollection({ id: collection.id, parentCollectionIds: [] });
29
- }, [collectionEditorController, path]);
28
+ const onEditCollectionClicked = () => {
29
+ collectionEditorController?.editCollection({
30
+ id: collection.id,
31
+ parentCollectionIds: []
32
+ });
33
+ };
30
34
 
31
35
  const [deleteRequested, setDeleteRequested] = useState(false);
32
36
 
33
- const deleteCollection = useCallback(() => {
37
+ const deleteCollection = () => {
34
38
  configController?.deleteCollection({ id: collection.id }).then(() => {
35
39
  setDeleteRequested(false);
36
40
  snackbarController.open({
@@ -38,22 +42,24 @@ export function HomePageEditorCollectionAction({
38
42
  type: "success"
39
43
  });
40
44
  });
41
- }, [path, configController]);
45
+ };
42
46
 
43
47
  return <>
44
48
 
45
49
  <div>
46
50
  {permissions.deleteCollections &&
47
51
  <Menu
48
- trigger={<IconButton>
52
+ trigger={<IconButton size={"small"}>
49
53
  <MoreVertIcon size={"small"}/>
50
54
  </IconButton>}
51
55
  >
52
- <MenuItem onClick={(event) => {
53
- event.preventDefault();
54
- event.stopPropagation();
55
- setDeleteRequested(true);
56
- }}>
56
+ <MenuItem
57
+ dense={true}
58
+ onClick={(event) => {
59
+ event.preventDefault();
60
+ event.stopPropagation();
61
+ setDeleteRequested(true);
62
+ }}>
57
63
  <DeleteIcon/>
58
64
  Delete
59
65
  </MenuItem>
@@ -64,6 +70,7 @@ export function HomePageEditorCollectionAction({
64
70
 
65
71
  {permissions.editCollections &&
66
72
  <IconButton
73
+ size={"small"}
67
74
  onClick={(event) => {
68
75
  onEditCollectionClicked();
69
76
  }}>
@@ -71,7 +78,7 @@ export function HomePageEditorCollectionAction({
71
78
  </IconButton>}
72
79
  </div>
73
80
 
74
- <DeleteConfirmationDialog
81
+ <ConfirmationDialog
75
82
  open={deleteRequested}
76
83
  onAccept={deleteCollection}
77
84
  onCancel={() => setDeleteRequested(false)}
@@ -3,7 +3,7 @@ import { useCollectionEditorController } from "../useCollectionEditorController"
3
3
 
4
4
  export function NewCollectionButton() {
5
5
  const collectionEditorController = useCollectionEditorController();
6
- return <div className={"bg-gray-50 dark:bg-gray-900 min-w-fit rounded"}>
6
+ return <div className={"bg-surface-50 dark:bg-surface-900 min-w-fit rounded"}>
7
7
  <Button className={"min-w-fit"}
8
8
  variant={"outlined"}
9
9
  onClick={() => collectionEditorController.createCollection({
@@ -1,5 +1,5 @@
1
1
  import { PluginHomePageAdditionalCardsProps, useAuthController } from "@firecms/core";
2
- import { AddIcon, Card, cn, Typography } from "@firecms/ui";
2
+ import { AddIcon, Card, cls, Typography } from "@firecms/ui";
3
3
  import { useCollectionEditorController } from "../useCollectionEditorController";
4
4
 
5
5
  export function NewCollectionCard({
@@ -20,7 +20,7 @@ export function NewCollectionCard({
20
20
  : true;
21
21
 
22
22
  return (
23
- <Card className={cn("h-full p-4 min-h-[124px]")}
23
+ <Card className={cls("h-full p-4 min-h-[124px]")}
24
24
  onClick={collectionEditorController && canCreateCollections
25
25
  ? () => collectionEditorController.createCollection({
26
26
  initialValues: group ? { group } : undefined,
@@ -31,7 +31,7 @@ export function NewCollectionCard({
31
31
  : undefined}>
32
32
 
33
33
  <div
34
- className="flex flex-col items-start h-full w-full items-center justify-center h-full w-full flex-grow flex-col">
34
+ className="flex items-center justify-center h-full w-full flex-grow flex-col">
35
35
  <AddIcon color="primary" size={"large"}/>
36
36
  <Typography color="primary"
37
37
  variant={"caption"}
@@ -1,4 +1,4 @@
1
- import { getDefaultPropertiesOrder, useAuthController } from "@firecms/core";
1
+ import { EntityTableController, getDefaultPropertiesOrder, useAuthController } from "@firecms/core";
2
2
  import { AddIcon, Tooltip } from "@firecms/ui";
3
3
  import { useCollectionEditorController } from "../useCollectionEditorController";
4
4
  import { PersistedCollection } from "../types/persisted_collection";
@@ -6,11 +6,13 @@ import { PersistedCollection } from "../types/persisted_collection";
6
6
  export function PropertyAddColumnComponent({
7
7
  fullPath,
8
8
  parentCollectionIds,
9
- collection
9
+ collection,
10
+ tableController
10
11
  }: {
11
12
  fullPath: string,
12
13
  parentCollectionIds: string[],
13
14
  collection: PersistedCollection;
15
+ tableController: EntityTableController;
14
16
  }) {
15
17
 
16
18
  const authController = useAuthController();
@@ -23,16 +25,19 @@ export function PropertyAddColumnComponent({
23
25
  : true;
24
26
 
25
27
  return (
26
- <Tooltip title={canEditCollection ? "Add new property" : "You don't have permission to add new properties"}>
28
+ <Tooltip
29
+ asChild={true}
30
+ title={canEditCollection ? "Add new property" : "You don't have permission to add new properties"}>
27
31
  <div
28
- className={"p-0.5 w-20 h-full flex items-center justify-center cursor-pointer bg-gray-100 bg-opacity-40 hover:bg-gray-100 dark:bg-gray-950 dark:bg-opacity-40 dark:hover:bg-gray-950"}
29
- // className={onHover ? "bg-white dark:bg-gray-950" : undefined}
32
+ className={"p-0.5 w-20 h-full flex items-center justify-center cursor-pointer bg-surface-100 bg-opacity-40 hover:bg-surface-100 dark:bg-surface-950 dark:bg-opacity-40 dark:hover:bg-surface-950"}
33
+ // className={onHover ? "bg-white dark:bg-surface-950" : undefined}
30
34
  onClick={() => {
31
35
  collectionEditorController.editProperty({
32
36
  editedCollectionId: collection.id,
33
37
  parentCollectionIds,
34
38
  currentPropertiesOrder: getDefaultPropertiesOrder(collection),
35
- collection
39
+ collection,
40
+ existingEntities: tableController.data
36
41
  });
37
42
  }}>
38
43
  <AddIcon color={"inherit"}/>
@@ -1,11 +1,10 @@
1
1
  import React, { useEffect, useState } from "react";
2
2
  import { EntityCollection, FieldCaption, IconForView, SearchIconsView, singular, toSnakeCase, } from "@firecms/core";
3
3
  import {
4
- Autocomplete,
5
- AutocompleteItem,
6
4
  BooleanSwitchWithLabel,
7
5
  Chip,
8
- cn,
6
+ CloseIcon,
7
+ cls,
9
8
  Container,
10
9
  DebouncedTextField,
11
10
  Dialog,
@@ -21,6 +20,8 @@ import {
21
20
  } from "@firecms/ui";
22
21
 
23
22
  import { Field, getIn, useFormex } from "@firecms/formex";
23
+ import { useCollectionEditorController } from "../../useCollectionEditorController";
24
+ import { LayoutModeSwitch } from "./LayoutModeSwitch";
24
25
 
25
26
  export function CollectionDetailsForm({
26
27
  isNewCollection,
@@ -28,7 +29,8 @@ export function CollectionDetailsForm({
28
29
  existingPaths,
29
30
  existingIds,
30
31
  groups,
31
- parentCollection
32
+ parentCollection,
33
+ children
32
34
  }: {
33
35
  isNewCollection: boolean,
34
36
  reservedGroups?: string[];
@@ -37,6 +39,7 @@ export function CollectionDetailsForm({
37
39
  groups: string[] | null;
38
40
  parentCollection?: EntityCollection;
39
41
  parentCollectionIds?: string[];
42
+ children?: React.ReactNode;
40
43
  }) {
41
44
 
42
45
  const groupRef = React.useRef<HTMLInputElement>(null);
@@ -51,9 +54,15 @@ export function CollectionDetailsForm({
51
54
  submitCount
52
55
  } = useFormex<EntityCollection>();
53
56
 
57
+ const collectionEditor = useCollectionEditorController();
58
+
54
59
  const [iconDialogOpen, setIconDialogOpen] = useState(false);
55
60
  const [advancedPanelExpanded, setAdvancedPanelExpanded] = useState(false);
56
61
 
62
+ const updateDatabaseId = (databaseId: string) => {
63
+ setFieldValue("databaseId", databaseId ?? undefined);
64
+ }
65
+
57
66
  const updateName = (name: string) => {
58
67
  setFieldValue("name", name);
59
68
 
@@ -106,17 +115,22 @@ export function CollectionDetailsForm({
106
115
  }
107
116
 
108
117
  const showErrors = submitCount > 0;
118
+
109
119
  return (
110
120
  <div className={"overflow-auto my-auto"}>
111
121
  <Container maxWidth={"4xl"} className={"flex flex-col gap-4 p-8 m-auto"}>
112
122
 
113
123
  <div>
114
124
  <div
115
- className="flex flex-row py-2 pt-3 items-center">
125
+ className="flex flex-row gap-2 py-2 pt-3 items-center">
116
126
  <Typography variant={!isNewCollection ? "h5" : "h4"} className={"flex-grow"}>
117
127
  {isNewCollection ? "New collection" : `${values?.name} collection`}
118
128
  </Typography>
119
- <Tooltip title={"Change icon"}>
129
+ <DefaultDatabaseField databaseId={values.databaseId}
130
+ onDatabaseIdUpdate={updateDatabaseId}/>
131
+
132
+ <Tooltip title={"Change icon"}
133
+ asChild={true}>
120
134
  <IconButton
121
135
  shape={"square"}
122
136
  onClick={() => setIconDialogOpen(true)}>
@@ -139,14 +153,15 @@ export function CollectionDetailsForm({
139
153
  value={values.name ?? ""}
140
154
  onChange={(e: any) => updateName(e.target.value)}
141
155
  label={"Name"}
156
+ autoFocus={true}
142
157
  required
143
158
  error={showErrors && Boolean(errors.name)}/>
144
159
  <FieldCaption error={touched.name && Boolean(errors.name)}>
145
- {touched.name && Boolean(errors.name) ? errors.name : "Name of in this collection, usually a plural name (e.g. Products)"}
160
+ {touched.name && Boolean(errors.name) ? errors.name : "Name of this collection, usually a plural name (e.g. Products)"}
146
161
  </FieldCaption>
147
162
  </div>
148
163
 
149
- <div className={cn("col-span-12 ", isSubcollection ? "" : "sm:col-span-8")}>
164
+ <div className={cls("col-span-12 ")}>
150
165
  <Field name={"path"}
151
166
  as={DebouncedTextField}
152
167
  label={"Path"}
@@ -162,44 +177,71 @@ export function CollectionDetailsForm({
162
177
 
163
178
  </div>
164
179
 
165
- {!isSubcollection && <div className={"col-span-12 sm:col-span-4 relative"}>
166
-
167
- <TextField error={showErrors && Boolean(errors.group)}
168
- disabled={isSubmitting}
169
- value={values.group ?? ""}
170
- autoComplete="off"
171
- onChange={(event) => setFieldValue("group", event.target.value)}
172
- name={"group"}
173
- inputRef={groupRef}
174
- label="Group"/>
175
- <Autocomplete
176
- open={autoCompleteOpen && (groupOptions ?? []).length > 0}
177
- setOpen={setAutoCompleteOpen}>
178
- {groupOptions?.map((group, index) => {
179
- return <AutocompleteItem
180
- key={index + "_" + group}
181
- onClick={() => {
182
- setAutoCompleteOpen(false);
183
- setFieldValue("group", group ?? null);
184
- }}
185
- >
186
- <div className={"flex-grow"}>
187
- {group}
188
- </div>
189
- </AutocompleteItem>;
190
- })}
191
- </Autocomplete>
180
+ {/*{!isSubcollection && <div className={"col-span-12 sm:col-span-4 relative"}>*/}
181
+
182
+ {/* <TextField error={showErrors && Boolean(errors.group)}*/}
183
+ {/* disabled={isSubmitting}*/}
184
+ {/* value={values.group ?? ""}*/}
185
+ {/* autoComplete="off"*/}
186
+ {/* onChange={(event) => setFieldValue("group", event.target.value)}*/}
187
+ {/* name={"group"}*/}
188
+ {/* inputRef={groupRef}*/}
189
+ {/* label="Group"/>*/}
190
+ {/* <Autocomplete*/}
191
+ {/* open={autoCompleteOpen && (groupOptions ?? []).length > 0}*/}
192
+ {/* setOpen={setAutoCompleteOpen}>*/}
193
+ {/* {groupOptions?.map((group, index) => {*/}
194
+ {/* return <AutocompleteItem*/}
195
+ {/* key={index + "_" + group}*/}
196
+ {/* className={"pr-6 pl-14"}*/}
197
+ {/* onClick={() => {*/}
198
+ {/* setAutoCompleteOpen(false);*/}
199
+ {/* setFieldValue("group", group ?? null);*/}
200
+ {/* }}*/}
201
+ {/* >*/}
202
+ {/* <div className={"flex-grow"}>*/}
203
+ {/* {group}*/}
204
+ {/* </div>*/}
205
+ {/* </AutocompleteItem>;*/}
206
+ {/* })}*/}
207
+ {/* </Autocomplete>*/}
208
+ {/* <FieldCaption>*/}
209
+ {/* {showErrors && Boolean(errors.group) ? errors.group : "Group in the home page"}*/}
210
+ {/* </FieldCaption>*/}
211
+
212
+
213
+ {/*</div>}*/}
214
+
215
+ <LayoutModeSwitch
216
+ className={"col-span-12"}
217
+ value={values.openEntityMode ?? "side_panel"}
218
+ onChange={(value) => setFieldValue("openEntityMode", value)}/>
219
+
220
+ <div className={"col-span-12"}>
221
+ <BooleanSwitchWithLabel
222
+ position={"start"}
223
+ size={"large"}
224
+ allowIndeterminate={true}
225
+ label={values.history === null || values.history === undefined ? "Document history revisions enabled if enabled globally" : (
226
+ values.history ? "Document history revisions ENABLED" : "Document history revisions NOT enabled"
227
+ )}
228
+ onValueChange={(v) => setFieldValue("history", v)}
229
+ value={values.history === undefined ? null : values.history}
230
+ />
192
231
  <FieldCaption>
193
- {showErrors && Boolean(errors.group) ? errors.group : "Group of the collection"}
232
+ When enabled, each document in this collection will have a history of changes.
233
+ This is useful for auditing purposes. The data is stored in a subcollection of the document
234
+ in your database, called <b>__history</b>.
194
235
  </FieldCaption>
195
- </div>}
236
+ </div>
196
237
 
197
- <div className={"col-span-12"}>
238
+
239
+ <div className={"col-span-12 mt-8"}>
198
240
  <ExpandablePanel
199
241
  expanded={advancedPanelExpanded}
200
242
  onExpandedChange={setAdvancedPanelExpanded}
201
243
  title={
202
- <div className="flex flex-row text-gray-500">
244
+ <div className="flex flex-row text-surface-500">
203
245
  <SettingsIcon/>
204
246
  <Typography variant={"subtitle2"}
205
247
  className="ml-2">
@@ -216,7 +258,7 @@ export function CollectionDetailsForm({
216
258
  label={"Collection id"}
217
259
  error={showErrors && Boolean(errors.id)}/>
218
260
  <FieldCaption error={touched.id && Boolean(errors.id)}>
219
- {touched.id && Boolean(errors.id) ? errors.id : "This id identifies this collection"}
261
+ {touched.id && Boolean(errors.id) ? errors.id : "This id identifies this collection. Typically the same as the path."}
220
262
  </FieldCaption>
221
263
  </div>
222
264
 
@@ -235,6 +277,35 @@ export function CollectionDetailsForm({
235
277
  {showErrors && Boolean(errors.singularName) ? errors.singularName : "Optionally define a singular name for your entities"}
236
278
  </FieldCaption>
237
279
  </div>
280
+ <div className={"col-span-12"}>
281
+ <TextField
282
+ error={showErrors && Boolean(errors.sideDialogWidth)}
283
+ name={"sideDialogWidth"}
284
+ type={"number"}
285
+ aria-describedby={"sideDialogWidth-helper"}
286
+ onChange={(e) => {
287
+ setFieldTouched("sideDialogWidth", true);
288
+ const value = e.target.value;
289
+ if (!value) {
290
+ setFieldValue("sideDialogWidth", null);
291
+ } else if (!isNaN(Number(value))) {
292
+ setFieldValue("sideDialogWidth", Number(value));
293
+ }
294
+ }}
295
+ endAdornment={<IconButton
296
+ size={"small"}
297
+ onClick={() => {
298
+ setFieldValue("sideDialogWidth", null);
299
+ }}
300
+ disabled={!values.sideDialogWidth}>
301
+ <CloseIcon size={"small"}/>
302
+ </IconButton>}
303
+ value={values.sideDialogWidth ?? ""}
304
+ label={"Side dialog width"}/>
305
+ <FieldCaption error={showErrors && Boolean(errors.singularName)}>
306
+ {showErrors && Boolean(errors.singularName) ? errors.singularName : "Optionally define the width (in pixels) of entities side dialog. Default is 768px"}
307
+ </FieldCaption>
308
+ </div>
238
309
  <div className={"col-span-12"}>
239
310
  <TextField
240
311
  error={showErrors && Boolean(errors.description)}
@@ -242,7 +313,7 @@ export function CollectionDetailsForm({
242
313
  value={values.description ?? ""}
243
314
  onChange={handleChange}
244
315
  multiline
245
- rows={2}
316
+ minRows={2}
246
317
  aria-describedby="description-helper-text"
247
318
  label="Description"
248
319
  />
@@ -254,6 +325,8 @@ export function CollectionDetailsForm({
254
325
  <div className={"col-span-12"}>
255
326
  <Select
256
327
  name="defaultSize"
328
+ size={"large"}
329
+ fullWidth={true}
257
330
  label="Default row size"
258
331
  position={"item-aligned"}
259
332
  onChange={handleChange}
@@ -269,21 +342,45 @@ export function CollectionDetailsForm({
269
342
  ))}
270
343
  </Select>
271
344
  </div>
345
+
346
+ <div className={"col-span-12"}>
347
+ <BooleanSwitchWithLabel
348
+ position={"start"}
349
+ size={"large"}
350
+ label={values.includeJsonView === undefined || values.includeJsonView ? "Include JSON view" : "Do not include JSON view"}
351
+ onValueChange={(v) => setFieldValue("includeJsonView", v)}
352
+ value={values.includeJsonView === undefined ? true : values.includeJsonView}
353
+ />
354
+ <FieldCaption>
355
+ Include the JSON representation of the document.
356
+ </FieldCaption>
357
+ </div>
358
+
359
+ <div className={"col-span-12"}>
360
+ <BooleanSwitchWithLabel
361
+ position={"start"}
362
+ size={"large"}
363
+ label={values.inlineEditing === undefined || values.inlineEditing ? "Data can be edited directly in the table view" : "Data can be edited only in the form view"}
364
+ onValueChange={(v) => setFieldValue("inlineEditing", v)}
365
+ value={values.inlineEditing === undefined ? true : values.inlineEditing}
366
+ />
367
+ <FieldCaption>
368
+ Allow editing data directly in the table view, without opening the form view.
369
+ </FieldCaption>
370
+ </div>
371
+
272
372
  <div className={"col-span-12"}>
273
373
  <Select
274
374
  name="customId"
275
- label="Data IDs generation"
375
+ label="Document IDs generation"
276
376
  position={"item-aligned"}
377
+ size={"large"}
378
+ fullWidth={true}
277
379
  disabled={customIdValue === "code_defined"}
278
380
  onValueChange={(v) => {
279
381
  if (v === "code_defined")
280
382
  throw new Error("This should not happen");
281
- else if (v === "true")
282
- setFieldValue("customId", true);
283
- else if (v === "false")
284
- setFieldValue("customId", false);
285
- else if (v === "optional")
286
- setFieldValue("customId", "optional");
383
+ setFieldValue("customId", v);
287
384
  }}
288
385
  value={customIdValue ?? ""}
289
386
  renderValue={(value: any) => {
@@ -308,9 +405,10 @@ export function CollectionDetailsForm({
308
405
  </SelectItem>
309
406
  </Select>
310
407
  </div>
311
- <div className={"col-span-12"}>
408
+ <div className={"col-span-12 mt-4"}>
312
409
  <BooleanSwitchWithLabel
313
410
  position={"start"}
411
+ size={"large"}
314
412
  label="Collection group"
315
413
  onValueChange={(v) => setFieldValue("collectionGroup", v)}
316
414
  value={values.collectionGroup ?? false}
@@ -324,6 +422,7 @@ export function CollectionDetailsForm({
324
422
  <div className={"col-span-12"}>
325
423
  <BooleanSwitchWithLabel
326
424
  position={"start"}
425
+ size={"large"}
327
426
  label="Enable text search for this collection"
328
427
  onValueChange={(v) => setFieldValue("textSearchEnabled", v)}
329
428
  value={values.textSearchEnabled ?? false}
@@ -334,9 +433,13 @@ export function CollectionDetailsForm({
334
433
  for large collections, as it may incur in performance and cost issues.
335
434
  </FieldCaption>
336
435
  </div>
436
+
437
+
337
438
  </div>
338
439
  </ExpandablePanel>
339
440
 
441
+ {children}
442
+
340
443
  </div>
341
444
 
342
445
  </div>
@@ -350,7 +453,7 @@ export function CollectionDetailsForm({
350
453
  fullWidth
351
454
  >
352
455
  <div className={"p-4 overflow-auto min-h-[200px]"}>
353
- <SearchIconsView selectedIcon={values.icon}
456
+ <SearchIconsView selectedIcon={typeof values.icon === "string" ? values.icon : undefined}
354
457
  onIconSelected={(icon: string) => {
355
458
  setIconDialogOpen(false);
356
459
  setFieldValue("icon", icon);
@@ -363,3 +466,20 @@ export function CollectionDetailsForm({
363
466
  </div>
364
467
  );
365
468
  }
469
+
470
+ function DefaultDatabaseField({
471
+ databaseId,
472
+ onDatabaseIdUpdate
473
+ }: { databaseId?: string, onDatabaseIdUpdate: (databaseId: string) => void }) {
474
+
475
+ return <Tooltip title={"Database ID"}
476
+ side={"top"}
477
+ align={"start"}>
478
+ <TextField size={"small"}
479
+ invisible={true}
480
+ inputClassName={"text-end"}
481
+ value={databaseId ?? ""}
482
+ onChange={(e: any) => onDatabaseIdUpdate(e.target.value)}
483
+ placeholder={"(default)"}></TextField>
484
+ </Tooltip>
485
+ }