@firecms/collection_editor 3.0.0-3.0.0-beta.4.pre.1.0

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 (140) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -0
  3. package/dist/ConfigControllerProvider.d.ts +37 -0
  4. package/dist/index.d.ts +11 -0
  5. package/dist/index.es.js +5454 -0
  6. package/dist/index.es.js.map +1 -0
  7. package/dist/index.umd.js +4 -0
  8. package/dist/index.umd.js.map +1 -0
  9. package/dist/types/collection_editor_controller.d.ts +36 -0
  10. package/dist/types/collection_inference.d.ts +2 -0
  11. package/dist/types/config_controller.d.ts +51 -0
  12. package/dist/types/config_permissions.d.ts +19 -0
  13. package/dist/types/persisted_collection.d.ts +6 -0
  14. package/dist/ui/CollectionViewHeaderAction.d.ts +10 -0
  15. package/dist/ui/EditorCollectionAction.d.ts +2 -0
  16. package/dist/ui/HomePageEditorCollectionAction.d.ts +2 -0
  17. package/dist/ui/MissingReferenceWidget.d.ts +3 -0
  18. package/dist/ui/NewCollectionButton.d.ts +1 -0
  19. package/dist/ui/NewCollectionCard.d.ts +2 -0
  20. package/dist/ui/PropertyAddColumnComponent.d.ts +6 -0
  21. package/dist/ui/RootCollectionSuggestions.d.ts +3 -0
  22. package/dist/ui/collection_editor/CollectionDetailsForm.d.ts +10 -0
  23. package/dist/ui/collection_editor/CollectionEditorDialog.d.ts +36 -0
  24. package/dist/ui/collection_editor/CollectionEditorWelcomeView.d.ts +15 -0
  25. package/dist/ui/collection_editor/CollectionPropertiesEditorForm.d.ts +19 -0
  26. package/dist/ui/collection_editor/CollectionYupValidation.d.ts +14 -0
  27. package/dist/ui/collection_editor/EntityCustomViewsSelectDialog.d.ts +4 -0
  28. package/dist/ui/collection_editor/EnumForm.d.ts +12 -0
  29. package/dist/ui/collection_editor/GetCodeDialog.d.ts +5 -0
  30. package/dist/ui/collection_editor/PropertyEditView.d.ts +40 -0
  31. package/dist/ui/collection_editor/PropertyFieldPreview.d.ts +15 -0
  32. package/dist/ui/collection_editor/PropertySelectItem.d.ts +8 -0
  33. package/dist/ui/collection_editor/PropertyTree.d.ts +33 -0
  34. package/dist/ui/collection_editor/SubcollectionsEditTab.d.ts +12 -0
  35. package/dist/ui/collection_editor/SwitchControl.d.ts +8 -0
  36. package/dist/ui/collection_editor/UnsavedChangesDialog.d.ts +9 -0
  37. package/dist/ui/collection_editor/import/CollectionEditorImportDataPreview.d.ts +7 -0
  38. package/dist/ui/collection_editor/import/CollectionEditorImportMapping.d.ts +7 -0
  39. package/dist/ui/collection_editor/import/clean_import_data.d.ts +7 -0
  40. package/dist/ui/collection_editor/properties/BlockPropertyField.d.ts +8 -0
  41. package/dist/ui/collection_editor/properties/BooleanPropertyField.d.ts +3 -0
  42. package/dist/ui/collection_editor/properties/CommonPropertyFields.d.ts +10 -0
  43. package/dist/ui/collection_editor/properties/DateTimePropertyField.d.ts +3 -0
  44. package/dist/ui/collection_editor/properties/EnumPropertyField.d.ts +8 -0
  45. package/dist/ui/collection_editor/properties/KeyValuePropertyField.d.ts +3 -0
  46. package/dist/ui/collection_editor/properties/MapPropertyField.d.ts +8 -0
  47. package/dist/ui/collection_editor/properties/NumberPropertyField.d.ts +3 -0
  48. package/dist/ui/collection_editor/properties/ReferencePropertyField.d.ts +13 -0
  49. package/dist/ui/collection_editor/properties/RepeatPropertyField.d.ts +10 -0
  50. package/dist/ui/collection_editor/properties/StoragePropertyField.d.ts +5 -0
  51. package/dist/ui/collection_editor/properties/StringPropertyField.d.ts +5 -0
  52. package/dist/ui/collection_editor/properties/UrlPropertyField.d.ts +4 -0
  53. package/dist/ui/collection_editor/properties/advanced/AdvancedPropertyValidation.d.ts +3 -0
  54. package/dist/ui/collection_editor/properties/validation/ArrayPropertyValidation.d.ts +5 -0
  55. package/dist/ui/collection_editor/properties/validation/GeneralPropertyValidation.d.ts +4 -0
  56. package/dist/ui/collection_editor/properties/validation/NumberPropertyValidation.d.ts +3 -0
  57. package/dist/ui/collection_editor/properties/validation/StringPropertyValidation.d.ts +11 -0
  58. package/dist/ui/collection_editor/properties/validation/ValidationPanel.d.ts +2 -0
  59. package/dist/ui/collection_editor/templates/blog_template.d.ts +2 -0
  60. package/dist/ui/collection_editor/templates/pages_template.d.ts +2 -0
  61. package/dist/ui/collection_editor/templates/products_template.d.ts +2 -0
  62. package/dist/ui/collection_editor/templates/users_template.d.ts +2 -0
  63. package/dist/ui/collection_editor/util.d.ts +5 -0
  64. package/dist/ui/collection_editor/utils/strings.d.ts +1 -0
  65. package/dist/ui/collection_editor/utils/supported_fields.d.ts +3 -0
  66. package/dist/ui/collection_editor/utils/update_property_for_widget.d.ts +2 -0
  67. package/dist/ui/collection_editor/utils/useTraceUpdate.d.ts +1 -0
  68. package/dist/useCollectionEditorController.d.ts +6 -0
  69. package/dist/useCollectionEditorPlugin.d.ts +49 -0
  70. package/dist/useCollectionsConfigController.d.ts +6 -0
  71. package/dist/utils/arrays.d.ts +1 -0
  72. package/dist/utils/entities.d.ts +3 -0
  73. package/package.json +85 -0
  74. package/src/ConfigControllerProvider.tsx +338 -0
  75. package/src/index.ts +35 -0
  76. package/src/types/collection_editor_controller.tsx +43 -0
  77. package/src/types/collection_inference.ts +3 -0
  78. package/src/types/config_controller.tsx +60 -0
  79. package/src/types/config_permissions.ts +20 -0
  80. package/src/types/persisted_collection.ts +9 -0
  81. package/src/ui/CollectionViewHeaderAction.tsx +43 -0
  82. package/src/ui/EditorCollectionAction.tsx +109 -0
  83. package/src/ui/HomePageEditorCollectionAction.tsx +84 -0
  84. package/src/ui/MissingReferenceWidget.tsx +37 -0
  85. package/src/ui/NewCollectionButton.tsx +16 -0
  86. package/src/ui/NewCollectionCard.tsx +48 -0
  87. package/src/ui/PropertyAddColumnComponent.tsx +42 -0
  88. package/src/ui/RootCollectionSuggestions.tsx +63 -0
  89. package/src/ui/collection_editor/CollectionDetailsForm.tsx +365 -0
  90. package/src/ui/collection_editor/CollectionEditorDialog.tsx +801 -0
  91. package/src/ui/collection_editor/CollectionEditorWelcomeView.tsx +213 -0
  92. package/src/ui/collection_editor/CollectionPropertiesEditorForm.tsx +506 -0
  93. package/src/ui/collection_editor/CollectionYupValidation.tsx +7 -0
  94. package/src/ui/collection_editor/EntityCustomViewsSelectDialog.tsx +37 -0
  95. package/src/ui/collection_editor/EnumForm.tsx +357 -0
  96. package/src/ui/collection_editor/GetCodeDialog.tsx +110 -0
  97. package/src/ui/collection_editor/PropertyEditView.tsx +615 -0
  98. package/src/ui/collection_editor/PropertyFieldPreview.tsx +207 -0
  99. package/src/ui/collection_editor/PropertySelectItem.tsx +32 -0
  100. package/src/ui/collection_editor/PropertyTree.tsx +252 -0
  101. package/src/ui/collection_editor/SubcollectionsEditTab.tsx +262 -0
  102. package/src/ui/collection_editor/SwitchControl.tsx +39 -0
  103. package/src/ui/collection_editor/UnsavedChangesDialog.tsx +47 -0
  104. package/src/ui/collection_editor/import/CollectionEditorImportDataPreview.tsx +37 -0
  105. package/src/ui/collection_editor/import/CollectionEditorImportMapping.tsx +268 -0
  106. package/src/ui/collection_editor/import/clean_import_data.ts +53 -0
  107. package/src/ui/collection_editor/properties/BlockPropertyField.tsx +138 -0
  108. package/src/ui/collection_editor/properties/BooleanPropertyField.tsx +40 -0
  109. package/src/ui/collection_editor/properties/CommonPropertyFields.tsx +110 -0
  110. package/src/ui/collection_editor/properties/DateTimePropertyField.tsx +86 -0
  111. package/src/ui/collection_editor/properties/EnumPropertyField.tsx +114 -0
  112. package/src/ui/collection_editor/properties/KeyValuePropertyField.tsx +20 -0
  113. package/src/ui/collection_editor/properties/MapPropertyField.tsx +150 -0
  114. package/src/ui/collection_editor/properties/NumberPropertyField.tsx +38 -0
  115. package/src/ui/collection_editor/properties/ReferencePropertyField.tsx +160 -0
  116. package/src/ui/collection_editor/properties/RepeatPropertyField.tsx +109 -0
  117. package/src/ui/collection_editor/properties/StoragePropertyField.tsx +200 -0
  118. package/src/ui/collection_editor/properties/StringPropertyField.tsx +79 -0
  119. package/src/ui/collection_editor/properties/UrlPropertyField.tsx +89 -0
  120. package/src/ui/collection_editor/properties/advanced/AdvancedPropertyValidation.tsx +45 -0
  121. package/src/ui/collection_editor/properties/validation/ArrayPropertyValidation.tsx +50 -0
  122. package/src/ui/collection_editor/properties/validation/GeneralPropertyValidation.tsx +61 -0
  123. package/src/ui/collection_editor/properties/validation/NumberPropertyValidation.tsx +115 -0
  124. package/src/ui/collection_editor/properties/validation/StringPropertyValidation.tsx +150 -0
  125. package/src/ui/collection_editor/properties/validation/ValidationPanel.tsx +28 -0
  126. package/src/ui/collection_editor/templates/blog_template.ts +115 -0
  127. package/src/ui/collection_editor/templates/pages_template.ts +188 -0
  128. package/src/ui/collection_editor/templates/products_template.ts +88 -0
  129. package/src/ui/collection_editor/templates/users_template.ts +42 -0
  130. package/src/ui/collection_editor/util.ts +28 -0
  131. package/src/ui/collection_editor/utils/strings.ts +9 -0
  132. package/src/ui/collection_editor/utils/supported_fields.tsx +29 -0
  133. package/src/ui/collection_editor/utils/update_property_for_widget.ts +271 -0
  134. package/src/ui/collection_editor/utils/useTraceUpdate.tsx +23 -0
  135. package/src/useCollectionEditorController.tsx +9 -0
  136. package/src/useCollectionEditorPlugin.tsx +154 -0
  137. package/src/useCollectionsConfigController.tsx +9 -0
  138. package/src/utils/arrays.ts +3 -0
  139. package/src/utils/entities.ts +38 -0
  140. package/src/vite-env.d.ts +1 -0
@@ -0,0 +1,20 @@
1
+ import { EntityCollection } from "@firecms/core";
2
+
3
+ export type CollectionEditorPermissionsBuilder<UserType = any, EC extends EntityCollection = EntityCollection> = (params: { user: UserType | null, collection?: EC }) => CollectionEditorPermissions;
4
+
5
+ export type CollectionEditorPermissions = {
6
+ /**
7
+ * Is the user allowed to create new collections.
8
+ */
9
+ createCollections: boolean;
10
+
11
+ /**
12
+ * Is the user allowed to modify this collection
13
+ */
14
+ editCollections: boolean;
15
+
16
+ /**
17
+ * Is the user allowed to delete this collection
18
+ */
19
+ deleteCollections: boolean;
20
+ }
@@ -0,0 +1,9 @@
1
+ import { EntityCollection, User } from "@firecms/core";
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>;
6
+ ownerId?: string;
7
+ subcollections?: PersistedCollection<any, any>[];
8
+ editable?: boolean;
9
+ }
@@ -0,0 +1,43 @@
1
+ import { ResolvedProperty } from "@firecms/core";
2
+ import { IconButton, SettingsIcon, Tooltip } from "@firecms/ui";
3
+ import React from "react";
4
+ import { useCollectionEditorController } from "../useCollectionEditorController";
5
+ import { PersistedCollection } from "../types/persisted_collection";
6
+
7
+ export function CollectionViewHeaderAction({
8
+ propertyKey,
9
+ onHover,
10
+ property,
11
+ fullPath,
12
+ parentCollectionIds,
13
+ collection
14
+ }: {
15
+ property: ResolvedProperty,
16
+ propertyKey: string,
17
+ onHover: boolean,
18
+ fullPath: string,
19
+ parentCollectionIds: string[],
20
+ collection: PersistedCollection;
21
+ }) {
22
+
23
+ const collectionEditorController = useCollectionEditorController();
24
+
25
+ return (
26
+ <Tooltip title={"Edit"}>
27
+ <IconButton
28
+ className={onHover ? "bg-white dark:bg-gray-950" : "hidden"}
29
+ onClick={() => {
30
+ collectionEditorController.editProperty({
31
+ propertyKey,
32
+ property,
33
+ editedCollectionId: collection.id,
34
+ parentCollectionIds,
35
+ collection
36
+ });
37
+ }}
38
+ size={"small"}>
39
+ <SettingsIcon size={"small"}/>
40
+ </IconButton>
41
+ </Tooltip>
42
+ )
43
+ }
@@ -0,0 +1,109 @@
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";
11
+
12
+ import { useCollectionEditorController } from "../useCollectionEditorController";
13
+ import { useCollectionsConfigController } from "../useCollectionsConfigController";
14
+ import { PersistedCollection } from "../types/persisted_collection";
15
+
16
+ export function EditorCollectionAction({
17
+ path: fullPath,
18
+ parentCollectionIds,
19
+ collection,
20
+ tableController
21
+ }: CollectionActionsProps) {
22
+
23
+ const authController = useAuthController();
24
+ const navigationController = useNavigationController();
25
+ const collectionEditorController = useCollectionEditorController();
26
+ const configController = useCollectionsConfigController();
27
+ const snackbarController = useSnackbarController();
28
+
29
+ const parentCollection = navigationController.getCollectionFromIds(parentCollectionIds);
30
+
31
+ const canEditCollection = collectionEditorController.configPermissions
32
+ ? collectionEditorController.configPermissions({
33
+ user: authController.user,
34
+ collection
35
+ }).editCollections
36
+ : true;
37
+
38
+ let saveDefaultFilterButton = null;
39
+ if (!equal(getObjectOrNull(tableController.filterValues), getObjectOrNull(collection.initialFilter)) ||
40
+ !equal(getObjectOrNull(tableController.sortBy), getObjectOrNull(collection.initialSort))) {
41
+ saveDefaultFilterButton = <>
42
+ {(collection.initialFilter || collection.initialSort) && <Tooltip
43
+ title={"Reset to default filter and sort"}>
44
+ <Button
45
+ color={"primary"}
46
+ size={"small"}
47
+ variant={"text"}
48
+ onClick={() => {
49
+ tableController.clearFilter?.();
50
+ if (collection?.initialFilter)
51
+ tableController.setFilterValues?.(collection?.initialFilter);
52
+ if (collection?.initialSort)
53
+ tableController.setSortBy?.(collection?.initialSort);
54
+ }}>
55
+ <UndoIcon/>
56
+ </Button>
57
+ </Tooltip>}
58
+
59
+ <Tooltip
60
+ title={tableController.sortBy || tableController.filterValues ? "Save default filter and sort" : "Clear default filter and sort"}>
61
+ <Button
62
+ color={"primary"}
63
+ size={"small"}
64
+ variant={"outlined"}
65
+ onClick={() => configController
66
+ ?.saveCollection({
67
+ id: collection.id,
68
+ parentCollectionIds,
69
+ collectionData: mergeDeep(collection as PersistedCollection,
70
+ {
71
+ initialFilter: tableController.filterValues ?? null,
72
+ initialSort: tableController.sortBy ?? null
73
+ })
74
+ }).then(() => {
75
+ snackbarController.open({
76
+ type: "success",
77
+ message: "Default config saved"
78
+ });
79
+ })}>
80
+ <SaveIcon/>
81
+ </Button>
82
+ </Tooltip>
83
+ </>;
84
+ }
85
+
86
+ const editorButton = <Tooltip
87
+ title={canEditCollection ? "Edit collection" : "You don't have permissions to edit this collection"}>
88
+ <IconButton
89
+ color={"primary"}
90
+ disabled={!canEditCollection}
91
+ onClick={canEditCollection
92
+ ? () => collectionEditorController?.editCollection({ id: collection.id, fullPath, parentCollectionIds, parentCollection: parentCollection as PersistedCollection })
93
+ : undefined}>
94
+ <SettingsIcon/>
95
+ </IconButton>
96
+ </Tooltip>;
97
+
98
+ return <>
99
+ {canEditCollection && saveDefaultFilterButton}
100
+ {editorButton}
101
+ </>
102
+
103
+ }
104
+
105
+ function getObjectOrNull(o?: object): object | null {
106
+ if (o && Object.keys(o).length === 0)
107
+ return o
108
+ return o ?? null;
109
+ }
@@ -0,0 +1,84 @@
1
+ import {
2
+ DeleteConfirmationDialog,
3
+ PluginHomePageActionsProps,
4
+ useAuthController,
5
+ useSnackbarController
6
+ } from "@firecms/core";
7
+ import { DeleteIcon, IconButton, Menu, MenuItem, MoreVertIcon, SettingsIcon, } from "@firecms/ui";
8
+ import { useCollectionEditorController } from "../useCollectionEditorController";
9
+ import { useCallback, useState } from "react";
10
+ import { useCollectionsConfigController } from "../useCollectionsConfigController";
11
+
12
+ export function HomePageEditorCollectionAction({
13
+ path,
14
+ collection
15
+ }: PluginHomePageActionsProps) {
16
+
17
+ const snackbarController = useSnackbarController();
18
+ const authController = useAuthController();
19
+ const configController = useCollectionsConfigController();
20
+ const collectionEditorController = useCollectionEditorController();
21
+
22
+ const permissions = collectionEditorController.configPermissions({
23
+ user: authController.user,
24
+ collection
25
+ });
26
+
27
+ const onEditCollectionClicked = useCallback(() => {
28
+ collectionEditorController?.editCollection({ id: collection.id, parentCollectionIds: [] });
29
+ }, [collectionEditorController, path]);
30
+
31
+ const [deleteRequested, setDeleteRequested] = useState(false);
32
+
33
+ const deleteCollection = useCallback(() => {
34
+ configController?.deleteCollection({ id: collection.id }).then(() => {
35
+ setDeleteRequested(false);
36
+ snackbarController.open({
37
+ message: "Collection deleted",
38
+ type: "success"
39
+ });
40
+ });
41
+ }, [path, configController]);
42
+
43
+ return <>
44
+
45
+ <div>
46
+ {permissions.deleteCollections &&
47
+ <Menu
48
+ trigger={<IconButton>
49
+ <MoreVertIcon size={"small"}/>
50
+ </IconButton>}
51
+ >
52
+ <MenuItem onClick={(event) => {
53
+ event.preventDefault();
54
+ event.stopPropagation();
55
+ setDeleteRequested(true);
56
+ }}>
57
+ <DeleteIcon/>
58
+ Delete
59
+ </MenuItem>
60
+
61
+ </Menu>
62
+
63
+ }
64
+
65
+ {permissions.editCollections &&
66
+ <IconButton
67
+ onClick={(event) => {
68
+ onEditCollectionClicked();
69
+ }}>
70
+ <SettingsIcon size={"small"}/>
71
+ </IconButton>}
72
+ </div>
73
+
74
+ <DeleteConfirmationDialog
75
+ open={deleteRequested}
76
+ onAccept={deleteCollection}
77
+ onCancel={() => setDeleteRequested(false)}
78
+ title={<>Delete this collection?</>}
79
+ body={<> This will <b>not
80
+ delete any data</b>, only
81
+ the collection in the CMS</>}/>
82
+ </>;
83
+
84
+ }
@@ -0,0 +1,37 @@
1
+ import { ErrorView, unslugify, useNavigationController } from "@firecms/core";
2
+ import { useCollectionEditorController } from "../useCollectionEditorController";
3
+ import { Button } from "@firecms/ui";
4
+
5
+ export function MissingReferenceWidget({ path: pathProp }: {
6
+ path: string
7
+ }) {
8
+ const navigation = useNavigationController();
9
+ const path = getLastSegment(pathProp);
10
+ const parentCollectionIds = navigation.getParentCollectionIds(pathProp);
11
+ const collectionEditor = useCollectionEditorController();
12
+ return <div className={"p-1 flex flex-col items-center"}>
13
+ <ErrorView error={"No collection for path: " + path}/>
14
+ <Button className={"mx-2"} variant={"outlined"}
15
+ size={"small"}
16
+ onClick={() => {
17
+ collectionEditor.createCollection({
18
+ initialValues: { path, name: unslugify(path) },
19
+ parentCollectionIds,
20
+ redirect: false,
21
+ sourceClick: "missing_reference"
22
+ });
23
+ }}>
24
+ Create
25
+ </Button>
26
+ </div>;
27
+ }
28
+
29
+ function getParentPathSegments(path: string): string[] {
30
+ const segments = path.split("/");
31
+ return segments.filter((segment, index) => index % 2 === 0 && index !== segments.length - 1);
32
+ }
33
+
34
+ function getLastSegment(path: string): string {
35
+ const segments = path.split("/");
36
+ return segments[segments.length - 1];
37
+ }
@@ -0,0 +1,16 @@
1
+ import { AddIcon, Button } from "@firecms/ui";
2
+ import { useCollectionEditorController } from "../useCollectionEditorController";
3
+
4
+ export function NewCollectionButton() {
5
+ const collectionEditorController = useCollectionEditorController();
6
+ return <Button className={"min-w-fit"}
7
+ variant={"outlined"}
8
+ onClick={() => collectionEditorController.createCollection({
9
+ parentCollectionIds: [],
10
+ redirect: true,
11
+ sourceClick: "new_collection_button"
12
+ })}>
13
+ <AddIcon/>
14
+ New collection
15
+ </Button>
16
+ }
@@ -0,0 +1,48 @@
1
+ import { PluginHomePageAdditionalCardsProps, useAuthController } from "@firecms/core";
2
+ import { AddIcon, Card, cn, Typography } from "@firecms/ui";
3
+ import { useCollectionEditorController } from "../useCollectionEditorController";
4
+
5
+ export function NewCollectionCard({
6
+ group,
7
+ context
8
+ }: PluginHomePageAdditionalCardsProps) {
9
+
10
+ if (!context.navigation.topLevelNavigation)
11
+ throw Error("Navigation not ready in FireCMSHomePage");
12
+
13
+ const authController = useAuthController();
14
+
15
+ const collectionEditorController = useCollectionEditorController();
16
+ const canCreateCollections = collectionEditorController.configPermissions
17
+ ? collectionEditorController.configPermissions({
18
+ user: authController.user,
19
+ }).createCollections
20
+ : true;
21
+
22
+ return (
23
+ <Card className={cn("h-full p-4 min-h-[124px]")}
24
+ onClick={collectionEditorController && canCreateCollections
25
+ ? () => collectionEditorController.createCollection({
26
+ initialValues: group ? { group } : undefined,
27
+ parentCollectionIds: [],
28
+ redirect: true,
29
+ sourceClick: "new_collection_card"
30
+ })
31
+ : undefined}>
32
+
33
+ <div
34
+ className="flex flex-col items-start h-full w-full items-center justify-center h-full w-full flex-grow flex-col">
35
+ <AddIcon color="primary" size={"large"}/>
36
+ <Typography color="primary"
37
+ variant={"caption"}
38
+ className={"font-medium"}>{"Add new collection".toUpperCase()}</Typography>
39
+
40
+ {!canCreateCollections &&
41
+ <Typography variant={"caption"}>You don&apos;t have permissions to create
42
+ collections</Typography>
43
+ }
44
+ </div>
45
+
46
+ </Card>
47
+ );
48
+ }
@@ -0,0 +1,42 @@
1
+ import { getDefaultPropertiesOrder, useAuthController } from "@firecms/core";
2
+ import { AddIcon, Tooltip } from "@firecms/ui";
3
+ import { useCollectionEditorController } from "../useCollectionEditorController";
4
+ import { PersistedCollection } from "../types/persisted_collection";
5
+
6
+ export function PropertyAddColumnComponent({
7
+ fullPath,
8
+ parentCollectionIds,
9
+ collection
10
+ }: {
11
+ fullPath: string,
12
+ parentCollectionIds: string[],
13
+ collection: PersistedCollection;
14
+ }) {
15
+
16
+ const authController = useAuthController();
17
+ const collectionEditorController = useCollectionEditorController();
18
+ const canEditCollection = collectionEditorController.configPermissions
19
+ ? collectionEditorController.configPermissions({
20
+ user: authController.user,
21
+ collection
22
+ }).editCollections
23
+ : true;
24
+
25
+ return (
26
+ <Tooltip title={canEditCollection ? "Add new property" : "You don't have permission to add new properties"}>
27
+ <div
28
+ className={"p-0.5 w-20 h-full flex items-center justify-center cursor-pointer bg-gray-100 bg-opacity-40 hover:bg-gray-100 dark:bg-gray-950 dark:bg-opacity-40 dark:hover:bg-gray-950"}
29
+ // className={onHover ? "bg-white dark:bg-gray-950" : undefined}
30
+ onClick={() => {
31
+ collectionEditorController.editProperty({
32
+ editedCollectionId: collection.id,
33
+ parentCollectionIds,
34
+ currentPropertiesOrder: getDefaultPropertiesOrder(collection),
35
+ collection
36
+ });
37
+ }}>
38
+ <AddIcon color={"inherit"}/>
39
+ </div>
40
+ </Tooltip>
41
+ )
42
+ }
@@ -0,0 +1,63 @@
1
+ import { unslugify, useAuthController, useNavigationController } from "@firecms/core";
2
+ import { AddIcon, Chip, CircularProgress, Collapse, Typography, } from "@firecms/ui";
3
+ import { useCollectionEditorController } from "../useCollectionEditorController";
4
+ import React from "react";
5
+
6
+ export function RootCollectionSuggestions({ introMode }: { introMode?: "new_project" | "existing_project" }) {
7
+
8
+ const authController = useAuthController();
9
+ const navigationController = useNavigationController();
10
+
11
+ const collectionEditorController = useCollectionEditorController();
12
+ const canCreateCollections = collectionEditorController.configPermissions
13
+ ? collectionEditorController.configPermissions({
14
+ user: authController.user
15
+ }).createCollections
16
+ : true;
17
+
18
+ const rootPathSuggestions = collectionEditorController.rootPathSuggestions;
19
+
20
+ const showSuggestions = (rootPathSuggestions ?? []).length > 3 || ((navigationController.collections ?? []).length === 0 && (rootPathSuggestions ?? []).length > 0);
21
+ const forceShowSuggestions = introMode === "existing_project";
22
+ return <Collapse
23
+ in={forceShowSuggestions || showSuggestions}>
24
+
25
+ <div
26
+ className={"flex flex-col gap-1 p-2 my-4"}>
27
+
28
+ {!introMode && <Typography variant={"body2"} color={"secondary"}>
29
+ Create a collection <b>automatically</b> from your data:
30
+ </Typography>}
31
+
32
+ {introMode === "existing_project" && <Typography>
33
+ You will see your <b>database collections</b> here, a few seconds after project creation
34
+ </Typography>}
35
+
36
+ <div
37
+ className={"flex flex-row gap-1 overflow-scroll no-scrollbar "}>
38
+ {(rootPathSuggestions ?? []).map((path) => {
39
+ return (
40
+ <div key={path}>
41
+ <Chip
42
+ icon={<AddIcon size={"small"}/>}
43
+ colorScheme={"cyanLighter"}
44
+ onClick={collectionEditorController && canCreateCollections
45
+ ? () => collectionEditorController.createCollection({
46
+ initialValues: { path, name: unslugify(path) },
47
+ parentCollectionIds: [],
48
+ redirect: true,
49
+ sourceClick: "root_collection_suggestion"
50
+ })
51
+ : undefined}
52
+ size="small">
53
+ {path}
54
+ </Chip>
55
+ </div>
56
+ );
57
+ })}
58
+ {rootPathSuggestions === undefined && <CircularProgress size={"small"}/>}
59
+ {rootPathSuggestions?.length === 0 && <Typography variant={"caption"}>No suggestions</Typography>}
60
+ </div>
61
+ </div>
62
+ </Collapse>
63
+ }