@firecms/collection_editor 3.0.0-canary.21 → 3.0.0-canary.211

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 (74) hide show
  1. package/LICENSE +114 -21
  2. package/dist/ConfigControllerProvider.d.ts +2 -2
  3. package/dist/index.d.ts +1 -0
  4. package/dist/index.es.js +10060 -4770
  5. package/dist/index.es.js.map +1 -1
  6. package/dist/index.umd.js +10750 -3
  7. package/dist/index.umd.js.map +1 -1
  8. package/dist/types/collection_editor_controller.d.ts +4 -2
  9. package/dist/types/collection_inference.d.ts +1 -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/CollectionViewHeaderAction.d.ts +3 -2
  13. package/dist/ui/EditorCollectionActionStart.d.ts +2 -0
  14. package/dist/ui/PropertyAddColumnComponent.d.ts +3 -1
  15. package/dist/ui/collection_editor/CollectionDetailsForm.d.ts +3 -1
  16. package/dist/ui/collection_editor/CollectionEditorDialog.d.ts +3 -2
  17. package/dist/ui/collection_editor/CollectionEditorWelcomeView.d.ts +1 -1
  18. package/dist/ui/collection_editor/CollectionPropertiesEditorForm.d.ts +1 -1
  19. package/dist/ui/collection_editor/LayoutModeSwitch.d.ts +5 -0
  20. package/dist/ui/collection_editor/PropertyEditView.d.ts +8 -0
  21. package/dist/ui/collection_editor/PropertyTree.d.ts +9 -9
  22. package/dist/ui/collection_editor/SubcollectionsEditTab.d.ts +1 -1
  23. package/dist/ui/collection_editor/import/CollectionEditorImportMapping.d.ts +7 -0
  24. package/dist/ui/collection_editor/properties/MarkdownPropertyField.d.ts +4 -0
  25. package/dist/ui/collection_editor/properties/StringPropertyField.d.ts +1 -1
  26. package/dist/useCollectionEditorPlugin.d.ts +8 -11
  27. package/dist/utils/collections.d.ts +6 -0
  28. package/package.json +24 -35
  29. package/src/ConfigControllerProvider.tsx +67 -64
  30. package/src/index.ts +1 -0
  31. package/src/types/collection_editor_controller.tsx +7 -4
  32. package/src/types/collection_inference.ts +1 -1
  33. package/src/types/config_permissions.ts +1 -1
  34. package/src/types/persisted_collection.ts +2 -3
  35. package/src/ui/CollectionViewHeaderAction.tsx +10 -5
  36. package/src/ui/EditorCollectionAction.tsx +10 -63
  37. package/src/ui/EditorCollectionActionStart.tsx +88 -0
  38. package/src/ui/HomePageEditorCollectionAction.tsx +19 -13
  39. package/src/ui/NewCollectionButton.tsx +1 -1
  40. package/src/ui/NewCollectionCard.tsx +3 -3
  41. package/src/ui/PropertyAddColumnComponent.tsx +11 -6
  42. package/src/ui/collection_editor/CollectionDetailsForm.tsx +89 -12
  43. package/src/ui/collection_editor/CollectionEditorDialog.tsx +101 -34
  44. package/src/ui/collection_editor/CollectionEditorWelcomeView.tsx +8 -7
  45. package/src/ui/collection_editor/CollectionPropertiesEditorForm.tsx +37 -36
  46. package/src/ui/collection_editor/EntityCustomViewsSelectDialog.tsx +6 -5
  47. package/src/ui/collection_editor/EnumForm.tsx +10 -6
  48. package/src/ui/collection_editor/GetCodeDialog.tsx +56 -26
  49. package/src/ui/collection_editor/LayoutModeSwitch.tsx +54 -0
  50. package/src/ui/collection_editor/PropertyEditView.tsx +257 -79
  51. package/src/ui/collection_editor/PropertyFieldPreview.tsx +7 -10
  52. package/src/ui/collection_editor/PropertyTree.tsx +9 -7
  53. package/src/ui/collection_editor/SubcollectionsEditTab.tsx +26 -19
  54. package/src/ui/collection_editor/UnsavedChangesDialog.tsx +3 -5
  55. package/src/ui/collection_editor/import/CollectionEditorImportDataPreview.tsx +26 -9
  56. package/src/ui/collection_editor/import/CollectionEditorImportMapping.tsx +42 -9
  57. package/src/ui/collection_editor/properties/BlockPropertyField.tsx +32 -20
  58. package/src/ui/collection_editor/properties/DateTimePropertyField.tsx +54 -47
  59. package/src/ui/collection_editor/properties/EnumPropertyField.tsx +3 -1
  60. package/src/ui/collection_editor/properties/MapPropertyField.tsx +7 -6
  61. package/src/ui/collection_editor/properties/MarkdownPropertyField.tsx +139 -0
  62. package/src/ui/collection_editor/properties/ReferencePropertyField.tsx +2 -0
  63. package/src/ui/collection_editor/properties/RepeatPropertyField.tsx +0 -1
  64. package/src/ui/collection_editor/properties/StoragePropertyField.tsx +34 -19
  65. package/src/ui/collection_editor/properties/StringPropertyField.tsx +1 -10
  66. package/src/ui/collection_editor/properties/UrlPropertyField.tsx +1 -0
  67. package/src/ui/collection_editor/properties/validation/ValidationPanel.tsx +2 -2
  68. package/src/ui/collection_editor/templates/pages_template.ts +1 -6
  69. package/src/useCollectionEditorPlugin.tsx +33 -32
  70. package/src/utils/collections.ts +36 -0
  71. package/dist/ui/RootCollectionSuggestions.d.ts +0 -3
  72. package/dist/ui/collection_editor/PropertySelectItem.d.ts +0 -8
  73. package/src/ui/RootCollectionSuggestions.tsx +0 -63
  74. package/src/ui/collection_editor/PropertySelectItem.tsx +0 -32
@@ -1,5 +1,5 @@
1
1
  import { CollectionEditorPermissionsBuilder } from "./config_permissions";
2
- import { Property } from "@firecms/core";
2
+ import { Entity, Property } from "@firecms/core";
3
3
  import { PersistedCollection } from "./persisted_collection";
4
4
  /**
5
5
  * Controller to open the collection editor dialog.
@@ -11,6 +11,7 @@ export interface CollectionEditorController {
11
11
  fullPath?: string;
12
12
  parentCollectionIds: string[];
13
13
  parentCollection?: PersistedCollection;
14
+ existingEntities?: Entity<any>[];
14
15
  }) => void;
15
16
  createCollection: (props: {
16
17
  initialValues?: {
@@ -30,7 +31,8 @@ export interface CollectionEditorController {
30
31
  editedCollectionId: string;
31
32
  parentCollectionIds: string[];
32
33
  collection: PersistedCollection;
34
+ existingEntities: Entity<any>[];
33
35
  }) => void;
34
36
  configPermissions: CollectionEditorPermissionsBuilder;
35
- rootPathSuggestions?: string[];
37
+ getPathSuggestions?: (path: string) => Promise<string[]>;
36
38
  }
@@ -1,2 +1,2 @@
1
1
  import { EntityCollection } from "@firecms/core";
2
- export type CollectionInference = (path: string, collectionGroup: boolean, parentCollectionIds: string[]) => Promise<Partial<EntityCollection> | null>;
2
+ export type CollectionInference = (path: string, collectionGroup: boolean, parentCollectionPaths: string[]) => Promise<Partial<EntityCollection> | null>;
@@ -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,10 +1,11 @@
1
- import { ResolvedProperty } from "@firecms/core";
1
+ import { EntityTableController, ResolvedProperty } from "@firecms/core";
2
2
  import { PersistedCollection } from "../types/persisted_collection";
3
- export declare function CollectionViewHeaderAction({ propertyKey, onHover, property, fullPath, parentCollectionIds, collection }: {
3
+ export declare function CollectionViewHeaderAction({ propertyKey, onHover, property, fullPath, parentCollectionIds, collection, tableController }: {
4
4
  property: ResolvedProperty;
5
5
  propertyKey: string;
6
6
  onHover: boolean;
7
7
  fullPath: string;
8
8
  parentCollectionIds: string[];
9
9
  collection: PersistedCollection;
10
+ tableController: EntityTableController;
10
11
  }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ import { CollectionActionsProps } from "@firecms/core";
2
+ export declare function EditorCollectionActionStart({ path: fullPath, parentCollectionIds, collection, tableController }: CollectionActionsProps): import("react/jsx-runtime").JSX.Element;
@@ -1,6 +1,8 @@
1
+ import { EntityTableController } from "@firecms/core";
1
2
  import { PersistedCollection } from "../types/persisted_collection";
2
- export declare function PropertyAddColumnComponent({ fullPath, parentCollectionIds, collection }: {
3
+ export declare function PropertyAddColumnComponent({ fullPath, parentCollectionIds, collection, tableController }: {
3
4
  fullPath: string;
4
5
  parentCollectionIds: string[];
5
6
  collection: PersistedCollection;
7
+ tableController: EntityTableController;
6
8
  }): import("react/jsx-runtime").JSX.Element;
@@ -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;
@@ -1,5 +1,5 @@
1
1
  import * as React from "react";
2
- import { EntityCollection, User } from "@firecms/core";
2
+ import { Entity, EntityCollection, User } from "@firecms/core";
3
3
  import { CollectionsConfigController } from "../../types/config_controller";
4
4
  import { CollectionInference } from "../../types/collection_inference";
5
5
  import { PersistedCollection } from "../../types/persisted_collection";
@@ -25,9 +25,10 @@ export interface CollectionEditorDialogProps {
25
25
  icon: React.ReactNode;
26
26
  };
27
27
  pathSuggestions?: (path?: string) => Promise<string[]>;
28
- getUser: (uid: string) => User | null;
28
+ getUser?: (uid: string) => User | null;
29
29
  getData?: (path: string, parentPaths: string[]) => Promise<object[]>;
30
30
  parentCollection?: PersistedCollection;
31
+ existingEntities?: Entity<any>[];
31
32
  }
32
33
  export declare function CollectionEditorDialog(props: CollectionEditorDialogProps): import("react/jsx-runtime").JSX.Element;
33
34
  export declare function CollectionEditor(props: CollectionEditorDialogProps & {
@@ -4,7 +4,7 @@ export declare function CollectionEditorWelcomeView({ path, pathSuggestions, par
4
4
  path: string;
5
5
  pathSuggestions?: (path: string) => Promise<string[]>;
6
6
  parentCollection?: EntityCollection;
7
- onContinue: (importData?: object[]) => void;
7
+ onContinue: (importData?: object[], propertiesOrder?: string[]) => void;
8
8
  existingCollectionPaths?: string[];
9
9
  }): import("react/jsx-runtime").JSX.Element;
10
10
  export declare function TemplateButton({ title, subtitle, icon, onClick }: {
@@ -9,7 +9,7 @@ type CollectionEditorFormProps = {
9
9
  setDirty?: (dirty: boolean) => void;
10
10
  reservedGroups?: string[];
11
11
  extraIcon: React.ReactNode;
12
- getUser: (uid: string) => User | null;
12
+ getUser?: (uid: string) => User | null;
13
13
  getData?: () => Promise<object[]>;
14
14
  doCollectionInference: (collection: PersistedCollection) => Promise<Partial<EntityCollection> | null> | undefined;
15
15
  propertyConfigs: Record<string, PropertyConfig>;
@@ -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;
@@ -21,6 +21,7 @@ export type PropertyFormProps = {
21
21
  property?: Property;
22
22
  onPropertyChanged?: (params: OnPropertyChangedParams) => void;
23
23
  onPropertyChangedImmediate?: boolean;
24
+ onDismiss?: () => void;
24
25
  onDelete?: (id?: string, namespace?: string) => void;
25
26
  onError?: (id: string, namespace?: string, error?: Record<string, any>) => void;
26
27
  initialErrors?: Record<string, any>;
@@ -38,3 +39,10 @@ export declare function PropertyFormDialog({ open, onCancel, onOkClicked, onProp
38
39
  onOkClicked?: () => void;
39
40
  onCancel?: () => void;
40
41
  }): import("react/jsx-runtime").JSX.Element;
42
+ export interface PropertySelectItemProps {
43
+ onClick?: () => void;
44
+ initialProperty?: PropertyWithId;
45
+ propertyConfig: PropertyConfig;
46
+ existing: boolean;
47
+ }
48
+ export declare function WidgetSelectViewItem({ onClick, initialProperty, propertyConfig, existing }: PropertySelectItemProps): import("react/jsx-runtime").JSX.Element;
@@ -4,17 +4,17 @@ import { DraggableProvided } from "@hello-pangea/dnd";
4
4
  export declare const PropertyTree: React.MemoExoticComponent<(<M extends {
5
5
  [Key: string]: CMSType;
6
6
  }>({ namespace, selectedPropertyKey, onPropertyClick, properties, propertiesOrder: propertiesOrderProp, additionalFields, errors, onPropertyMove, onPropertyRemove, className, inferredPropertyKeys, collectionEditable }: {
7
- namespace?: string | undefined;
8
- selectedPropertyKey?: string | undefined;
9
- onPropertyClick?: ((propertyKey: string, namespace?: string) => void) | undefined;
7
+ namespace?: string;
8
+ selectedPropertyKey?: string;
9
+ onPropertyClick?: (propertyKey: string, namespace?: string) => void;
10
10
  properties: PropertiesOrBuilders<M>;
11
- propertiesOrder?: string[] | undefined;
12
- additionalFields?: AdditionalFieldDelegate<M, import("@firecms/core").User>[] | undefined;
11
+ propertiesOrder?: string[];
12
+ additionalFields?: AdditionalFieldDelegate<M>[];
13
13
  errors: Record<string, any>;
14
- onPropertyMove?: ((propertiesOrder: string[], namespace?: string) => void) | undefined;
15
- onPropertyRemove?: ((propertyKey: string, namespace?: string) => void) | undefined;
16
- className?: string | undefined;
17
- inferredPropertyKeys?: string[] | undefined;
14
+ onPropertyMove?: (propertiesOrder: string[], namespace?: string) => void;
15
+ onPropertyRemove?: (propertyKey: string, namespace?: string) => void;
16
+ className?: string;
17
+ inferredPropertyKeys?: string[];
18
18
  collectionEditable: boolean;
19
19
  }) => import("react/jsx-runtime").JSX.Element)>;
20
20
  export declare function PropertyTreeEntry({ propertyKey, namespace, propertyOrBuilder, additionalField, provided, selectedPropertyKey, errors, onPropertyClick, onPropertyMove, onPropertyRemove, inferredPropertyKeys, collectionEditable }: {
@@ -7,6 +7,6 @@ export declare function SubcollectionsEditTab({ collection, parentCollection, co
7
7
  parentCollection?: EntityCollection;
8
8
  configController: CollectionsConfigController;
9
9
  collectionInference?: CollectionInference;
10
- getUser: (uid: string) => User | null;
10
+ getUser?: (uid: string) => User | null;
11
11
  parentCollectionIds?: string[];
12
12
  }): import("react/jsx-runtime").JSX.Element;
@@ -5,3 +5,10 @@ export declare function CollectionEditorImportMapping({ importConfig, propertyCo
5
5
  propertyConfigs: Record<string, PropertyConfig>;
6
6
  collectionEditable: boolean;
7
7
  }): import("react/jsx-runtime").JSX.Element;
8
+ export interface PropertySelectItemProps {
9
+ value: string;
10
+ optionDisabled: boolean;
11
+ propertyConfig: PropertyConfig;
12
+ existing: boolean;
13
+ }
14
+ export declare function PropertySelectItem({ value, optionDisabled, propertyConfig, existing }: PropertySelectItemProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,4 @@
1
+ export declare function MarkdownPropertyField({ disabled, showErrors }: {
2
+ disabled: boolean;
3
+ showErrors: boolean;
4
+ }): import("react/jsx-runtime").JSX.Element;
@@ -1,5 +1,5 @@
1
1
  export declare function StringPropertyField({ widgetId, disabled, showErrors }: {
2
- widgetId: "text_field" | "multiline" | "markdown" | "email";
2
+ widgetId: "text_field" | "multiline" | "email";
3
3
  disabled: boolean;
4
4
  showErrors: boolean;
5
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,25 +12,24 @@ 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.
19
19
  * e.g. ["admin"]
20
20
  */
21
- reservedGroups: string[];
21
+ reservedGroups?: string[];
22
22
  extraView?: {
23
23
  View: React.ComponentType<{
24
24
  path: string;
25
25
  }>;
26
26
  icon: React.ReactNode;
27
27
  };
28
- pathSuggestions?: (path: string) => Promise<string[]>;
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
- introMode?: "new_project" | "existing_project";
34
33
  }
35
34
  /**
36
35
  * Use this hook to initialise the Collection Editor plugin.
@@ -39,11 +38,9 @@ export interface CollectionConfigControllerProps<EC extends PersistedCollection
39
38
  * @param configPermissions
40
39
  * @param reservedGroups
41
40
  * @param extraView
42
- * @param pathSuggestions
41
+ * @param getData
43
42
  * @param getUser
44
43
  * @param collectionInference
45
44
  */
46
- export declare function useCollectionEditorPlugin<EC extends PersistedCollection = PersistedCollection, UserType extends User = User>({ collectionConfigController, introMode, configPermissions, reservedGroups, extraView, pathSuggestions, getUser, collectionInference, getData, onAnalyticsEvent }: CollectionConfigControllerProps<EC, UserType>): FireCMSPlugin<any, any, PersistedCollection>;
47
- export declare function IntroWidget({ introMode }: {
48
- introMode?: "new_project" | "existing_project";
49
- }): import("react/jsx-runtime").JSX.Element;
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>;
46
+ export declare function IntroWidget({}: {}): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,6 @@
1
+ import { EntityCollection, ModifyCollectionProps } from "@firecms/core";
2
+ import { PersistedCollection } from "../types/persisted_collection";
3
+ /**
4
+ * Function in charge of merging collections defined in code with those stored in the backend.
5
+ */
6
+ export declare const mergeCollections: (baseCollections: EntityCollection[], backendCollections?: PersistedCollection[], modifyCollection?: (props: ModifyCollectionProps) => EntityCollection | void) => EntityCollection<any, any>[];
package/package.json CHANGED
@@ -1,24 +1,27 @@
1
1
  {
2
2
  "name": "@firecms/collection_editor",
3
3
  "type": "module",
4
- "version": "3.0.0-canary.21",
4
+ "version": "3.0.0-canary.211",
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_import_export": "^3.0.0-canary.21",
11
- "@firecms/formex": "^3.0.0-canary.21",
12
- "@firecms/schema_inference": "^3.0.0-canary.21",
13
- "@firecms/ui": "^3.0.0-canary.21",
10
+ "@firecms/data_export": "^3.0.0-canary.211",
11
+ "@firecms/data_import": "^3.0.0-canary.211",
12
+ "@firecms/data_import_export": "^3.0.0-canary.211",
13
+ "@firecms/formex": "^3.0.0-canary.211",
14
+ "@firecms/schema_inference": "^3.0.0-canary.211",
15
+ "@firecms/ui": "^3.0.0-canary.211",
16
+ "@hello-pangea/dnd": "^17.0.0",
14
17
  "json5": "^2.2.3",
15
- "prism-react-renderer": "^2.3.1"
18
+ "prism-react-renderer": "^2.4.1"
16
19
  },
17
20
  "peerDependencies": {
18
- "react": "^18.2.0",
19
- "react-dom": "^18.2.0",
20
- "react-router": "^6.22.0",
21
- "react-router-dom": "^6.22.0"
21
+ "react": ">=18.0.0",
22
+ "react-dom": ">=18.0.0",
23
+ "react-router": "^6.28.0",
24
+ "react-router-dom": "^6.28.0"
22
25
  },
23
26
  "exports": {
24
27
  ".": {
@@ -34,12 +37,6 @@
34
37
  "build": "vite build && tsc --emitDeclarationOnly -p tsconfig.prod.json",
35
38
  "clean": "rm -rf dist && find ./src -name '*.js' -type f | xargs rm -f"
36
39
  },
37
- "eslintConfig": {
38
- "extends": [
39
- "react-app",
40
- "react-app/jest"
41
- ]
42
- },
43
40
  "browserslist": {
44
41
  "production": [
45
42
  ">0.2%",
@@ -54,25 +51,17 @@
54
51
  },
55
52
  "devDependencies": {
56
53
  "@jest/globals": "^29.7.0",
57
- "@types/react": "^18.2.67",
58
- "@types/react-dom": "^18.2.22",
59
- "@typescript-eslint/eslint-plugin": "^7.3.1",
60
- "@typescript-eslint/parser": "^7.3.1",
61
- "@vitejs/plugin-react": "^4.2.1",
62
- "eslint": "^8.57.0",
63
- "eslint-config-standard": "^17.1.0",
64
- "eslint-plugin-import": "^2.29.1",
65
- "eslint-plugin-n": "^16.6.2",
66
- "eslint-plugin-promise": "^6.1.1",
67
- "eslint-plugin-react": "^7.34.1",
68
- "eslint-plugin-react-hooks": "^4.6.0",
54
+ "@types/react": "^18.3.18",
55
+ "@types/react-dom": "^18.3.0",
56
+ "@vitejs/plugin-react": "^4.3.4",
57
+ "babel-plugin-react-compiler": "beta",
58
+ "eslint-plugin-react-compiler": "beta",
69
59
  "jest": "^29.7.0",
70
- "react-router": "^6.22.0",
71
- "react-router-dom": "^6.22.0",
72
- "ts-jest": "^29.1.2",
73
- "typescript": "^5.4.2",
74
- "vite": "^5.2.3",
75
- "vite-plugin-fonts": "^0.7.0"
60
+ "react-router": "^6.28.2",
61
+ "react-router-dom": "^6.28.2",
62
+ "ts-jest": "^29.2.5",
63
+ "typescript": "^5.7.3",
64
+ "vite": "^5.4.14"
76
65
  },
77
66
  "files": [
78
67
  "dist",
@@ -81,5 +70,5 @@
81
70
  "publishConfig": {
82
71
  "access": "public"
83
72
  },
84
- "gitHead": "e451246cf15bdd8d934b5e2a70d86f606f6292f5"
73
+ "gitHead": "ee9fd6ecade3bb23be5cfa025117be9fe2b6fd7f"
85
74
  }
@@ -1,8 +1,9 @@
1
- import React, { PropsWithChildren, useCallback, useEffect } from "react";
1
+ import React, { PropsWithChildren, useCallback } from "react";
2
2
  import equal from "react-fast-compare"
3
3
 
4
4
  import { CollectionsConfigController } from "./types/config_controller";
5
5
  import {
6
+ Entity,
6
7
  Property,
7
8
  useCustomizationController,
8
9
  useNavigationController,
@@ -48,9 +49,9 @@ export interface ConfigControllerProviderProps {
48
49
  icon: React.ReactNode
49
50
  };
50
51
 
51
- pathSuggestions?: (path?: string) => Promise<string[]>;
52
+ getPathSuggestions?: (path?: string) => Promise<string[]>;
52
53
 
53
- getUser: (uid: string) => User | null
54
+ getUser?: (uid: string) => User | null
54
55
 
55
56
  getData?: (path: string, parentPaths: string[]) => Promise<object[]>;
56
57
 
@@ -66,10 +67,10 @@ export const ConfigControllerProvider = React.memo(
66
67
  reservedGroups,
67
68
  collectionInference,
68
69
  extraView,
69
- pathSuggestions,
70
+ getPathSuggestions,
70
71
  getUser,
71
72
  getData,
72
- onAnalyticsEvent
73
+ onAnalyticsEvent,
73
74
  }: PropsWithChildren<ConfigControllerProviderProps>) {
74
75
 
75
76
  const navigation = useNavigationController();
@@ -77,20 +78,6 @@ export const ConfigControllerProvider = React.memo(
77
78
  const snackbarController = useSnackbarController();
78
79
  const { propertyConfigs } = useCustomizationController();
79
80
 
80
- const {
81
- collections
82
- } = navigation;
83
- const existingPaths = (collections ?? []).map(col => col.path.trim().toLowerCase());
84
-
85
- const [rootPathSuggestions, setRootPathSuggestions] = React.useState<string[] | undefined>();
86
- useEffect(() => {
87
- if (pathSuggestions) {
88
- pathSuggestions().then((paths) => {
89
- setRootPathSuggestions(paths.filter(p => !existingPaths.includes(p.trim().toLowerCase())));
90
- });
91
- }
92
- }, [pathSuggestions]);
93
-
94
81
  const [currentDialog, setCurrentDialog] = React.useState<{
95
82
  isNewCollection: boolean,
96
83
  parentCollection?: PersistedCollection,
@@ -102,7 +89,8 @@ export const ConfigControllerProvider = React.memo(
102
89
  group?: string,
103
90
  name?: string
104
91
  },
105
- redirect: boolean
92
+ redirect: boolean,
93
+ existingEntities?: Entity<any>[]
106
94
  }>();
107
95
 
108
96
  const [currentPropertyDialog, setCurrentPropertyDialog] = React.useState<{
@@ -115,6 +103,7 @@ export const ConfigControllerProvider = React.memo(
115
103
  fullPath?: string,
116
104
  parentCollectionIds: string[],
117
105
  collectionEditable: boolean;
106
+ existingEntities?: Entity<any>[]
118
107
  }>();
119
108
 
120
109
  const defaultConfigPermissions: CollectionEditorPermissionsBuilder = useCallback(() => ({
@@ -123,46 +112,57 @@ export const ConfigControllerProvider = React.memo(
123
112
  deleteCollections: true
124
113
  }), []);
125
114
 
126
- const editCollection = useCallback(({
127
- id,
128
- fullPath,
129
- parentCollectionIds,
130
- parentCollection
131
- }: {
115
+ const editCollection = ({
116
+ id,
117
+ fullPath,
118
+ parentCollectionIds,
119
+ parentCollection,
120
+ existingEntities
121
+ }: {
132
122
  id?: string,
133
123
  fullPath?: string,
134
124
  parentCollectionIds: string[],
135
- parentCollection?: PersistedCollection
125
+ parentCollection?: PersistedCollection,
126
+ existingEntities?: Entity<any>[]
136
127
  }) => {
137
128
  console.debug("Edit collection", id, fullPath, parentCollectionIds, parentCollection);
138
- onAnalyticsEvent?.("edit_collection", { id, fullPath });
129
+ onAnalyticsEvent?.("edit_collection", {
130
+ id,
131
+ fullPath
132
+ });
139
133
  setCurrentDialog({
140
134
  editedCollectionId: id,
141
135
  fullPath,
142
136
  parentCollectionIds,
143
137
  isNewCollection: false,
144
138
  parentCollection,
145
- redirect: false
139
+ redirect: false,
140
+ existingEntities
146
141
  });
147
- }, []);
142
+ };
148
143
 
149
- const editProperty = useCallback(({
150
- propertyKey,
151
- property,
152
- editedCollectionId,
153
- currentPropertiesOrder,
154
- parentCollectionIds,
155
- collection
156
- }: {
144
+ const editProperty = ({
145
+ propertyKey,
146
+ property,
147
+ editedCollectionId,
148
+ currentPropertiesOrder,
149
+ parentCollectionIds,
150
+ collection,
151
+ existingEntities
152
+ }: {
157
153
  propertyKey?: string,
158
154
  property?: Property,
159
155
  currentPropertiesOrder?: string[],
160
156
  editedCollectionId: string,
161
157
  parentCollectionIds: string[],
162
158
  collection: PersistedCollection,
159
+ existingEntities?: Entity<any>[]
163
160
  }) => {
164
161
  console.debug("Edit property", propertyKey, property, editedCollectionId, currentPropertiesOrder, parentCollectionIds, collection);
165
- onAnalyticsEvent?.("edit_property", { propertyKey, editedCollectionId });
162
+ onAnalyticsEvent?.("edit_property", {
163
+ propertyKey,
164
+ editedCollectionId
165
+ });
166
166
  // namespace is all the path until the last dot
167
167
  const namespace = propertyKey && propertyKey.includes(".")
168
168
  ? propertyKey.substring(0, propertyKey.lastIndexOf("."))
@@ -175,19 +175,20 @@ export const ConfigControllerProvider = React.memo(
175
175
  property,
176
176
  namespace,
177
177
  currentPropertiesOrder,
178
- editedCollectionId: editedCollectionId,
178
+ editedCollectionId,
179
179
  parentCollectionIds,
180
- collectionEditable: collection?.editable ?? false
180
+ collectionEditable: collection?.editable ?? false,
181
+ existingEntities
181
182
  });
182
- }, []);
183
+ };
183
184
 
184
- const createCollection = React.useCallback(({
185
- parentCollectionIds,
186
- parentCollection,
187
- initialValues,
188
- redirect,
189
- sourceClick
190
- }: {
185
+ const createCollection = ({
186
+ parentCollectionIds,
187
+ parentCollection,
188
+ initialValues,
189
+ redirect,
190
+ sourceClick
191
+ }: {
191
192
  parentCollectionIds: string[],
192
193
  parentCollection?: PersistedCollection
193
194
  initialValues?: {
@@ -198,8 +199,20 @@ export const ConfigControllerProvider = React.memo(
198
199
  redirect: boolean,
199
200
  sourceClick?: string
200
201
  }) => {
201
- console.debug("Create collection", { parentCollectionIds, parentCollection, initialValues, redirect, sourceClick });
202
- onAnalyticsEvent?.("create_collection", { parentCollectionIds, parentCollection, initialValues, redirect, sourceClick });
202
+ console.debug("Create collection", {
203
+ parentCollectionIds,
204
+ parentCollection,
205
+ initialValues,
206
+ redirect,
207
+ sourceClick
208
+ });
209
+ onAnalyticsEvent?.("create_collection", {
210
+ parentCollectionIds,
211
+ parentCollection,
212
+ initialValues,
213
+ redirect,
214
+ sourceClick
215
+ });
203
216
  setCurrentDialog({
204
217
  isNewCollection: true,
205
218
  parentCollectionIds,
@@ -207,17 +220,7 @@ export const ConfigControllerProvider = React.memo(
207
220
  initialValues,
208
221
  redirect
209
222
  });
210
- }, []);
211
-
212
- const getPathSuggestions = !pathSuggestions
213
- ? undefined
214
- : (path?: string) => {
215
- if (!path && rootPathSuggestions)
216
- return Promise.resolve(rootPathSuggestions);
217
- else {
218
- return pathSuggestions?.(path);
219
- }
220
- }
223
+ };
221
224
 
222
225
  return (
223
226
  <ConfigControllerContext.Provider value={collectionConfigController}>
@@ -227,7 +230,7 @@ export const ConfigControllerProvider = React.memo(
227
230
  createCollection,
228
231
  editProperty,
229
232
  configPermissions: configPermissions ?? defaultConfigPermissions,
230
- rootPathSuggestions
233
+ getPathSuggestions,
231
234
  }}>
232
235
 
233
236
  {children}
@@ -265,7 +268,7 @@ export const ConfigControllerProvider = React.memo(
265
268
  getData={getData && currentPropertyDialog?.editedCollectionId
266
269
  ? () => {
267
270
  console.debug("get data for property", currentPropertyDialog?.editedCollectionId);
268
- const resolvedPath = navigation.resolveAliasesFrom(currentPropertyDialog.editedCollectionId!)
271
+ const resolvedPath = navigation.resolveIdsFrom(currentPropertyDialog.editedCollectionId!)
269
272
  return getData(resolvedPath, []);
270
273
  }
271
274
  : undefined}
package/src/index.ts CHANGED
@@ -12,6 +12,7 @@ export {
12
12
  export {
13
13
  editableProperty, removeNonEditableProperties
14
14
  } from "./utils/entities";
15
+ export * from "./utils/collections";
15
16
 
16
17
  export type {
17
18
  CollectionsConfigController, DeleteCollectionParams, SaveCollectionParams, UpdateCollectionParams