@firecms/collection_editor 3.0.0-beta.7 → 3.0.0-beta.9

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 (37) hide show
  1. package/LICENSE +2 -1
  2. package/dist/ConfigControllerProvider.d.ts +9 -0
  3. package/dist/index.es.js +4633 -3467
  4. package/dist/index.es.js.map +1 -1
  5. package/dist/index.umd.js +6679 -3
  6. package/dist/index.umd.js.map +1 -1
  7. package/dist/types/collection_editor_controller.d.ts +13 -1
  8. package/dist/ui/CollectionViewHeaderAction.d.ts +3 -2
  9. package/dist/ui/PropertyAddColumnComponent.d.ts +3 -1
  10. package/dist/ui/collection_editor/CollectionEditorDialog.d.ts +2 -1
  11. package/dist/ui/collection_editor/properties/MarkdownPropertyField.d.ts +4 -0
  12. package/dist/ui/collection_editor/properties/StringPropertyField.d.ts +1 -1
  13. package/dist/useCollectionEditorPlugin.d.ts +11 -2
  14. package/package.json +16 -30
  15. package/src/ConfigControllerProvider.tsx +26 -8
  16. package/src/types/collection_editor_controller.tsx +13 -3
  17. package/src/ui/CollectionViewHeaderAction.tsx +9 -4
  18. package/src/ui/EditorCollectionAction.tsx +10 -12
  19. package/src/ui/EditorCollectionActionStart.tsx +1 -0
  20. package/src/ui/HomePageEditorCollectionAction.tsx +11 -6
  21. package/src/ui/PropertyAddColumnComponent.tsx +9 -4
  22. package/src/ui/collection_editor/CollectionDetailsForm.tsx +34 -4
  23. package/src/ui/collection_editor/CollectionEditorDialog.tsx +12 -2
  24. package/src/ui/collection_editor/CollectionEditorWelcomeView.tsx +2 -1
  25. package/src/ui/collection_editor/CollectionPropertiesEditorForm.tsx +6 -3
  26. package/src/ui/collection_editor/GetCodeDialog.tsx +1 -1
  27. package/src/ui/collection_editor/PropertyEditView.tsx +10 -3
  28. package/src/ui/collection_editor/PropertySelectItem.tsx +1 -1
  29. package/src/ui/collection_editor/PropertyTree.tsx +4 -2
  30. package/src/ui/collection_editor/SubcollectionsEditTab.tsx +5 -3
  31. package/src/ui/collection_editor/properties/DateTimePropertyField.tsx +50 -47
  32. package/src/ui/collection_editor/properties/EnumPropertyField.tsx +1 -1
  33. package/src/ui/collection_editor/properties/MarkdownPropertyField.tsx +139 -0
  34. package/src/ui/collection_editor/properties/StoragePropertyField.tsx +31 -16
  35. package/src/ui/collection_editor/properties/StringPropertyField.tsx +1 -10
  36. package/src/ui/collection_editor/templates/pages_template.ts +0 -5
  37. package/src/useCollectionEditorPlugin.tsx +13 -4
@@ -1,5 +1,6 @@
1
+ import React from "react";
1
2
  import { CollectionEditorPermissionsBuilder } from "./config_permissions";
2
- import { Property } from "@firecms/core";
3
+ import { Entity, Property } from "@firecms/core";
3
4
  import { PersistedCollection } from "./persisted_collection";
4
5
  /**
5
6
  * Controller to open the collection editor dialog.
@@ -11,6 +12,7 @@ export interface CollectionEditorController {
11
12
  fullPath?: string;
12
13
  parentCollectionIds: string[];
13
14
  parentCollection?: PersistedCollection;
15
+ existingEntities?: Entity<any>[];
14
16
  }) => void;
15
17
  createCollection: (props: {
16
18
  initialValues?: {
@@ -30,7 +32,17 @@ export interface CollectionEditorController {
30
32
  editedCollectionId: string;
31
33
  parentCollectionIds: string[];
32
34
  collection: PersistedCollection;
35
+ existingEntities: Entity<any>[];
33
36
  }) => void;
34
37
  configPermissions: CollectionEditorPermissionsBuilder;
35
38
  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
+ };
36
48
  }
@@ -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;
@@ -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,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";
@@ -28,6 +28,7 @@ export interface CollectionEditorDialogProps {
28
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 & {
@@ -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;
@@ -30,6 +30,15 @@ export interface CollectionConfigControllerProps<EC extends PersistedCollection
30
30
  getData?: (path: string, parentPaths: string[]) => Promise<object[]>;
31
31
  getUser?: (uid: string) => UserType | 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
+ };
33
42
  }
34
43
  /**
35
44
  * Use this hook to initialise the Collection Editor plugin.
@@ -38,9 +47,9 @@ export interface CollectionConfigControllerProps<EC extends PersistedCollection
38
47
  * @param configPermissions
39
48
  * @param reservedGroups
40
49
  * @param extraView
41
- * @param getPathsSuggestions
50
+ * @param getData
42
51
  * @param getUser
43
52
  * @param collectionInference
44
53
  */
45
- export declare function useCollectionEditorPlugin<EC extends PersistedCollection = PersistedCollection, UserType extends User = User>({ collectionConfigController, configPermissions, reservedGroups, extraView, getPathSuggestions, getUser, collectionInference, getData, onAnalyticsEvent }: CollectionConfigControllerProps<EC, UserType>): FireCMSPlugin<any, any, PersistedCollection>;
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>;
46
55
  export declare function IntroWidget({}: {}): import("react/jsx-runtime").JSX.Element | null;
package/package.json CHANGED
@@ -1,24 +1,26 @@
1
1
  {
2
2
  "name": "@firecms/collection_editor",
3
3
  "type": "module",
4
- "version": "3.0.0-beta.7",
4
+ "version": "3.0.0-beta.9",
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-beta.7",
11
- "@firecms/formex": "^3.0.0-beta.7",
12
- "@firecms/schema_inference": "^3.0.0-beta.7",
13
- "@firecms/ui": "^3.0.0-beta.7",
10
+ "@firecms/data_export": "^3.0.0-beta.9",
11
+ "@firecms/data_import": "^3.0.0-beta.9",
12
+ "@firecms/data_import_export": "^3.0.0-beta.9",
13
+ "@firecms/formex": "^3.0.0-beta.9",
14
+ "@firecms/schema_inference": "^3.0.0-beta.9",
15
+ "@firecms/ui": "^3.0.0-beta.9",
14
16
  "json5": "^2.2.3",
15
17
  "prism-react-renderer": "^2.3.1"
16
18
  },
17
19
  "peerDependencies": {
18
20
  "react": "^18.3.1",
19
21
  "react-dom": "^18.3.1",
20
- "react-router": "^6.22.0",
21
- "react-router-dom": "^6.22.0"
22
+ "react-router": "^6.25.1",
23
+ "react-router-dom": "^6.25.1"
22
24
  },
23
25
  "exports": {
24
26
  ".": {
@@ -34,12 +36,6 @@
34
36
  "build": "vite build && tsc --emitDeclarationOnly -p tsconfig.prod.json",
35
37
  "clean": "rm -rf dist && find ./src -name '*.js' -type f | xargs rm -f"
36
38
  },
37
- "eslintConfig": {
38
- "extends": [
39
- "react-app",
40
- "react-app/jest"
41
- ]
42
- },
43
39
  "browserslist": {
44
40
  "production": [
45
41
  ">0.2%",
@@ -56,23 +52,13 @@
56
52
  "@jest/globals": "^29.7.0",
57
53
  "@types/react": "^18.3.3",
58
54
  "@types/react-dom": "^18.3.0",
59
- "@typescript-eslint/eslint-plugin": "^7.11.0",
60
- "@typescript-eslint/parser": "^7.11.0",
61
- "@vitejs/plugin-react": "^4.3.0",
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.2.0",
67
- "eslint-plugin-react": "^7.34.2",
68
- "eslint-plugin-react-hooks": "^4.6.2",
55
+ "@vitejs/plugin-react": "^4.3.1",
69
56
  "jest": "^29.7.0",
70
- "react-router": "^6.23.1",
71
- "react-router-dom": "^6.23.1",
72
- "ts-jest": "^29.1.4",
73
- "typescript": "^5.4.5",
74
- "vite": "^5.2.12",
75
- "vite-plugin-fonts": "^0.7.0"
57
+ "react-router": "^6.25.1",
58
+ "react-router-dom": "^6.25.1",
59
+ "ts-jest": "^29.2.3",
60
+ "typescript": "^5.5.4",
61
+ "vite": "^5.3.4"
76
62
  },
77
63
  "files": [
78
64
  "dist",
@@ -81,5 +67,5 @@
81
67
  "publishConfig": {
82
68
  "access": "public"
83
69
  },
84
- "gitHead": "b1f5dbd89d66bd75e8d214a4a6c40e07e371a1d1"
70
+ "gitHead": "a2fffa74049d185e674aae9f70b462f011edd1c2"
85
71
  }
@@ -3,6 +3,7 @@ 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,
@@ -56,6 +57,13 @@ export interface ConfigControllerProviderProps {
56
57
 
57
58
  onAnalyticsEvent?: (event: string, params?: object) => void;
58
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
+
59
67
  }
60
68
 
61
69
  export const ConfigControllerProvider = React.memo(
@@ -69,7 +77,8 @@ export const ConfigControllerProvider = React.memo(
69
77
  getPathSuggestions,
70
78
  getUser,
71
79
  getData,
72
- onAnalyticsEvent
80
+ onAnalyticsEvent,
81
+ components
73
82
  }: PropsWithChildren<ConfigControllerProviderProps>) {
74
83
 
75
84
  const navigation = useNavigationController();
@@ -88,7 +97,8 @@ export const ConfigControllerProvider = React.memo(
88
97
  group?: string,
89
98
  name?: string
90
99
  },
91
- redirect: boolean
100
+ redirect: boolean,
101
+ existingEntities?: Entity<any>[]
92
102
  }>();
93
103
 
94
104
  const [currentPropertyDialog, setCurrentPropertyDialog] = React.useState<{
@@ -101,6 +111,7 @@ export const ConfigControllerProvider = React.memo(
101
111
  fullPath?: string,
102
112
  parentCollectionIds: string[],
103
113
  collectionEditable: boolean;
114
+ existingEntities?: Entity<any>[]
104
115
  }>();
105
116
 
106
117
  const defaultConfigPermissions: CollectionEditorPermissionsBuilder = useCallback(() => ({
@@ -113,12 +124,14 @@ export const ConfigControllerProvider = React.memo(
113
124
  id,
114
125
  fullPath,
115
126
  parentCollectionIds,
116
- parentCollection
127
+ parentCollection,
128
+ existingEntities
117
129
  }: {
118
130
  id?: string,
119
131
  fullPath?: string,
120
132
  parentCollectionIds: string[],
121
- parentCollection?: PersistedCollection
133
+ parentCollection?: PersistedCollection,
134
+ existingEntities?: Entity<any>[]
122
135
  }) => {
123
136
  console.debug("Edit collection", id, fullPath, parentCollectionIds, parentCollection);
124
137
  onAnalyticsEvent?.("edit_collection", {
@@ -131,7 +144,8 @@ export const ConfigControllerProvider = React.memo(
131
144
  parentCollectionIds,
132
145
  isNewCollection: false,
133
146
  parentCollection,
134
- redirect: false
147
+ redirect: false,
148
+ existingEntities
135
149
  });
136
150
  };
137
151
 
@@ -141,7 +155,8 @@ export const ConfigControllerProvider = React.memo(
141
155
  editedCollectionId,
142
156
  currentPropertiesOrder,
143
157
  parentCollectionIds,
144
- collection
158
+ collection,
159
+ existingEntities
145
160
  }: {
146
161
  propertyKey?: string,
147
162
  property?: Property,
@@ -149,6 +164,7 @@ export const ConfigControllerProvider = React.memo(
149
164
  editedCollectionId: string,
150
165
  parentCollectionIds: string[],
151
166
  collection: PersistedCollection,
167
+ existingEntities?: Entity<any>[]
152
168
  }) => {
153
169
  console.debug("Edit property", propertyKey, property, editedCollectionId, currentPropertiesOrder, parentCollectionIds, collection);
154
170
  onAnalyticsEvent?.("edit_property", {
@@ -169,7 +185,8 @@ export const ConfigControllerProvider = React.memo(
169
185
  currentPropertiesOrder,
170
186
  editedCollectionId,
171
187
  parentCollectionIds,
172
- collectionEditable: collection?.editable ?? false
188
+ collectionEditable: collection?.editable ?? false,
189
+ existingEntities
173
190
  });
174
191
  };
175
192
 
@@ -221,7 +238,8 @@ export const ConfigControllerProvider = React.memo(
221
238
  createCollection,
222
239
  editProperty,
223
240
  configPermissions: configPermissions ?? defaultConfigPermissions,
224
- getPathSuggestions
241
+ getPathSuggestions,
242
+ components
225
243
  }}>
226
244
 
227
245
  {children}
@@ -1,5 +1,6 @@
1
+ import React from "react";
1
2
  import { CollectionEditorPermissionsBuilder } from "./config_permissions";
2
- import { Property } from "@firecms/core";
3
+ import { Entity, Property } from "@firecms/core";
3
4
  import { PersistedCollection } from "./persisted_collection";
4
5
 
5
6
  /**
@@ -12,7 +13,8 @@ export interface CollectionEditorController {
12
13
  id?: string,
13
14
  fullPath?: string,
14
15
  parentCollectionIds: string[],
15
- parentCollection?: PersistedCollection
16
+ parentCollection?: PersistedCollection,
17
+ existingEntities?: Entity<any>[]
16
18
  }) => void;
17
19
 
18
20
  createCollection: (props: {
@@ -33,11 +35,19 @@ export interface CollectionEditorController {
33
35
  currentPropertiesOrder?: string[],
34
36
  editedCollectionId: string,
35
37
  parentCollectionIds: string[],
36
- collection: PersistedCollection
38
+ collection: PersistedCollection,
39
+ existingEntities: Entity<any>[]
37
40
  }) => void;
38
41
 
39
42
  configPermissions: CollectionEditorPermissionsBuilder;
40
43
 
41
44
  getPathSuggestions?: (path: string) => Promise<string[]>;
42
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
+
43
53
  }
@@ -1,4 +1,4 @@
1
- import { ResolvedProperty } from "@firecms/core";
1
+ import { EntityTableController, ResolvedProperty } from "@firecms/core";
2
2
  import { IconButton, SettingsIcon, Tooltip } from "@firecms/ui";
3
3
  import React from "react";
4
4
  import { useCollectionEditorController } from "../useCollectionEditorController";
@@ -10,7 +10,8 @@ export function CollectionViewHeaderAction({
10
10
  property,
11
11
  fullPath,
12
12
  parentCollectionIds,
13
- collection
13
+ collection,
14
+ tableController
14
15
  }: {
15
16
  property: ResolvedProperty,
16
17
  propertyKey: string,
@@ -18,12 +19,15 @@ export function CollectionViewHeaderAction({
18
19
  fullPath: string,
19
20
  parentCollectionIds: string[],
20
21
  collection: PersistedCollection;
22
+ tableController: EntityTableController;
21
23
  }) {
22
24
 
23
25
  const collectionEditorController = useCollectionEditorController();
24
26
 
25
27
  return (
26
- <Tooltip title={"Edit"}>
28
+ <Tooltip
29
+ asChild={true}
30
+ title={"Edit"}>
27
31
  <IconButton
28
32
  className={onHover ? "bg-white dark:bg-gray-950" : "hidden"}
29
33
  onClick={() => {
@@ -32,7 +36,8 @@ export function CollectionViewHeaderAction({
32
36
  property,
33
37
  editedCollectionId: collection.id,
34
38
  parentCollectionIds,
35
- collection
39
+ collection,
40
+ existingEntities: tableController.data ?? []
36
41
  });
37
42
  }}
38
43
  size={"small"}>
@@ -1,16 +1,7 @@
1
- import equal from "react-fast-compare"
2
-
3
- import {
4
- CollectionActionsProps,
5
- mergeDeep,
6
- useAuthController,
7
- useNavigationController,
8
- useSnackbarController
9
- } from "@firecms/core";
10
- import { Button, IconButton, SaveIcon, SettingsIcon, Tooltip, UndoIcon, } from "@firecms/ui";
1
+ import { CollectionActionsProps, useAuthController, useNavigationController } from "@firecms/core";
2
+ import { IconButton, SettingsIcon, Tooltip, } from "@firecms/ui";
11
3
 
12
4
  import { useCollectionEditorController } from "../useCollectionEditorController";
13
- import { useCollectionsConfigController } from "../useCollectionsConfigController";
14
5
  import { PersistedCollection } from "../types/persisted_collection";
15
6
 
16
7
  export function EditorCollectionAction({
@@ -34,12 +25,19 @@ export function EditorCollectionAction({
34
25
  : true;
35
26
 
36
27
  const editorButton = <Tooltip
28
+ asChild={true}
37
29
  title={canEditCollection ? "Edit collection" : "You don't have permissions to edit this collection"}>
38
30
  <IconButton
39
31
  color={"primary"}
40
32
  disabled={!canEditCollection}
41
33
  onClick={canEditCollection
42
- ? () => collectionEditorController?.editCollection({ id: collection.id, fullPath, parentCollectionIds, parentCollection: parentCollection as PersistedCollection })
34
+ ? () => collectionEditorController?.editCollection({
35
+ id: collection.id,
36
+ fullPath,
37
+ parentCollectionIds,
38
+ parentCollection: parentCollection as PersistedCollection,
39
+ existingEntities: tableController?.data ?? []
40
+ })
43
41
  : undefined}>
44
42
  <SettingsIcon/>
45
43
  </IconButton>
@@ -31,6 +31,7 @@ export function EditorCollectionActionStart({
31
31
  !equal(getObjectOrNull(tableController.sortBy), getObjectOrNull(collection.initialSort))) {
32
32
  saveDefaultFilterButton = <>
33
33
  <Tooltip
34
+ asChild={true}
34
35
  title={tableController.sortBy || tableController.filterValues ? "Save default filter and sort" : "Clear default filter and sort"}>
35
36
  <Button
36
37
  color={"primary"}
@@ -25,7 +25,10 @@ export function HomePageEditorCollectionAction({
25
25
  });
26
26
 
27
27
  const onEditCollectionClicked = () => {
28
- collectionEditorController?.editCollection({ id: collection.id, parentCollectionIds: [] });
28
+ collectionEditorController?.editCollection({
29
+ id: collection.id,
30
+ parentCollectionIds: []
31
+ });
29
32
  };
30
33
 
31
34
  const [deleteRequested, setDeleteRequested] = useState(false);
@@ -49,11 +52,13 @@ export function HomePageEditorCollectionAction({
49
52
  <MoreVertIcon size={"small"}/>
50
53
  </IconButton>}
51
54
  >
52
- <MenuItem onClick={(event) => {
53
- event.preventDefault();
54
- event.stopPropagation();
55
- setDeleteRequested(true);
56
- }}>
55
+ <MenuItem
56
+ dense={true}
57
+ onClick={(event) => {
58
+ event.preventDefault();
59
+ event.stopPropagation();
60
+ setDeleteRequested(true);
61
+ }}>
57
62
  <DeleteIcon/>
58
63
  Delete
59
64
  </MenuItem>
@@ -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,7 +25,9 @@ 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
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"}
29
33
  // className={onHover ? "bg-white dark:bg-gray-950" : undefined}
@@ -32,7 +36,8 @@ export function PropertyAddColumnComponent({
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"}/>
@@ -22,6 +22,7 @@ import {
22
22
  } from "@firecms/ui";
23
23
 
24
24
  import { Field, getIn, useFormex } from "@firecms/formex";
25
+ import { useCollectionEditorController } from "../../useCollectionEditorController";
25
26
 
26
27
  export function CollectionDetailsForm({
27
28
  isNewCollection,
@@ -52,9 +53,15 @@ export function CollectionDetailsForm({
52
53
  submitCount
53
54
  } = useFormex<EntityCollection>();
54
55
 
56
+ const collectionEditor = useCollectionEditorController();
57
+
55
58
  const [iconDialogOpen, setIconDialogOpen] = useState(false);
56
59
  const [advancedPanelExpanded, setAdvancedPanelExpanded] = useState(false);
57
60
 
61
+ const updateDatabaseId = (databaseId: string) => {
62
+ setFieldValue("databaseId", databaseId ?? undefined);
63
+ }
64
+
58
65
  const updateName = (name: string) => {
59
66
  setFieldValue("name", name);
60
67
 
@@ -81,6 +88,8 @@ export function CollectionDetailsForm({
81
88
  }
82
89
  }, [errors.id]);
83
90
 
91
+ const DatabaseField = collectionEditor.components?.DatabaseField ?? DefaultDatabaseField;
92
+
84
93
  const collectionIcon = <IconForView collectionOrView={values}/>;
85
94
 
86
95
  const groupOptions = groups?.filter((group) => !reservedGroups?.includes(group));
@@ -113,11 +122,15 @@ export function CollectionDetailsForm({
113
122
 
114
123
  <div>
115
124
  <div
116
- className="flex flex-row py-2 pt-3 items-center">
125
+ className="flex flex-row gap-2 py-2 pt-3 items-center">
117
126
  <Typography variant={!isNewCollection ? "h5" : "h4"} className={"flex-grow"}>
118
127
  {isNewCollection ? "New collection" : `${values?.name} collection`}
119
128
  </Typography>
120
- <Tooltip title={"Change icon"}>
129
+ <DatabaseField databaseId={values.databaseId}
130
+ onDatabaseIdUpdate={updateDatabaseId}/>
131
+
132
+ <Tooltip title={"Change icon"}
133
+ asChild={true}>
121
134
  <IconButton
122
135
  shape={"square"}
123
136
  onClick={() => setIconDialogOpen(true)}>
@@ -143,7 +156,7 @@ export function CollectionDetailsForm({
143
156
  required
144
157
  error={showErrors && Boolean(errors.name)}/>
145
158
  <FieldCaption error={touched.name && Boolean(errors.name)}>
146
- {touched.name && Boolean(errors.name) ? errors.name : "Name of in this collection, usually a plural name (e.g. Products)"}
159
+ {touched.name && Boolean(errors.name) ? errors.name : "Name of this collection, usually a plural name (e.g. Products)"}
147
160
  </FieldCaption>
148
161
  </div>
149
162
 
@@ -191,7 +204,7 @@ export function CollectionDetailsForm({
191
204
  })}
192
205
  </Autocomplete>
193
206
  <FieldCaption>
194
- {showErrors && Boolean(errors.group) ? errors.group : "Group of the collection"}
207
+ {showErrors && Boolean(errors.group) ? errors.group : "Group in the home page"}
195
208
  </FieldCaption>
196
209
  </div>}
197
210
 
@@ -393,3 +406,20 @@ export function CollectionDetailsForm({
393
406
  </div>
394
407
  );
395
408
  }
409
+
410
+ function DefaultDatabaseField({
411
+ databaseId,
412
+ onDatabaseIdUpdate
413
+ }: { databaseId?: string, onDatabaseIdUpdate: (databaseId: string) => void }) {
414
+
415
+ return <Tooltip title={"Database ID"}
416
+ side={"top"}
417
+ align={"start"}>
418
+ <TextField size={"smallest"}
419
+ invisible={true}
420
+ inputClassName={"text-end"}
421
+ value={databaseId ?? ""}
422
+ onChange={(e: any) => onDatabaseIdUpdate(e.target.value)}
423
+ placeholder={"(default)"}></TextField>
424
+ </Tooltip>
425
+ }
@@ -2,6 +2,7 @@ import * as React from "react";
2
2
  import { useEffect, useRef, useState } from "react";
3
3
  import {
4
4
  CircularProgressCenter,
5
+ Entity,
5
6
  EntityCollection,
6
7
  ErrorView,
7
8
  isPropertyBuilder,
@@ -79,6 +80,7 @@ export interface CollectionEditorDialogProps {
79
80
  getUser?: (uid: string) => User | null;
80
81
  getData?: (path: string, parentPaths: string[]) => Promise<object[]>;
81
82
  parentCollection?: PersistedCollection;
83
+ existingEntities?: Entity<any>[];
82
84
  }
83
85
 
84
86
  export function CollectionEditorDialog(props: CollectionEditorDialogProps) {
@@ -244,7 +246,8 @@ function CollectionEditorInternal<M extends Record<string, any>>({
244
246
  setCollection,
245
247
  initialValues,
246
248
  propertyConfigs,
247
- groups
249
+ groups,
250
+ existingEntities
248
251
  }: CollectionEditorDialogProps & {
249
252
  handleCancel: () => void,
250
253
  setFormDirty: (dirty: boolean) => void,
@@ -481,7 +484,14 @@ function CollectionEditorInternal<M extends Record<string, any>>({
481
484
 
482
485
  const parentPaths = !pathError && parentCollectionIds ? navigation.convertIdsToPaths(parentCollectionIds) : undefined;
483
486
  const resolvedPath = !pathError ? navigation.resolveAliasesFrom(updatedFullPath) : undefined;
484
- const getDataWithPath = resolvedPath && getData ? () => getData(resolvedPath, parentPaths ?? []) : undefined;
487
+ const getDataWithPath = resolvedPath && getData ? async () => {
488
+ const data = await getData(resolvedPath, parentPaths ?? []);
489
+ if (existingEntities) {
490
+ const existingData = existingEntities.map(e => e.values);
491
+ data.push(...existingData);
492
+ }
493
+ return data;
494
+ } : undefined;
485
495
 
486
496
  useEffect(() => {
487
497
  setFormDirty(dirty);
@@ -185,7 +185,8 @@ export function TemplateButton({
185
185
  }) {
186
186
 
187
187
  return (
188
- <Tooltip title={subtitle}>
188
+ <Tooltip title={subtitle}
189
+ asChild={true}>
189
190
  <Card
190
191
  onClick={onClick}
191
192
  className={cls(