@firecms/collection_editor 3.0.1 → 3.1.0-canary.02232f4

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 (119) 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 +15260 -8173
  6. package/dist/index.es.js.map +1 -1
  7. package/dist/index.umd.js +15257 -8170
  8. package/dist/index.umd.js.map +1 -1
  9. package/dist/locales/de.d.ts +120 -0
  10. package/dist/locales/en.d.ts +120 -0
  11. package/dist/locales/es.d.ts +120 -0
  12. package/dist/locales/fr.d.ts +120 -0
  13. package/dist/locales/hi.d.ts +120 -0
  14. package/dist/locales/it.d.ts +120 -0
  15. package/dist/locales/pt.d.ts +120 -0
  16. package/dist/types/collection_editor_controller.d.ts +14 -0
  17. package/dist/types/collection_inference.d.ts +8 -2
  18. package/dist/types/config_controller.d.ts +23 -2
  19. package/dist/ui/AddKanbanColumnAction.d.ts +11 -0
  20. package/dist/ui/KanbanSetupAction.d.ts +10 -0
  21. package/dist/ui/collection_editor/AICollectionGeneratorPopover.d.ts +37 -0
  22. package/dist/ui/collection_editor/AIModifiedPathsContext.d.ts +20 -0
  23. package/dist/ui/collection_editor/CollectionDetailsForm.d.ts +2 -3
  24. package/dist/ui/collection_editor/CollectionEditorDialog.d.ts +24 -0
  25. package/dist/ui/collection_editor/CollectionEditorWelcomeView.d.ts +4 -1
  26. package/dist/ui/collection_editor/CollectionJsonImportDialog.d.ts +7 -0
  27. package/dist/ui/collection_editor/CollectionYupValidation.d.ts +9 -13
  28. package/dist/ui/collection_editor/DisplaySettingsForm.d.ts +3 -0
  29. package/dist/ui/collection_editor/EntityActionsEditTab.d.ts +2 -1
  30. package/dist/ui/collection_editor/ExtendSettingsForm.d.ts +14 -0
  31. package/dist/ui/collection_editor/GeneralSettingsForm.d.ts +7 -0
  32. package/dist/ui/collection_editor/KanbanConfigSection.d.ts +4 -0
  33. package/dist/ui/collection_editor/PropertyEditView.d.ts +6 -1
  34. package/dist/ui/collection_editor/PropertyTree.d.ts +2 -1
  35. package/dist/ui/collection_editor/SubcollectionsEditTab.d.ts +2 -1
  36. package/dist/ui/collection_editor/ViewModeSwitch.d.ts +6 -0
  37. package/dist/ui/collection_editor/properties/EnumPropertyField.d.ts +2 -1
  38. package/dist/ui/collection_editor/properties/conditions/ConditionsEditor.d.ts +10 -0
  39. package/dist/ui/collection_editor/properties/conditions/ConditionsPanel.d.ts +2 -0
  40. package/dist/ui/collection_editor/properties/conditions/EnumConditionsEditor.d.ts +6 -0
  41. package/dist/ui/collection_editor/properties/conditions/index.d.ts +6 -0
  42. package/dist/ui/collection_editor/properties/conditions/property_paths.d.ts +19 -0
  43. package/dist/useCollectionEditorPlugin.d.ts +7 -1
  44. package/dist/utils/validateCollectionJson.d.ts +22 -0
  45. package/package.json +15 -15
  46. package/src/ConfigControllerProvider.tsx +82 -47
  47. package/src/api/generateCollectionApi.ts +119 -0
  48. package/src/api/index.ts +1 -0
  49. package/src/index.ts +28 -1
  50. package/src/locales/de.ts +125 -0
  51. package/src/locales/en.ts +145 -0
  52. package/src/locales/es.ts +125 -0
  53. package/src/locales/fr.ts +125 -0
  54. package/src/locales/hi.ts +125 -0
  55. package/src/locales/it.ts +125 -0
  56. package/src/locales/pt.ts +125 -0
  57. package/src/types/collection_editor_controller.tsx +16 -3
  58. package/src/types/collection_inference.ts +15 -2
  59. package/src/types/config_controller.tsx +27 -2
  60. package/src/ui/AddKanbanColumnAction.tsx +203 -0
  61. package/src/ui/EditorCollectionAction.tsx +3 -3
  62. package/src/ui/EditorCollectionActionStart.tsx +1 -2
  63. package/src/ui/EditorEntityAction.tsx +3 -2
  64. package/src/ui/HomePageEditorCollectionAction.tsx +41 -13
  65. package/src/ui/KanbanSetupAction.tsx +38 -0
  66. package/src/ui/MissingReferenceWidget.tsx +1 -1
  67. package/src/ui/NewCollectionButton.tsx +4 -2
  68. package/src/ui/NewCollectionCard.tsx +7 -4
  69. package/src/ui/PropertyAddColumnComponent.tsx +4 -3
  70. package/src/ui/collection_editor/AICollectionGeneratorPopover.tsx +243 -0
  71. package/src/ui/collection_editor/AIModifiedPathsContext.tsx +88 -0
  72. package/src/ui/collection_editor/CollectionDetailsForm.tsx +222 -267
  73. package/src/ui/collection_editor/CollectionEditorDialog.tsx +270 -198
  74. package/src/ui/collection_editor/CollectionEditorWelcomeView.tsx +138 -71
  75. package/src/ui/collection_editor/CollectionJsonImportDialog.tsx +171 -0
  76. package/src/ui/collection_editor/CollectionPropertiesEditorForm.tsx +202 -101
  77. package/src/ui/collection_editor/DisplaySettingsForm.tsx +335 -0
  78. package/src/ui/collection_editor/EntityActionsEditTab.tsx +106 -97
  79. package/src/ui/collection_editor/EntityActionsSelectDialog.tsx +8 -10
  80. package/src/ui/collection_editor/EntityCustomViewsSelectDialog.tsx +5 -7
  81. package/src/ui/collection_editor/EnumForm.tsx +153 -102
  82. package/src/ui/collection_editor/ExtendSettingsForm.tsx +94 -0
  83. package/src/ui/collection_editor/GeneralSettingsForm.tsx +335 -0
  84. package/src/ui/collection_editor/GetCodeDialog.tsx +63 -41
  85. package/src/ui/collection_editor/KanbanConfigSection.tsx +209 -0
  86. package/src/ui/collection_editor/LayoutModeSwitch.tsx +27 -43
  87. package/src/ui/collection_editor/PropertyEditView.tsx +272 -199
  88. package/src/ui/collection_editor/PropertyFieldPreview.tsx +1 -1
  89. package/src/ui/collection_editor/PropertyTree.tsx +130 -58
  90. package/src/ui/collection_editor/SubcollectionsEditTab.tsx +169 -163
  91. package/src/ui/collection_editor/UnsavedChangesDialog.tsx +0 -2
  92. package/src/ui/collection_editor/ViewModeSwitch.tsx +43 -0
  93. package/src/ui/collection_editor/import/CollectionEditorImportDataPreview.tsx +6 -3
  94. package/src/ui/collection_editor/import/CollectionEditorImportMapping.tsx +5 -2
  95. package/src/ui/collection_editor/properties/BlockPropertyField.tsx +0 -2
  96. package/src/ui/collection_editor/properties/BooleanPropertyField.tsx +4 -1
  97. package/src/ui/collection_editor/properties/CommonPropertyFields.tsx +6 -4
  98. package/src/ui/collection_editor/properties/DateTimePropertyField.tsx +126 -42
  99. package/src/ui/collection_editor/properties/EnumPropertyField.tsx +32 -24
  100. package/src/ui/collection_editor/properties/MapPropertyField.tsx +8 -9
  101. package/src/ui/collection_editor/properties/MarkdownPropertyField.tsx +128 -53
  102. package/src/ui/collection_editor/properties/NumberPropertyField.tsx +3 -1
  103. package/src/ui/collection_editor/properties/ReferencePropertyField.tsx +5 -4
  104. package/src/ui/collection_editor/properties/StoragePropertyField.tsx +47 -52
  105. package/src/ui/collection_editor/properties/StringPropertyField.tsx +3 -1
  106. package/src/ui/collection_editor/properties/UrlPropertyField.tsx +12 -10
  107. package/src/ui/collection_editor/properties/advanced/AdvancedPropertyValidation.tsx +23 -4
  108. package/src/ui/collection_editor/properties/conditions/ConditionsEditor.tsx +866 -0
  109. package/src/ui/collection_editor/properties/conditions/ConditionsPanel.tsx +28 -0
  110. package/src/ui/collection_editor/properties/conditions/EnumConditionsEditor.tsx +599 -0
  111. package/src/ui/collection_editor/properties/conditions/index.ts +6 -0
  112. package/src/ui/collection_editor/properties/conditions/property_paths.ts +92 -0
  113. package/src/ui/collection_editor/properties/validation/ArrayPropertyValidation.tsx +5 -2
  114. package/src/ui/collection_editor/properties/validation/GeneralPropertyValidation.tsx +7 -5
  115. package/src/ui/collection_editor/properties/validation/NumberPropertyValidation.tsx +10 -7
  116. package/src/ui/collection_editor/properties/validation/StringPropertyValidation.tsx +11 -9
  117. package/src/ui/collection_editor/properties/validation/ValidationPanel.tsx +5 -2
  118. package/src/useCollectionEditorPlugin.tsx +53 -22
  119. package/src/utils/validateCollectionJson.ts +380 -0
@@ -1,4 +1,4 @@
1
- import { useCustomizationController } from "@firecms/core";
1
+ import { useCustomizationController, useTranslation } from "@firecms/core";
2
2
  import { Button, Dialog, DialogActions, DialogContent, DialogTitle, Typography } from "@firecms/ui";
3
3
  import React from "react";
4
4
 
@@ -9,11 +9,12 @@ export function EntityCustomViewsSelectDialog({
9
9
  const {
10
10
  entityViews,
11
11
  } = useCustomizationController();
12
+ const { t } = useTranslation();
12
13
 
13
14
  return <Dialog
14
15
  maxWidth={"md"}
15
16
  open={open}>
16
- <DialogTitle>Select custom view</DialogTitle>
17
+ <DialogTitle>{t("select_custom_view")}</DialogTitle>
17
18
  <DialogContent className={"flex flex-col gap-4"}>
18
19
  {entityViews?.map((view) => {
19
20
  return <Button
@@ -27,15 +28,12 @@ export function EntityCustomViewsSelectDialog({
27
28
  })}
28
29
  {(entityViews ?? []).length === 0 &&
29
30
  <Typography variant={"body2"}>
30
- No custom views defined. Define your custom views in the customization settings, before using this
31
- dialog.
31
+ {t("no_custom_views_defined")}
32
32
  </Typography>
33
33
  }
34
34
  </DialogContent>
35
35
  <DialogActions>
36
- <Button variant={"outlined"}
37
- color={"primary"}
38
- onClick={() => onClose()}>Cancel</Button>
36
+ <Button onClick={() => onClose()}>{t("cancel")}</Button>
39
37
  </DialogActions>
40
38
  </Dialog>
41
39
  }
@@ -1,17 +1,22 @@
1
1
  import React, { useEffect } from "react";
2
2
  import equal from "react-fast-compare"
3
3
 
4
- import { ArrayContainer, ArrayEntryParams, EnumValueConfig, EnumValues, FieldCaption, } from "@firecms/core";
4
+ import { ArrayContainer, ArrayEntryParams, EnumValueConfig, EnumValues, FieldCaption, useTranslation
5
+ } from "@firecms/core";
5
6
  import {
6
- AutorenewIcon,
7
+ FindInPageIcon,
7
8
  Badge,
8
9
  Button,
10
+ ChipColorKey,
9
11
  CircularProgress,
12
+ ColorPicker,
10
13
  DebouncedTextField,
11
14
  Dialog,
12
15
  DialogActions,
13
16
  DialogContent,
14
17
  DialogTitle,
18
+ getColorSchemeForKey,
19
+ getColorSchemeForSeed,
15
20
  IconButton,
16
21
  ListIcon,
17
22
  Paper,
@@ -32,14 +37,16 @@ type EnumFormProps = {
32
37
  };
33
38
 
34
39
  export function EnumForm({
35
- enumValues,
36
- onValuesChanged,
37
- onError,
38
- updateIds,
39
- disabled,
40
- allowDataInference,
41
- getData
42
- }: EnumFormProps) {
40
+ enumValues,
41
+ onValuesChanged,
42
+ onError,
43
+ updateIds,
44
+ disabled,
45
+ allowDataInference,
46
+ getData
47
+ }: EnumFormProps) {
48
+ const { t } = useTranslation();
49
+
43
50
 
44
51
  const formex = useCreateFormex<{
45
52
  enumValues: EnumValueConfig[]
@@ -68,7 +75,10 @@ export function EnumForm({
68
75
  }
69
76
  });
70
77
 
71
- const { values, errors } = formex;
78
+ const {
79
+ values,
80
+ errors
81
+ } = formex;
72
82
 
73
83
  useEffect(() => {
74
84
  if (onValuesChanged) {
@@ -78,12 +88,12 @@ export function EnumForm({
78
88
 
79
89
  return <Formex value={formex}>
80
90
  <EnumFormFields enumValuesPath={"enumValues"}
81
- values={values}
82
- errors={errors}
83
- shouldUpdateId={updateIds}
84
- disabled={disabled}
85
- allowDataInference={allowDataInference}
86
- getData={getData}/>
91
+ values={values}
92
+ errors={errors}
93
+ shouldUpdateId={updateIds}
94
+ disabled={disabled}
95
+ allowDataInference={allowDataInference}
96
+ getData={getData} />
87
97
  </Formex>
88
98
 
89
99
  }
@@ -102,14 +112,14 @@ type EnumFormFieldsProps = {
102
112
 
103
113
  // const EnumFormFields = React.memo(
104
114
  function EnumFormFields({
105
- values,
106
- errors,
107
- disabled,
108
- enumValuesPath,
109
- shouldUpdateId,
110
- allowDataInference,
111
- getData,
112
- }: EnumFormFieldsProps) {
115
+ values,
116
+ errors,
117
+ disabled,
118
+ enumValuesPath,
119
+ shouldUpdateId,
120
+ allowDataInference,
121
+ getData,
122
+ }: EnumFormFieldsProps) {
113
123
 
114
124
  const {
115
125
  setFieldValue
@@ -123,25 +133,27 @@ function EnumFormFields({
123
133
  const inferredValues = inferredValuesRef.current;
124
134
 
125
135
  const buildEntry = ({
126
- index,
127
- internalId
128
- }:ArrayEntryParams) => {
136
+ index,
137
+ internalId
138
+ }: ArrayEntryParams) => {
129
139
  const justAdded = lastInternalIdAdded === internalId;
130
140
  const entryError = errors?.enumValues && errors?.enumValues[index];
131
141
  return <EnumEntry index={index}
132
- disabled={disabled}
133
- enumValuesPath={enumValuesPath}
134
- autoFocus={justAdded}
135
- entryError={entryError}
136
- shouldUpdateId={shouldUpdateId || justAdded}
137
- onDialogOpen={() => setEditDialogIndex(index)}
138
- inferredEntry={inferredValues.has(values.enumValues[index]?.id as string)}
139
- key={`${internalId}`}/>;
142
+ disabled={disabled}
143
+ enumValuesPath={enumValuesPath}
144
+ autoFocus={justAdded}
145
+ entryError={entryError}
146
+ shouldUpdateId={shouldUpdateId || justAdded}
147
+ onDialogOpen={() => setEditDialogIndex(index)}
148
+ inferredEntry={inferredValues.has(values.enumValues[index]?.id as string)}
149
+ key={`${internalId}`} />;
140
150
  };
141
151
 
142
152
  const inferValues = async () => {
143
- if (!getData)
153
+ if (!getData) {
154
+ console.warn("INTERNAL: No getData function provided for data inference");
144
155
  return;
156
+ }
145
157
  setInferring(true);
146
158
  getData?.().then((data) => {
147
159
  if (!data)
@@ -172,18 +184,18 @@ function EnumFormFields({
172
184
  return (
173
185
  <div className={"col-span-12"}>
174
186
  <div className="ml-3.5 flex flex-row items-center">
175
- <ListIcon/>
187
+ <ListIcon />
176
188
  <Typography variant={"subtitle2"}
177
- className="ml-2 grow">
189
+ className="ml-2 grow">
178
190
  Values
179
191
  </Typography>
180
192
  {allowDataInference &&
181
- <Button loading={inferring}
182
- disabled={disabled || inferring}
183
- variant={"text"}
184
- size={"small"}
185
- onClick={inferValues}>
186
- {inferring ? <CircularProgress size={"smallest"}/> : <AutorenewIcon/>}
193
+ <Button
194
+ disabled={disabled || inferring}
195
+ variant={"text"}
196
+ size={"small"}
197
+ onClick={inferValues}>
198
+ {inferring ? <CircularProgress size={"smallest"} /> : <FindInPageIcon />}
187
199
  Infer values from data
188
200
  </Button>}
189
201
  </div>
@@ -191,20 +203,23 @@ function EnumFormFields({
191
203
  <Paper className="p-4 m-1">
192
204
 
193
205
  <ArrayContainer droppableId={enumValuesPath}
194
- addLabel={"Add enum value"}
195
- value={values.enumValues}
196
- disabled={disabled}
197
- size={"small"}
198
- buildEntry={buildEntry}
199
- onInternalIdAdded={setLastInternalIdAdded}
200
- canAddElements={true}
201
- onValueChange={(value) => setFieldValue(enumValuesPath, value)}
202
- newDefaultEntry={{ id: "", label: "" }}/>
206
+ addLabel={"Add enum value"}
207
+ value={values.enumValues}
208
+ disabled={disabled}
209
+ size={"small"}
210
+ buildEntry={buildEntry}
211
+ onInternalIdAdded={setLastInternalIdAdded}
212
+ canAddElements={true}
213
+ onValueChange={(value) => setFieldValue(enumValuesPath, value)}
214
+ newDefaultEntry={{
215
+ id: "",
216
+ label: ""
217
+ }} />
203
218
 
204
219
  <EnumEntryDialog index={editDialogIndex}
205
- open={editDialogIndex !== undefined}
206
- enumValuesPath={enumValuesPath}
207
- onClose={() => setEditDialogIndex(undefined)}/>
220
+ open={editDialogIndex !== undefined}
221
+ enumValuesPath={enumValuesPath}
222
+ onClose={() => setEditDialogIndex(undefined)} />
208
223
  </Paper>
209
224
  </div>
210
225
  );
@@ -223,15 +238,15 @@ type EnumEntryProps = {
223
238
 
224
239
  const EnumEntry = React.memo(
225
240
  function EnumEntryInternal({
226
- index,
227
- shouldUpdateId: updateId,
228
- enumValuesPath,
229
- autoFocus,
230
- onDialogOpen,
231
- disabled,
232
- inferredEntry,
233
- entryError
234
- }: EnumEntryProps) {
241
+ index,
242
+ shouldUpdateId: updateId,
243
+ enumValuesPath,
244
+ autoFocus,
245
+ onDialogOpen,
246
+ disabled,
247
+ inferredEntry,
248
+ entryError
249
+ }: EnumEntryProps) {
235
250
 
236
251
  const {
237
252
  values,
@@ -256,40 +271,59 @@ const EnumEntry = React.memo(
256
271
  currentLabelRef.current = labelValue;
257
272
  }, [labelValue]);
258
273
 
274
+ const colorValue = getIn(values, `${enumValuesPath}[${index}].color`) as ChipColorKey | undefined;
275
+ const colorScheme = colorValue
276
+ ? getColorSchemeForKey(colorValue)
277
+ : idValue
278
+ ? getColorSchemeForSeed(String(idValue))
279
+ : undefined;
280
+
259
281
  return (
260
282
  <>
261
283
  <div className={"flex w-full align-center justify-center"}>
262
284
  <Field name={`${enumValuesPath}[${index}].label`}
263
- as={DebouncedTextField}
264
- className={"flex-grow"}
265
- required
266
- disabled={disabled}
267
- size="small"
268
- autoFocus={autoFocus}
269
- autoComplete="off"
270
- endAdornment={inferredEntry && <AutorenewIcon size={"small"}/>}
271
- error={Boolean(entryError?.label)}/>
272
-
273
- {!disabled &&
285
+ as={DebouncedTextField}
286
+ className={"flex-grow"}
287
+ required
288
+ disabled={disabled}
289
+ size="small"
290
+ autoFocus={autoFocus}
291
+ autoComplete="off"
292
+ endAdornment={inferredEntry && <FindInPageIcon size={"small"} />}
293
+ error={Boolean(entryError?.label)} />
294
+
295
+ {!disabled && <>
296
+ {/* Color indicator - clickable to open settings */}
297
+ <button
298
+ type="button"
299
+ onClick={() => onDialogOpen()}
300
+ className="w-5 h-5 rounded-full flex-shrink-0 self-center border border-surface-accent-200 dark:border-surface-accent-700 hover:scale-110 transition-transform cursor-pointer ml-3"
301
+ style={{
302
+ backgroundColor: colorScheme?.color ?? "#ccc"
303
+ }}
304
+ title={colorValue ? `Color: ${colorValue}` : "Auto color - Click to change"}
305
+ aria-label="Edit enum color"
306
+ />
274
307
  <Badge color={"error"} invisible={!entryError?.id}>
275
308
  <IconButton
276
309
  size="small"
277
310
  aria-label="edit"
278
311
  className={"m-1"}
279
312
  onClick={() => onDialogOpen()}>
280
- <SettingsIcon size={"small"}/>
313
+ <SettingsIcon size={"small"} />
281
314
  </IconButton>
282
- </Badge>}
315
+ </Badge>
316
+ </>}
283
317
 
284
318
  </div>
285
319
 
286
320
  {entryError?.label && <Typography variant={"caption"}
287
- className={"ml-3.5 text-red-500 dark:text-red-500"}>
321
+ className={"ml-3.5 text-red-500 dark:text-red-500"}>
288
322
  {entryError?.label}
289
323
  </Typography>}
290
324
 
291
325
  {entryError?.id && <Typography variant={"caption"}
292
- className={"ml-3.5 text-red-500 dark:text-red-500"}>
326
+ className={"ml-3.5 text-red-500 dark:text-red-500"}>
293
327
  {entryError?.id}
294
328
  </Typography>}
295
329
 
@@ -306,52 +340,69 @@ const EnumEntry = React.memo(
306
340
  );
307
341
 
308
342
  function EnumEntryDialog({
309
- index,
310
- open,
311
- onClose,
312
- enumValuesPath
313
- }: {
343
+ index,
344
+ open,
345
+ onClose,
346
+ enumValuesPath
347
+ }: {
314
348
  index?: number;
315
349
  open: boolean;
316
350
  enumValuesPath: string;
317
351
  onClose: () => void;
318
352
  }) {
353
+ const { t } = useTranslation();
319
354
 
320
355
  const {
321
356
  errors,
357
+ values,
358
+ setFieldValue
322
359
  } = useFormex<EnumValues>();
323
360
 
324
361
  const idError = index !== undefined ? getIn(errors, `${enumValuesPath}[${index}].id`) : undefined;
362
+ const colorValue = index !== undefined ? getIn(values, `${enumValuesPath}[${index}].color`) as ChipColorKey | undefined : undefined;
363
+
325
364
  return <Dialog
326
365
  maxWidth="md"
327
366
  aria-labelledby="enum-edit-dialog"
328
367
  open={open}
329
368
  onOpenChange={(open) => !open ? onClose() : undefined}
330
369
  >
331
- <DialogTitle hidden>Enum form dialog</DialogTitle>
370
+ <DialogTitle hidden>{t("enum_form_dialog")}</DialogTitle>
332
371
  <DialogContent>
333
372
  {index !== undefined &&
334
- <div>
335
- <Field name={`${enumValuesPath}[${index}].id`}
336
- as={DebouncedTextField}
337
- required
338
- label={"ID"}
339
- size="small"
340
- autoComplete="off"
341
- error={Boolean(idError)}/>
342
-
343
- <FieldCaption error={Boolean(idError)}>
344
- {idError ?? "Value saved in the data source"}
345
- </FieldCaption>
373
+ <div className="flex flex-col gap-4">
374
+ <div>
375
+ <Field name={`${enumValuesPath}[${index}].id`}
376
+ as={DebouncedTextField}
377
+ required
378
+ label={"ID"}
379
+ size="small"
380
+ autoComplete="off"
381
+ error={Boolean(idError)} />
382
+
383
+ <FieldCaption error={Boolean(idError)}>
384
+ {idError ?? "Value saved in the data source"}
385
+ </FieldCaption>
386
+ </div>
387
+
388
+ <div>
389
+ <Typography variant="body2" className="font-medium mb-2">
390
+ Chip color
391
+ </Typography>
392
+ <ColorPicker
393
+ value={colorValue}
394
+ onChange={(color) => setFieldValue(`${enumValuesPath}[${index}].color`, color)}
395
+ size="small"
396
+ allowClear={true}
397
+ />
398
+ </div>
346
399
  </div>}
347
400
  </DialogContent>
348
401
 
349
402
  <DialogActions>
350
403
  <Button
351
404
  autoFocus
352
- variant="outlined"
353
- onClick={onClose}
354
- color="primary">
405
+ onClick={onClose}>
355
406
  Ok
356
407
  </Button>
357
408
  </DialogActions>
@@ -0,0 +1,94 @@
1
+ import React from "react";
2
+ import {
3
+ EntityCollection,
4
+ User,
5
+ useTranslation
6
+ } from "@firecms/core";
7
+ import {
8
+ Button,
9
+ cls,
10
+ Container,
11
+ defaultBorderMixin,
12
+ Typography
13
+ } from "@firecms/ui";
14
+
15
+ import { useFormex } from "@firecms/formex";
16
+ import { CollectionsConfigController } from "../../types/config_controller";
17
+ import { CollectionInference } from "../../types/collection_inference";
18
+ import { SubcollectionsEditTab } from "./SubcollectionsEditTab";
19
+ import { EntityActionsEditTab } from "./EntityActionsEditTab";
20
+ import { PersistedCollection } from "../../types/persisted_collection";
21
+
22
+ export function ExtendSettingsForm({
23
+ collection,
24
+ parentCollection,
25
+ configController,
26
+ collectionInference,
27
+ getUser,
28
+ parentCollectionIds,
29
+ isMergedCollection,
30
+ onResetToCode
31
+ }: {
32
+ collection: PersistedCollection;
33
+ parentCollection?: EntityCollection;
34
+ configController: CollectionsConfigController;
35
+ collectionInference?: CollectionInference;
36
+ getUser?: (uid: string) => User | null;
37
+ parentCollectionIds?: string[];
38
+ isMergedCollection?: boolean;
39
+ onResetToCode?: () => void;
40
+ }) {
41
+
42
+ const {
43
+ values,
44
+ setFieldValue,
45
+ submitCount
46
+ } = useFormex<EntityCollection>();
47
+
48
+ const { t } = useTranslation();
49
+
50
+ return (
51
+ <div className={"overflow-auto my-auto"}>
52
+ <Container maxWidth={"4xl"} className={"flex flex-col gap-8 p-8 m-auto"}>
53
+
54
+ <div>
55
+ <Typography variant={"h5"} className={"flex-grow"}>
56
+ {t("extend_title")}
57
+ </Typography>
58
+ <Typography variant={"body2"} color={"secondary"}>
59
+ {t("extend_description")}
60
+ </Typography>
61
+ </div>
62
+
63
+ {/* Subcollections Section */}
64
+ <SubcollectionsEditTab
65
+ collection={collection}
66
+ parentCollection={parentCollection}
67
+ configController={configController}
68
+ collectionInference={collectionInference}
69
+ getUser={getUser}
70
+ parentCollectionIds={parentCollectionIds}
71
+ embedded={true}
72
+ />
73
+
74
+ {/* Entity Actions Section */}
75
+ <EntityActionsEditTab collection={collection} embedded={true} />
76
+
77
+ {/* Reset to code (for merged collections) */}
78
+ {isMergedCollection && onResetToCode && (
79
+ <div className={cls("flex flex-col gap-4 mt-8 border-t pt-8", defaultBorderMixin)}>
80
+ <Typography variant={"body2"} color={"secondary"}>
81
+ {t("collection_defined_in_code")}
82
+ </Typography>
83
+ <Button color={"neutral"} onClick={onResetToCode}>
84
+ {t("reset_to_code")}
85
+ </Button>
86
+ </div>
87
+ )}
88
+
89
+ <div style={{ height: "52px" }} />
90
+
91
+ </Container>
92
+ </div>
93
+ );
94
+ }