@firecms/collection_editor 3.0.0-beta.10 → 3.0.0-beta.12

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 (46) hide show
  1. package/dist/ConfigControllerProvider.d.ts +0 -9
  2. package/dist/index.es.js +9188 -5266
  3. package/dist/index.es.js.map +1 -1
  4. package/dist/index.umd.js +9180 -5259
  5. package/dist/index.umd.js.map +1 -1
  6. package/dist/types/collection_editor_controller.d.ts +0 -10
  7. package/dist/types/config_permissions.d.ts +2 -2
  8. package/dist/types/persisted_collection.d.ts +1 -1
  9. package/dist/ui/collection_editor/CollectionDetailsForm.d.ts +3 -1
  10. package/dist/ui/collection_editor/LayoutModeSwitch.d.ts +5 -0
  11. package/dist/useCollectionEditorPlugin.d.ts +4 -13
  12. package/dist/utils/collections.d.ts +1 -1
  13. package/package.json +22 -19
  14. package/src/ConfigControllerProvider.tsx +1 -10
  15. package/src/types/collection_editor_controller.tsx +0 -7
  16. package/src/types/config_permissions.ts +1 -1
  17. package/src/types/persisted_collection.ts +2 -3
  18. package/src/ui/CollectionViewHeaderAction.tsx +1 -1
  19. package/src/ui/HomePageEditorCollectionAction.tsx +1 -0
  20. package/src/ui/NewCollectionButton.tsx +1 -1
  21. package/src/ui/PropertyAddColumnComponent.tsx +2 -2
  22. package/src/ui/collection_editor/CollectionDetailsForm.tsx +26 -10
  23. package/src/ui/collection_editor/CollectionEditorDialog.tsx +50 -8
  24. package/src/ui/collection_editor/CollectionEditorWelcomeView.tsx +2 -2
  25. package/src/ui/collection_editor/CollectionPropertiesEditorForm.tsx +3 -9
  26. package/src/ui/collection_editor/EntityCustomViewsSelectDialog.tsx +6 -5
  27. package/src/ui/collection_editor/EnumForm.tsx +10 -6
  28. package/src/ui/collection_editor/GetCodeDialog.tsx +42 -24
  29. package/src/ui/collection_editor/LayoutModeSwitch.tsx +54 -0
  30. package/src/ui/collection_editor/PropertyEditView.tsx +7 -3
  31. package/src/ui/collection_editor/PropertyFieldPreview.tsx +4 -4
  32. package/src/ui/collection_editor/PropertyTree.tsx +2 -2
  33. package/src/ui/collection_editor/UnsavedChangesDialog.tsx +3 -5
  34. package/src/ui/collection_editor/import/CollectionEditorImportDataPreview.tsx +1 -0
  35. package/src/ui/collection_editor/import/CollectionEditorImportMapping.tsx +2 -0
  36. package/src/ui/collection_editor/properties/BlockPropertyField.tsx +18 -12
  37. package/src/ui/collection_editor/properties/DateTimePropertyField.tsx +4 -0
  38. package/src/ui/collection_editor/properties/EnumPropertyField.tsx +2 -0
  39. package/src/ui/collection_editor/properties/MapPropertyField.tsx +2 -1
  40. package/src/ui/collection_editor/properties/MarkdownPropertyField.tsx +3 -3
  41. package/src/ui/collection_editor/properties/ReferencePropertyField.tsx +2 -0
  42. package/src/ui/collection_editor/properties/StoragePropertyField.tsx +3 -3
  43. package/src/ui/collection_editor/properties/UrlPropertyField.tsx +1 -0
  44. package/src/ui/collection_editor/properties/validation/ValidationPanel.tsx +1 -1
  45. package/src/useCollectionEditorPlugin.tsx +6 -15
  46. package/src/utils/collections.ts +13 -7
@@ -1,4 +1,3 @@
1
- import React from "react";
2
1
  import { CollectionEditorPermissionsBuilder } from "./config_permissions";
3
2
  import { Entity, Property } from "@firecms/core";
4
3
  import { PersistedCollection } from "./persisted_collection";
@@ -36,13 +35,4 @@ export interface CollectionEditorController {
36
35
  }) => void;
37
36
  configPermissions: CollectionEditorPermissionsBuilder;
38
37
  getPathSuggestions?: (path: string) => Promise<string[]>;
39
- components?: {
40
- /**
41
- * Custom component to render the database field
42
- */
43
- DatabaseField?: React.ComponentType<{
44
- databaseId?: string;
45
- onDatabaseIdUpdate: (databaseId: string) => void;
46
- }>;
47
- };
48
38
  }
@@ -1,6 +1,6 @@
1
1
  import { EntityCollection } from "@firecms/core";
2
- export type CollectionEditorPermissionsBuilder<UserType = any, EC extends EntityCollection = EntityCollection> = (params: {
3
- user: UserType | null;
2
+ export type CollectionEditorPermissionsBuilder<USER = any, EC extends EntityCollection = EntityCollection> = (params: {
3
+ user: USER | null;
4
4
  collection?: EC;
5
5
  }) => CollectionEditorPermissions;
6
6
  export type CollectionEditorPermissions = {
@@ -1,5 +1,5 @@
1
1
  import { EntityCollection, User } from "@firecms/core";
2
- export type PersistedCollection<M extends Record<string, any> = any, UserType extends User = User> = Omit<EntityCollection<M, UserType>, "subcollections"> & {
2
+ export type PersistedCollection<M extends Record<string, any> = any, USER extends User = User> = Omit<EntityCollection<M, USER>, "subcollections"> & {
3
3
  ownerId?: string;
4
4
  subcollections?: PersistedCollection<any, any>[];
5
5
  editable?: boolean;
@@ -1,5 +1,6 @@
1
+ import React from "react";
1
2
  import { EntityCollection } from "@firecms/core";
2
- export declare function CollectionDetailsForm({ isNewCollection, reservedGroups, existingPaths, existingIds, groups, parentCollection }: {
3
+ export declare function CollectionDetailsForm({ isNewCollection, reservedGroups, existingPaths, existingIds, groups, parentCollection, children }: {
3
4
  isNewCollection: boolean;
4
5
  reservedGroups?: string[];
5
6
  existingPaths?: string[];
@@ -7,4 +8,5 @@ export declare function CollectionDetailsForm({ isNewCollection, reservedGroups,
7
8
  groups: string[] | null;
8
9
  parentCollection?: EntityCollection;
9
10
  parentCollectionIds?: string[];
11
+ children?: React.ReactNode;
10
12
  }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,5 @@
1
+ export declare function LayoutModeSwitch({ value, onChange, className }: {
2
+ value: "side_panel" | "full_screen";
3
+ onChange: (value: "side_panel" | "full_screen") => void;
4
+ className?: string;
5
+ }): import("react/jsx-runtime").JSX.Element;
@@ -4,7 +4,7 @@ import { CollectionEditorPermissionsBuilder } from "./types/config_permissions";
4
4
  import { PersistedCollection } from "./types/persisted_collection";
5
5
  import { CollectionInference } from "./types/collection_inference";
6
6
  import { CollectionsConfigController } from "./types/config_controller";
7
- export interface CollectionConfigControllerProps<EC extends PersistedCollection = PersistedCollection, UserType extends User = User> {
7
+ export interface CollectionConfigControllerProps<EC extends PersistedCollection = PersistedCollection, USER extends User = User> {
8
8
  /**
9
9
  * Firebase app where the configuration is saved.
10
10
  */
@@ -12,7 +12,7 @@ export interface CollectionConfigControllerProps<EC extends PersistedCollection
12
12
  /**
13
13
  * Define what actions can be performed on the configuration.
14
14
  */
15
- configPermissions?: CollectionEditorPermissionsBuilder<UserType, EC>;
15
+ configPermissions?: CollectionEditorPermissionsBuilder<USER, EC>;
16
16
  /**
17
17
  * The words you define here will not be allowed to be used as group
18
18
  * names when creating collections.
@@ -28,17 +28,8 @@ export interface CollectionConfigControllerProps<EC extends PersistedCollection
28
28
  getPathSuggestions?: (path?: string) => Promise<string[]>;
29
29
  collectionInference?: CollectionInference;
30
30
  getData?: (path: string, parentPaths: string[]) => Promise<object[]>;
31
- getUser?: (uid: string) => UserType | null;
31
+ getUser?: (uid: string) => USER | null;
32
32
  onAnalyticsEvent?: (event: string, params?: object) => void;
33
- components?: {
34
- /**
35
- * Custom component to render the database field
36
- */
37
- DatabaseField?: React.ComponentType<{
38
- databaseId?: string;
39
- onDatabaseIdUpdate: (databaseId: string) => void;
40
- }>;
41
- };
42
33
  }
43
34
  /**
44
35
  * Use this hook to initialise the Collection Editor plugin.
@@ -51,5 +42,5 @@ export interface CollectionConfigControllerProps<EC extends PersistedCollection
51
42
  * @param getUser
52
43
  * @param collectionInference
53
44
  */
54
- export declare function useCollectionEditorPlugin<EC extends PersistedCollection = PersistedCollection, UserType extends User = User>({ collectionConfigController, configPermissions, reservedGroups, extraView, getPathSuggestions, getUser, collectionInference, getData, onAnalyticsEvent, components }: CollectionConfigControllerProps<EC, UserType>): FireCMSPlugin<any, any, PersistedCollection>;
45
+ export declare function useCollectionEditorPlugin<EC extends PersistedCollection = PersistedCollection, USER extends User = User>({ collectionConfigController, configPermissions, reservedGroups, extraView, getPathSuggestions, getUser, collectionInference, getData, onAnalyticsEvent, }: CollectionConfigControllerProps<EC, USER>): FireCMSPlugin<any, any, PersistedCollection>;
55
46
  export declare function IntroWidget({}: {}): import("react/jsx-runtime").JSX.Element | null;
@@ -3,4 +3,4 @@ import { PersistedCollection } from "../types/persisted_collection";
3
3
  /**
4
4
  * Function in charge of merging collections defined in code with those stored in the backend.
5
5
  */
6
- export declare const mergeCollections: (baseCollections: EntityCollection[], backendCollections: PersistedCollection[], modifyCollection?: (props: ModifyCollectionProps) => EntityCollection | void) => EntityCollection<any, any>[];
6
+ export declare const mergeCollections: (baseCollections: EntityCollection[], backendCollections?: PersistedCollection[], modifyCollection?: (props: ModifyCollectionProps) => EntityCollection | void) => EntityCollection<any, any>[];
package/package.json CHANGED
@@ -1,26 +1,27 @@
1
1
  {
2
2
  "name": "@firecms/collection_editor",
3
3
  "type": "module",
4
- "version": "3.0.0-beta.10",
4
+ "version": "3.0.0-beta.12",
5
5
  "main": "./dist/index.umd.js",
6
6
  "module": "./dist/index.es.js",
7
7
  "types": "dist/index.d.ts",
8
8
  "source": "src/index.ts",
9
9
  "dependencies": {
10
- "@firecms/data_export": "^3.0.0-beta.10",
11
- "@firecms/data_import": "^3.0.0-beta.10",
12
- "@firecms/data_import_export": "^3.0.0-beta.10",
13
- "@firecms/formex": "^3.0.0-beta.10",
14
- "@firecms/schema_inference": "^3.0.0-beta.10",
15
- "@firecms/ui": "^3.0.0-beta.10",
10
+ "@firecms/data_export": "^3.0.0-beta.12",
11
+ "@firecms/data_import": "^3.0.0-beta.12",
12
+ "@firecms/data_import_export": "^3.0.0-beta.12",
13
+ "@firecms/formex": "^3.0.0-beta.12",
14
+ "@firecms/schema_inference": "^3.0.0-beta.12",
15
+ "@firecms/ui": "^3.0.0-beta.12",
16
+ "@hello-pangea/dnd": "^17.0.0",
16
17
  "json5": "^2.2.3",
17
- "prism-react-renderer": "^2.4.0"
18
+ "prism-react-renderer": "^2.4.1"
18
19
  },
19
20
  "peerDependencies": {
20
- "react": "^18.3.1",
21
- "react-dom": "^18.3.1",
22
- "react-router": "^6.25.1",
23
- "react-router-dom": "^6.25.1"
21
+ "react": ">=18.0.0",
22
+ "react-dom": ">=18.0.0",
23
+ "react-router": "^6.28.0",
24
+ "react-router-dom": "^6.28.0"
24
25
  },
25
26
  "exports": {
26
27
  ".": {
@@ -50,15 +51,17 @@
50
51
  },
51
52
  "devDependencies": {
52
53
  "@jest/globals": "^29.7.0",
53
- "@types/react": "^18.3.11",
54
+ "@types/react": "^18.3.18",
54
55
  "@types/react-dom": "^18.3.0",
55
- "@vitejs/plugin-react": "^4.3.2",
56
+ "@vitejs/plugin-react": "^4.3.4",
57
+ "babel-plugin-react-compiler": "beta",
58
+ "eslint-plugin-react-compiler": "beta",
56
59
  "jest": "^29.7.0",
57
- "react-router": "^6.26.2",
58
- "react-router-dom": "^6.26.2",
60
+ "react-router": "^6.28.2",
61
+ "react-router-dom": "^6.28.2",
59
62
  "ts-jest": "^29.2.5",
60
- "typescript": "^5.6.3",
61
- "vite": "^5.4.8"
63
+ "typescript": "^5.7.3",
64
+ "vite": "^5.4.14"
62
65
  },
63
66
  "files": [
64
67
  "dist",
@@ -67,5 +70,5 @@
67
70
  "publishConfig": {
68
71
  "access": "public"
69
72
  },
70
- "gitHead": "f844c3f86094efec6c33313c3f106f30cdcd309f"
73
+ "gitHead": "8de3edb4560643922fe44e9c357985f64c3951c1"
71
74
  }
@@ -57,13 +57,6 @@ export interface ConfigControllerProviderProps {
57
57
 
58
58
  onAnalyticsEvent?: (event: string, params?: object) => void;
59
59
 
60
- components?: {
61
- /**
62
- * Custom component to render the database field
63
- */
64
- DatabaseField?: React.ComponentType<{ databaseId?: string, onDatabaseIdUpdate: (databaseId:string) => void }>;
65
- };
66
-
67
60
  }
68
61
 
69
62
  export const ConfigControllerProvider = React.memo(
@@ -78,7 +71,6 @@ export const ConfigControllerProvider = React.memo(
78
71
  getUser,
79
72
  getData,
80
73
  onAnalyticsEvent,
81
- components
82
74
  }: PropsWithChildren<ConfigControllerProviderProps>) {
83
75
 
84
76
  const navigation = useNavigationController();
@@ -239,7 +231,6 @@ export const ConfigControllerProvider = React.memo(
239
231
  editProperty,
240
232
  configPermissions: configPermissions ?? defaultConfigPermissions,
241
233
  getPathSuggestions,
242
- components
243
234
  }}>
244
235
 
245
236
  {children}
@@ -277,7 +268,7 @@ export const ConfigControllerProvider = React.memo(
277
268
  getData={getData && currentPropertyDialog?.editedCollectionId
278
269
  ? () => {
279
270
  console.debug("get data for property", currentPropertyDialog?.editedCollectionId);
280
- const resolvedPath = navigation.resolveAliasesFrom(currentPropertyDialog.editedCollectionId!)
271
+ const resolvedPath = navigation.resolveIdsFrom(currentPropertyDialog.editedCollectionId!)
281
272
  return getData(resolvedPath, []);
282
273
  }
283
274
  : undefined}
@@ -43,11 +43,4 @@ export interface CollectionEditorController {
43
43
 
44
44
  getPathSuggestions?: (path: string) => Promise<string[]>;
45
45
 
46
- components?: {
47
- /**
48
- * Custom component to render the database field
49
- */
50
- DatabaseField?: React.ComponentType<{ databaseId?: string, onDatabaseIdUpdate: (databaseId: string) => void }>;
51
- };
52
-
53
46
  }
@@ -1,6 +1,6 @@
1
1
  import { EntityCollection } from "@firecms/core";
2
2
 
3
- export type CollectionEditorPermissionsBuilder<UserType = any, EC extends EntityCollection = EntityCollection> = (params: { user: UserType | null, collection?: EC }) => CollectionEditorPermissions;
3
+ export type CollectionEditorPermissionsBuilder<USER = any, EC extends EntityCollection = EntityCollection> = (params: { user: USER | null, collection?: EC }) => CollectionEditorPermissions;
4
4
 
5
5
  export type CollectionEditorPermissions = {
6
6
  /**
@@ -1,8 +1,7 @@
1
1
  import { EntityCollection, User } from "@firecms/core";
2
2
 
3
- export type PersistedCollection<M extends Record<string, any> = any, UserType extends User = User>
4
- = Omit<EntityCollection<M, UserType>, "subcollections"> & {
5
- // properties: Properties<M>;
3
+ export type PersistedCollection<M extends Record<string, any> = any, USER extends User = User>
4
+ = Omit<EntityCollection<M, USER>, "subcollections"> & {
6
5
  ownerId?: string;
7
6
  subcollections?: PersistedCollection<any, any>[];
8
7
  editable?: boolean;
@@ -29,7 +29,7 @@ export function CollectionViewHeaderAction({
29
29
  asChild={true}
30
30
  title={"Edit"}>
31
31
  <IconButton
32
- className={onHover ? "bg-white dark:bg-gray-950" : "hidden"}
32
+ className={onHover ? "bg-white dark:bg-surface-950" : "hidden"}
33
33
  onClick={() => {
34
34
  collectionEditorController.editProperty({
35
35
  propertyKey,
@@ -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();
@@ -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({
@@ -29,8 +29,8 @@ export function PropertyAddColumnComponent({
29
29
  asChild={true}
30
30
  title={canEditCollection ? "Add new property" : "You don't have permission to add new properties"}>
31
31
  <div
32
- 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"}
33
- // 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}
34
34
  onClick={() => {
35
35
  collectionEditorController.editProperty({
36
36
  editedCollectionId: collection.id,
@@ -5,7 +5,7 @@ import {
5
5
  AutocompleteItem,
6
6
  BooleanSwitchWithLabel,
7
7
  Chip,
8
- ClearIcon,
8
+ CloseIcon,
9
9
  cls,
10
10
  Container,
11
11
  DebouncedTextField,
@@ -23,6 +23,7 @@ import {
23
23
 
24
24
  import { Field, getIn, useFormex } from "@firecms/formex";
25
25
  import { useCollectionEditorController } from "../../useCollectionEditorController";
26
+ import { LayoutModeSwitch } from "./LayoutModeSwitch";
26
27
 
27
28
  export function CollectionDetailsForm({
28
29
  isNewCollection,
@@ -30,7 +31,8 @@ export function CollectionDetailsForm({
30
31
  existingPaths,
31
32
  existingIds,
32
33
  groups,
33
- parentCollection
34
+ parentCollection,
35
+ children
34
36
  }: {
35
37
  isNewCollection: boolean,
36
38
  reservedGroups?: string[];
@@ -39,6 +41,7 @@ export function CollectionDetailsForm({
39
41
  groups: string[] | null;
40
42
  parentCollection?: EntityCollection;
41
43
  parentCollectionIds?: string[];
44
+ children?: React.ReactNode;
42
45
  }) {
43
46
 
44
47
  const groupRef = React.useRef<HTMLInputElement>(null);
@@ -88,8 +91,6 @@ export function CollectionDetailsForm({
88
91
  }
89
92
  }, [errors.id]);
90
93
 
91
- const DatabaseField = collectionEditor.components?.DatabaseField ?? DefaultDatabaseField;
92
-
93
94
  const collectionIcon = <IconForView collectionOrView={values}/>;
94
95
 
95
96
  const groupOptions = groups?.filter((group) => !reservedGroups?.includes(group));
@@ -126,8 +127,8 @@ export function CollectionDetailsForm({
126
127
  <Typography variant={!isNewCollection ? "h5" : "h4"} className={"flex-grow"}>
127
128
  {isNewCollection ? "New collection" : `${values?.name} collection`}
128
129
  </Typography>
129
- <DatabaseField databaseId={values.databaseId}
130
- onDatabaseIdUpdate={updateDatabaseId}/>
130
+ <DefaultDatabaseField databaseId={values.databaseId}
131
+ onDatabaseIdUpdate={updateDatabaseId}/>
131
132
 
132
133
  <Tooltip title={"Change icon"}
133
134
  asChild={true}>
@@ -207,14 +208,21 @@ export function CollectionDetailsForm({
207
208
  <FieldCaption>
208
209
  {showErrors && Boolean(errors.group) ? errors.group : "Group in the home page"}
209
210
  </FieldCaption>
211
+
212
+
210
213
  </div>}
211
214
 
212
- <div className={"col-span-12"}>
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 mt-8"}>
213
221
  <ExpandablePanel
214
222
  expanded={advancedPanelExpanded}
215
223
  onExpandedChange={setAdvancedPanelExpanded}
216
224
  title={
217
- <div className="flex flex-row text-gray-500">
225
+ <div className="flex flex-row text-surface-500">
218
226
  <SettingsIcon/>
219
227
  <Typography variant={"subtitle2"}
220
228
  className="ml-2">
@@ -271,7 +279,7 @@ export function CollectionDetailsForm({
271
279
  setFieldValue("sideDialogWidth", null);
272
280
  }}
273
281
  disabled={!values.sideDialogWidth}>
274
- <ClearIcon size={"small"}/>
282
+ <CloseIcon size={"small"}/>
275
283
  </IconButton>}
276
284
  value={values.sideDialogWidth ?? ""}
277
285
  label={"Side dialog width"}/>
@@ -298,6 +306,8 @@ export function CollectionDetailsForm({
298
306
  <div className={"col-span-12"}>
299
307
  <Select
300
308
  name="defaultSize"
309
+ size={"large"}
310
+ fullWidth={true}
301
311
  label="Default row size"
302
312
  position={"item-aligned"}
303
313
  onChange={handleChange}
@@ -318,6 +328,8 @@ export function CollectionDetailsForm({
318
328
  name="customId"
319
329
  label="Document IDs generation"
320
330
  position={"item-aligned"}
331
+ size={"large"}
332
+ fullWidth={true}
321
333
  disabled={customIdValue === "code_defined"}
322
334
  onValueChange={(v) => {
323
335
  if (v === "code_defined")
@@ -378,9 +390,13 @@ export function CollectionDetailsForm({
378
390
  for large collections, as it may incur in performance and cost issues.
379
391
  </FieldCaption>
380
392
  </div>
393
+
394
+
381
395
  </div>
382
396
  </ExpandablePanel>
383
397
 
398
+ {children}
399
+
384
400
  </div>
385
401
 
386
402
  </div>
@@ -416,7 +432,7 @@ function DefaultDatabaseField({
416
432
  return <Tooltip title={"Database ID"}
417
433
  side={"top"}
418
434
  align={"start"}>
419
- <TextField size={"smallest"}
435
+ <TextField size={"small"}
420
436
  invisible={true}
421
437
  inputClassName={"text-end"}
422
438
  value={databaseId ?? ""}
@@ -2,6 +2,7 @@ import * as React from "react";
2
2
  import { useEffect, useRef, useState } from "react";
3
3
  import {
4
4
  CircularProgressCenter,
5
+ ConfirmationDialog,
5
6
  Entity,
6
7
  EntityCollection,
7
8
  ErrorView,
@@ -26,17 +27,19 @@ import {
26
27
  import {
27
28
  ArrowBackIcon,
28
29
  Button,
30
+ CheckIcon,
29
31
  cls,
30
32
  coolIconKeys,
31
33
  defaultBorderMixin,
32
34
  Dialog,
33
35
  DialogActions,
34
36
  DialogContent,
35
- DoneIcon,
37
+ DialogTitle,
36
38
  IconButton,
37
39
  LoadingButton,
38
40
  Tab,
39
- Tabs
41
+ Tabs,
42
+ Typography
40
43
  } from "@firecms/ui";
41
44
  import { YupSchema } from "./CollectionYupValidation";
42
45
  import { CollectionDetailsForm } from "./CollectionDetailsForm";
@@ -114,6 +117,7 @@ export function CollectionEditorDialog(props: CollectionEditorDialogProps) {
114
117
  maxWidth={"7xl"}
115
118
  onOpenChange={(open) => !open ? handleCancel() : undefined}
116
119
  >
120
+ <DialogTitle hidden>Collection editor</DialogTitle>
117
121
  {open && <CollectionEditor {...props}
118
122
  handleCancel={handleCancel}
119
123
  setFormDirty={setFormDirty}/>}
@@ -276,6 +280,7 @@ function CollectionEditorInternal<M extends Record<string, any>>({
276
280
 
277
281
  const saveCollection = (updatedCollection: PersistedCollection<M>): Promise<boolean> => {
278
282
  const id = updatedCollection.id || updatedCollection.path;
283
+
279
284
  return configController.saveCollection({
280
285
  id,
281
286
  collectionData: updatedCollection,
@@ -377,7 +382,7 @@ function CollectionEditorInternal<M extends Record<string, any>>({
377
382
 
378
383
  if (!isNewCollection) {
379
384
  saveCollection(newCollectionState).then(() => {
380
- formexController.resetForm({ values: initialValues });
385
+ formexController.resetForm();
381
386
  handleClose(newCollectionState);
382
387
  });
383
388
  return;
@@ -466,7 +471,8 @@ function CollectionEditorInternal<M extends Record<string, any>>({
466
471
  const formController = useCreateFormex<PersistedCollection<M>>({
467
472
  initialValues,
468
473
  onSubmit,
469
- validation
474
+ validation,
475
+ debugId: "COLLECTION_EDITOR"
470
476
  });
471
477
 
472
478
  const {
@@ -483,7 +489,7 @@ function CollectionEditorInternal<M extends Record<string, any>>({
483
489
  const pathError = validatePath(path, isNewCollection, existingPaths, values.id);
484
490
 
485
491
  const parentPaths = !pathError && parentCollectionIds ? navigation.convertIdsToPaths(parentCollectionIds) : undefined;
486
- const resolvedPath = !pathError ? navigation.resolveAliasesFrom(updatedFullPath) : undefined;
492
+ const resolvedPath = !pathError ? navigation.resolveIdsFrom(updatedFullPath) : undefined;
487
493
  const getDataWithPath = resolvedPath && getData ? async () => {
488
494
  const data = await getData(resolvedPath, parentPaths ?? []);
489
495
  if (existingEntities) {
@@ -529,14 +535,30 @@ function CollectionEditorInternal<M extends Record<string, any>>({
529
535
  };
530
536
 
531
537
  const editable = collection?.editable === undefined || collection?.editable === true;
538
+ // @ts-ignore
539
+ const isMergedCollection = collection?.merged ?? false;
532
540
  const collectionEditable = editable || isNewCollection;
533
541
 
542
+ const [deleteRequested, setDeleteRequested] = useState(false);
543
+
544
+ const deleteCollection = () => {
545
+ if (!collection) return;
546
+ configController?.deleteCollection({ id: collection.id }).then(() => {
547
+ setDeleteRequested(false);
548
+ handleCancel();
549
+ snackbarController.open({
550
+ message: "Collection deleted",
551
+ type: "success"
552
+ });
553
+ });
554
+ };
555
+
534
556
  return <DialogContent fullHeight={true}>
535
557
  <Formex value={formController}>
536
558
 
537
559
  <>
538
560
  {!isNewCollection && <Tabs value={currentView}
539
- className={cls(defaultBorderMixin, "justify-end bg-gray-50 dark:bg-gray-950 border-b")}
561
+ innerClassName={cls(defaultBorderMixin, "px-4 h-14 w-full justify-end bg-surface-50 dark:bg-surface-950 border-b")}
540
562
  onValueChange={(v) => setCurrentView(v as EditorView)}>
541
563
  <Tab value={"details"}>
542
564
  Details
@@ -610,7 +632,18 @@ function CollectionEditorInternal<M extends Record<string, any>>({
610
632
  groups={groups}
611
633
  parentCollectionIds={parentCollectionIds}
612
634
  parentCollection={parentCollection}
613
- isNewCollection={isNewCollection}/>}
635
+ isNewCollection={isNewCollection}>
636
+ {!isNewCollection && isMergedCollection && <div className={"flex flex-col gap-4 mt-8"}>
637
+ <Typography variant={"body2"} color={"secondary"}>This collection is defined in code.
638
+ The changes done in this editor will override the properties defined in code.
639
+ You can delete the overridden values to revert to the state defined in code.
640
+ </Typography>
641
+ <Button variant={"neutral"}
642
+ onClick={() => {
643
+ setDeleteRequested(true);
644
+ }}>Reset to code</Button>
645
+ </div>}
646
+ </CollectionDetailsForm>}
614
647
 
615
648
  {currentView === "subcollections" && collection &&
616
649
  <SubcollectionsEditTab
@@ -722,7 +755,7 @@ function CollectionEditorInternal<M extends Record<string, any>>({
722
755
  loading={isSubmitting}
723
756
  disabled={isSubmitting || (currentView === "details" && !validValues)}
724
757
  startIcon={currentView === "properties"
725
- ? <DoneIcon/>
758
+ ? <CheckIcon/>
726
759
  : undefined}
727
760
  >
728
761
  {currentView === "details" && "Next"}
@@ -744,6 +777,15 @@ function CollectionEditorInternal<M extends Record<string, any>>({
744
777
 
745
778
  </Formex>
746
779
 
780
+ <ConfirmationDialog
781
+ open={deleteRequested}
782
+ onAccept={deleteCollection}
783
+ onCancel={() => setDeleteRequested(false)}
784
+ title={<>Delete the stored config?</>}
785
+ body={<> This will <b>not
786
+ delete any data</b>, only
787
+ the stored config, and reset to the code state.</>}/>
788
+
747
789
  </DialogContent>
748
790
 
749
791
  }
@@ -191,9 +191,9 @@ export function TemplateButton({
191
191
  onClick={onClick}
192
192
  className={cls(
193
193
  "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",
194
- "text-gray-700 dark:text-slate-300",
194
+ "text-surface-700 dark:text-surface-accent-300",
195
195
  "hover:border-primary-dark hover:text-primary-dark dark:hover:text-primary focus:ring-primary hover:ring-1 hover:ring-primary",
196
- "border-gray-400 dark:border-gray-600 "
196
+ "border-surface-400 dark:border-surface-600 "
197
197
  )}
198
198
  >
199
199
  {icon}
@@ -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,
@@ -233,12 +233,6 @@ export function CollectionPropertiesEditorForm({
233
233
 
234
234
  // If the id has changed we need to a little cleanup
235
235
  if (previousId && previousId !== id) {
236
- console.debug("onPropertyChanged, id change", {
237
- id,
238
- property,
239
- previousId,
240
- namespace
241
- })
242
236
 
243
237
  const previousFullId = getFullId(previousId, namespace);
244
238
  const previousPropertyPath = idToPropertiesPath(previousFullId);
@@ -316,7 +310,7 @@ export function CollectionPropertiesEditorForm({
316
310
  };
317
311
 
318
312
  const body = (
319
- <div className={"grid grid-cols-12 gap-2 h-full bg-gray-50 dark:bg-gray-900"}>
313
+ <div className={"grid grid-cols-12 gap-2 h-full bg-surface-50 dark:bg-surface-900"}>
320
314
  <div className={cls(
321
315
  "p-4 md:p-8 pb-20 md:pb-20",
322
316
  "col-span-12 lg:col-span-5 h-full overflow-auto",
@@ -366,7 +360,7 @@ export function CollectionPropertiesEditorForm({
366
360
  variant={"filled"}
367
361
  disabled={inferringProperties}
368
362
  onClick={inferPropertiesFromData}>
369
- {inferringProperties ? <CircularProgress size={"small"}/> : <AutoAwesomeIcon/>}
363
+ {inferringProperties ? <CircularProgress size={"small"}/> : <AutorenewIcon/>}
370
364
  </IconButton>
371
365
  </Tooltip>}
372
366
  <Tooltip title={"Add new property"}
@@ -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}