@firecms/collection_editor 3.0.0-canary.41 → 3.0.0-canary.43

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.
@@ -32,5 +32,5 @@ export interface CollectionEditorController {
32
32
  collection: PersistedCollection;
33
33
  }) => void;
34
34
  configPermissions: CollectionEditorPermissionsBuilder;
35
- rootPathSuggestions?: string[];
35
+ getPathSuggestions?: (path: string) => Promise<string[]>;
36
36
  }
@@ -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 }: {
@@ -25,12 +25,11 @@ export interface CollectionConfigControllerProps<EC extends PersistedCollection
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
31
  getUser?: (uid: string) => UserType | 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 getPathsSuggestions
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, UserType extends User = User>({ collectionConfigController, configPermissions, reservedGroups, extraView, getPathSuggestions, getUser, collectionInference, getData, onAnalyticsEvent }: CollectionConfigControllerProps<EC, UserType>): FireCMSPlugin<any, any, PersistedCollection>;
46
+ export declare function IntroWidget({}: {}): import("react/jsx-runtime").JSX.Element | null;
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "@firecms/collection_editor",
3
3
  "type": "module",
4
- "version": "3.0.0-canary.41",
4
+ "version": "3.0.0-canary.43",
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.41",
11
- "@firecms/formex": "^3.0.0-canary.41",
12
- "@firecms/schema_inference": "^3.0.0-canary.41",
13
- "@firecms/ui": "^3.0.0-canary.41",
10
+ "@firecms/data_import_export": "^3.0.0-canary.43",
11
+ "@firecms/formex": "^3.0.0-canary.43",
12
+ "@firecms/schema_inference": "^3.0.0-canary.43",
13
+ "@firecms/ui": "^3.0.0-canary.43",
14
14
  "json5": "^2.2.3",
15
15
  "prism-react-renderer": "^2.3.1"
16
16
  },
@@ -54,10 +54,10 @@
54
54
  },
55
55
  "devDependencies": {
56
56
  "@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",
57
+ "@types/react": "^18.2.79",
58
+ "@types/react-dom": "^18.2.25",
59
+ "@typescript-eslint/eslint-plugin": "^7.7.0",
60
+ "@typescript-eslint/parser": "^7.7.0",
61
61
  "@vitejs/plugin-react": "^4.2.1",
62
62
  "eslint": "^8.57.0",
63
63
  "eslint-config-standard": "^17.1.0",
@@ -67,11 +67,11 @@
67
67
  "eslint-plugin-react": "^7.34.1",
68
68
  "eslint-plugin-react-hooks": "^4.6.0",
69
69
  "jest": "^29.7.0",
70
- "react-router": "^6.22.0",
71
- "react-router-dom": "^6.22.0",
70
+ "react-router": "^6.22.3",
71
+ "react-router-dom": "^6.22.3",
72
72
  "ts-jest": "^29.1.2",
73
- "typescript": "^5.4.2",
74
- "vite": "^5.2.3",
73
+ "typescript": "^5.4.5",
74
+ "vite": "^5.2.9",
75
75
  "vite-plugin-fonts": "^0.7.0"
76
76
  },
77
77
  "files": [
@@ -81,5 +81,5 @@
81
81
  "publishConfig": {
82
82
  "access": "public"
83
83
  },
84
- "gitHead": "d1ffa185f8930bab4e7b9941ba551c53f947aa1f"
84
+ "gitHead": "fedcb0d43c504245dd76b702e4ab4479fa8592df"
85
85
  }
@@ -1,4 +1,4 @@
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";
@@ -48,7 +48,7 @@ export interface ConfigControllerProviderProps {
48
48
  icon: React.ReactNode
49
49
  };
50
50
 
51
- pathSuggestions?: (path?: string) => Promise<string[]>;
51
+ getPathSuggestions?: (path?: string) => Promise<string[]>;
52
52
 
53
53
  getUser?: (uid: string) => User | null
54
54
 
@@ -66,7 +66,7 @@ export const ConfigControllerProvider = React.memo(
66
66
  reservedGroups,
67
67
  collectionInference,
68
68
  extraView,
69
- pathSuggestions,
69
+ getPathSuggestions,
70
70
  getUser,
71
71
  getData,
72
72
  onAnalyticsEvent
@@ -77,20 +77,6 @@ export const ConfigControllerProvider = React.memo(
77
77
  const snackbarController = useSnackbarController();
78
78
  const { propertyConfigs } = useCustomizationController();
79
79
 
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
80
  const [currentDialog, setCurrentDialog] = React.useState<{
95
81
  isNewCollection: boolean,
96
82
  parentCollection?: PersistedCollection,
@@ -135,7 +121,10 @@ export const ConfigControllerProvider = React.memo(
135
121
  parentCollection?: PersistedCollection
136
122
  }) => {
137
123
  console.debug("Edit collection", id, fullPath, parentCollectionIds, parentCollection);
138
- onAnalyticsEvent?.("edit_collection", { id, fullPath });
124
+ onAnalyticsEvent?.("edit_collection", {
125
+ id,
126
+ fullPath
127
+ });
139
128
  setCurrentDialog({
140
129
  editedCollectionId: id,
141
130
  fullPath,
@@ -162,7 +151,10 @@ export const ConfigControllerProvider = React.memo(
162
151
  collection: PersistedCollection,
163
152
  }) => {
164
153
  console.debug("Edit property", propertyKey, property, editedCollectionId, currentPropertiesOrder, parentCollectionIds, collection);
165
- onAnalyticsEvent?.("edit_property", { propertyKey, editedCollectionId });
154
+ onAnalyticsEvent?.("edit_property", {
155
+ propertyKey,
156
+ editedCollectionId
157
+ });
166
158
  // namespace is all the path until the last dot
167
159
  const namespace = propertyKey && propertyKey.includes(".")
168
160
  ? propertyKey.substring(0, propertyKey.lastIndexOf("."))
@@ -175,7 +167,7 @@ export const ConfigControllerProvider = React.memo(
175
167
  property,
176
168
  namespace,
177
169
  currentPropertiesOrder,
178
- editedCollectionId: editedCollectionId,
170
+ editedCollectionId,
179
171
  parentCollectionIds,
180
172
  collectionEditable: collection?.editable ?? false
181
173
  });
@@ -198,8 +190,20 @@ export const ConfigControllerProvider = React.memo(
198
190
  redirect: boolean,
199
191
  sourceClick?: string
200
192
  }) => {
201
- console.debug("Create collection", { parentCollectionIds, parentCollection, initialValues, redirect, sourceClick });
202
- onAnalyticsEvent?.("create_collection", { parentCollectionIds, parentCollection, initialValues, redirect, sourceClick });
193
+ console.debug("Create collection", {
194
+ parentCollectionIds,
195
+ parentCollection,
196
+ initialValues,
197
+ redirect,
198
+ sourceClick
199
+ });
200
+ onAnalyticsEvent?.("create_collection", {
201
+ parentCollectionIds,
202
+ parentCollection,
203
+ initialValues,
204
+ redirect,
205
+ sourceClick
206
+ });
203
207
  setCurrentDialog({
204
208
  isNewCollection: true,
205
209
  parentCollectionIds,
@@ -209,16 +213,6 @@ export const ConfigControllerProvider = React.memo(
209
213
  });
210
214
  }, []);
211
215
 
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
- }
221
-
222
216
  return (
223
217
  <ConfigControllerContext.Provider value={collectionConfigController}>
224
218
  <CollectionEditorContext.Provider
@@ -227,7 +221,7 @@ export const ConfigControllerProvider = React.memo(
227
221
  createCollection,
228
222
  editProperty,
229
223
  configPermissions: configPermissions ?? defaultConfigPermissions,
230
- rootPathSuggestions
224
+ getPathSuggestions
231
225
  }}>
232
226
 
233
227
  {children}
@@ -38,6 +38,6 @@ export interface CollectionEditorController {
38
38
 
39
39
  configPermissions: CollectionEditorPermissionsBuilder;
40
40
 
41
- rootPathSuggestions?: string[];
41
+ getPathSuggestions?: (path: string) => Promise<string[]>;
42
42
 
43
43
  }
@@ -216,7 +216,7 @@ export function CollectionDetailsForm({
216
216
  label={"Collection id"}
217
217
  error={showErrors && Boolean(errors.id)}/>
218
218
  <FieldCaption error={touched.id && Boolean(errors.id)}>
219
- {touched.id && Boolean(errors.id) ? errors.id : "This id identifies this collection"}
219
+ {touched.id && Boolean(errors.id) ? errors.id : "This id identifies this collection. Typically the same as the path."}
220
220
  </FieldCaption>
221
221
  </div>
222
222
 
@@ -487,19 +487,23 @@ function CollectionEditorInternal<M extends Record<string, any>>({
487
487
  setFormDirty(dirty);
488
488
  }, [dirty]);
489
489
 
490
- function onImportDataSet(data: object[]) {
490
+ function onImportDataSet(data: object[], propertiesOrder?: string[]) {
491
491
  importConfig.setInUse(true);
492
492
  buildEntityPropertiesFromData(data, getInferenceType)
493
493
  .then((properties) => {
494
494
  const res = cleanPropertiesFromImport(properties);
495
495
 
496
- setFieldValue("properties", res.properties);
497
- setFieldValue("propertiesOrder", Object.keys(res.properties));
498
-
499
496
  importConfig.setIdColumn(res.idColumn);
500
497
  importConfig.setImportData(data);
501
498
  importConfig.setHeadersMapping(res.headersMapping);
499
+ const filteredHeadingsOrder = ((propertiesOrder ?? [])
500
+ .filter((key) => res.headersMapping[key]) as string[]) ?? Object.keys(res.properties);
501
+ importConfig.setHeadingsOrder(filteredHeadingsOrder);
502
502
  importConfig.setOriginProperties(res.properties);
503
+
504
+ const mappedHeadings = (propertiesOrder ?? []).map((key) => res.headersMapping[key]).filter(Boolean) as string[] ?? Object.keys(res.properties);
505
+ setFieldValue("properties", res.properties);
506
+ setFieldValue("propertiesOrder", mappedHeadings);
503
507
  });
504
508
  }
505
509
 
@@ -552,9 +556,10 @@ function CollectionEditorInternal<M extends Record<string, any>>({
552
556
  {currentView === "welcome" &&
553
557
  <CollectionEditorWelcomeView
554
558
  path={path}
555
- onContinue={(importData) => {
559
+ onContinue={(importData, propertiesOrder) => {
560
+ // console.log("Import data", importData, propertiesOrder)
556
561
  if (importData) {
557
- onImportDataSet(importData);
562
+ onImportDataSet(importData, propertiesOrder);
558
563
  setCurrentView("import_data_mapping");
559
564
  } else {
560
565
  setCurrentView("details");
@@ -19,7 +19,7 @@ export function CollectionEditorWelcomeView({
19
19
  path: string;
20
20
  pathSuggestions?: (path: string) => Promise<string[]>;
21
21
  parentCollection?: EntityCollection;
22
- onContinue: (importData?: object[]) => void;
22
+ onContinue: (importData?: object[], propertiesOrder?: string[]) => void;
23
23
  existingCollectionPaths?: string[];
24
24
  }) {
25
25
 
@@ -154,7 +154,7 @@ export function CollectionEditorWelcomeView({
154
154
  ● Create a collection from a file (csv, json, xls, xslx...)
155
155
  </Typography>
156
156
 
157
- <ImportFileUpload onDataAdded={(data) => onContinue(data)}/>
157
+ <ImportFileUpload onDataAdded={(data, propertiesOrder) => onContinue(data, propertiesOrder)}/>
158
158
 
159
159
  </div>}
160
160
 
@@ -1,21 +1,33 @@
1
- import { convertDataToEntity, getPropertiesMapping, ImportConfig } from "@firecms/data_import_export";
2
- import { EntityCollectionTable, Properties, useSelectionController } from "@firecms/core";
3
- import { useEffect } from "react";
1
+ import { convertDataToEntity, ImportConfig } from "@firecms/data_import_export";
2
+ import { CircularProgressCenter, EntityCollectionTable, Properties, useSelectionController } from "@firecms/core";
3
+ import { useEffect, useState } from "react";
4
4
  import { Typography } from "@firecms/ui";
5
5
 
6
- export function CollectionEditorImportDataPreview({ importConfig, properties, propertiesOrder }: {
6
+ export function CollectionEditorImportDataPreview({
7
+ importConfig,
8
+ properties,
9
+ propertiesOrder
10
+ }: {
7
11
  importConfig: ImportConfig,
8
12
  properties: Properties,
9
13
  propertiesOrder: string[]
10
14
  }) {
11
15
 
12
- useEffect(() => {
13
- const propertiesMapping = getPropertiesMapping(importConfig.originProperties, properties);
14
- const mappedData = importConfig.importData.map(d => convertDataToEntity(d, importConfig.idColumn, importConfig.headersMapping, properties, propertiesMapping, "TEMP_PATH"));
16
+ const [loading, setLoading] = useState<boolean>(false);
17
+
18
+ async function loadEntities() {
19
+ // const propertiesMapping = getPropertiesMapping(importConfig.originProperties, properties, importConfig.headersMapping);
20
+ const mappedData = importConfig.importData.map(d => convertDataToEntity(d, importConfig.idColumn, importConfig.headersMapping, properties, "TEMP_PATH", importConfig.defaultValues));
15
21
  importConfig.setEntities(mappedData);
22
+ }
23
+
24
+ useEffect(() => {
25
+ loadEntities().finally(() => setLoading(false));
16
26
  }, []);
17
27
 
18
28
  const selectionController = useSelectionController();
29
+ if (loading)
30
+ return <CircularProgressCenter/>
19
31
 
20
32
  return <EntityCollectionTable
21
33
  title={<div>
@@ -31,7 +43,10 @@ export function CollectionEditorImportDataPreview({ importConfig, properties, pr
31
43
  filterable={false}
32
44
  sortable={false}
33
45
  selectionController={selectionController}
34
- displayedColumnIds={propertiesOrder.map(p => ({ key: p, disabled: false }))}
46
+ displayedColumnIds={propertiesOrder.map(p => ({
47
+ key: p,
48
+ disabled: false
49
+ }))}
35
50
  properties={properties}/>
36
51
 
37
52
  }
@@ -6,7 +6,7 @@ import {
6
6
  } from "@firecms/data_import_export";
7
7
  import { getIn, useFormex } from "@firecms/formex";
8
8
 
9
- import { PropertyConfigBadge, getFieldConfig, getFieldId, Properties, Property, PropertyConfig, } from "@firecms/core";
9
+ import { getFieldConfig, getFieldId, Properties, Property, PropertyConfig, PropertyConfigBadge, } from "@firecms/core";
10
10
  import { Container, Select, Tooltip, Typography } from "@firecms/ui";
11
11
  import React, { useState } from "react";
12
12
  import { OnPropertyChangedParams, PropertyFormDialog, PropertyWithId } from "../PropertyEditView";
@@ -143,18 +143,20 @@ export function CollectionEditorImportMapping({
143
143
  <div className={"overflow-auto my-auto"}>
144
144
  <Container maxWidth={"6xl"} className={"flex flex-col gap-4 p-8 m-auto"}>
145
145
 
146
- <Typography variant="h6" className={"mt-4"}>Data property mapping</Typography>
146
+ <Typography variant="h6" className={"my-4 ml-3.5"}>Data property mapping</Typography>
147
147
 
148
- <DataNewPropertiesMapping headersMapping={importConfig.headersMapping}
149
- idColumn={importConfig.idColumn}
150
- originProperties={importConfig.originProperties}
148
+ <DataNewPropertiesMapping importConfig={importConfig}
151
149
  destinationProperties={values.properties as Properties}
152
- onIdPropertyChanged={(value) => importConfig.setIdColumn(value ?? undefined)}
153
150
  buildPropertyView={({
154
151
  property,
155
152
  propertyKey,
156
- importKey
153
+ importKey,
154
+ isIdColumn
157
155
  }) => {
156
+ if (isIdColumn) {
157
+ return <Typography> This column will be used as ID</Typography>
158
+ }
159
+
158
160
  return <ImportNewPropertyFieldPreview
159
161
  property={property}
160
162
  propertyKey={propertyKey}
@@ -4,17 +4,16 @@ import { ConfigControllerProvider } from "./ConfigControllerProvider";
4
4
  import { CollectionEditorPermissionsBuilder } from "./types/config_permissions";
5
5
  import { EditorCollectionAction } from "./ui/EditorCollectionAction";
6
6
  import { HomePageEditorCollectionAction } from "./ui/HomePageEditorCollectionAction";
7
- import { NewCollectionCard } from "./ui/NewCollectionCard";
8
7
  import { PersistedCollection } from "./types/persisted_collection";
9
8
  import { CollectionInference } from "./types/collection_inference";
10
9
  import { CollectionsConfigController } from "./types/config_controller";
11
- import { RootCollectionSuggestions } from "./ui/RootCollectionSuggestions";
12
10
  import { CollectionViewHeaderAction } from "./ui/CollectionViewHeaderAction";
13
11
  import { PropertyAddColumnComponent } from "./ui/PropertyAddColumnComponent";
14
12
  import { NewCollectionButton } from "./ui/NewCollectionButton";
15
- import { AddIcon, Button, Typography } from "@firecms/ui";
13
+ import { AddIcon, Button, Paper, Typography } from "@firecms/ui";
16
14
  import { useCollectionEditorController } from "./useCollectionEditorController";
17
15
  import { EditorCollectionActionStart } from "./ui/EditorCollectionActionStart";
16
+ import { NewCollectionCard } from "./ui/NewCollectionCard";
18
17
 
19
18
  export interface CollectionConfigControllerProps<EC extends PersistedCollection = PersistedCollection, UserType extends User = User> {
20
19
 
@@ -42,7 +41,7 @@ export interface CollectionConfigControllerProps<EC extends PersistedCollection
42
41
  icon: React.ReactNode
43
42
  };
44
43
 
45
- pathSuggestions?: (path: string) => Promise<string[]>;
44
+ getPathSuggestions?: (path?: string) => Promise<string[]>;
46
45
 
47
46
  collectionInference?: CollectionInference;
48
47
 
@@ -52,8 +51,6 @@ export interface CollectionConfigControllerProps<EC extends PersistedCollection
52
51
 
53
52
  onAnalyticsEvent?: (event: string, params?: object) => void;
54
53
 
55
- introMode?: "new_project" | "existing_project";
56
-
57
54
  }
58
55
 
59
56
  /**
@@ -63,18 +60,17 @@ export interface CollectionConfigControllerProps<EC extends PersistedCollection
63
60
  * @param configPermissions
64
61
  * @param reservedGroups
65
62
  * @param extraView
66
- * @param pathSuggestions
63
+ * @param getPathsSuggestions
67
64
  * @param getUser
68
65
  * @param collectionInference
69
66
  */
70
67
  export function useCollectionEditorPlugin<EC extends PersistedCollection = PersistedCollection, UserType extends User = User>
71
68
  ({
72
69
  collectionConfigController,
73
- introMode,
74
70
  configPermissions,
75
71
  reservedGroups,
76
72
  extraView,
77
- pathSuggestions,
73
+ getPathSuggestions,
78
74
  getUser,
79
75
  collectionInference,
80
76
  getData,
@@ -92,7 +88,7 @@ export function useCollectionEditorPlugin<EC extends PersistedCollection = Persi
92
88
  collectionInference,
93
89
  reservedGroups,
94
90
  extraView,
95
- pathSuggestions,
91
+ getPathSuggestions,
96
92
  getUser,
97
93
  getData,
98
94
  onAnalyticsEvent
@@ -100,10 +96,10 @@ export function useCollectionEditorPlugin<EC extends PersistedCollection = Persi
100
96
  },
101
97
  homePage: {
102
98
  additionalActions: <NewCollectionButton/>,
103
- additionalChildrenStart: introMode ? <IntroWidget introMode={introMode}/> : undefined,
104
- additionalChildrenEnd: <RootCollectionSuggestions introMode={introMode}/>,
99
+ additionalChildrenStart: <IntroWidget/>,
100
+ // additionalChildrenEnd: <RootCollectionSuggestions introMode={introMode}/>,
105
101
  CollectionActions: HomePageEditorCollectionAction,
106
- AdditionalCards: introMode ? undefined : NewCollectionCard,
102
+ AdditionalCards: NewCollectionCard,
107
103
  },
108
104
  collectionView: {
109
105
  CollectionActionsStart: EditorCollectionActionStart,
@@ -114,9 +110,7 @@ export function useCollectionEditorPlugin<EC extends PersistedCollection = Persi
114
110
  };
115
111
  }
116
112
 
117
- export function IntroWidget({ introMode }: {
118
- introMode?: "new_project" | "existing_project";
119
- }) {
113
+ export function IntroWidget({}: {}) {
120
114
 
121
115
  const navigation = useNavigationController();
122
116
  if (!navigation.topLevelNavigation)
@@ -131,17 +125,19 @@ export function IntroWidget({ introMode }: {
131
125
  }).createCollections
132
126
  : true;
133
127
 
128
+ if (!navigation.initialised || navigation.collections === undefined || (navigation.collections ?? []).length > 0) {
129
+ return null;
130
+ }
131
+
134
132
  return (
135
- <div className={"mt-8 flex flex-col mt-8 p-2"}>
136
- <Typography variant={"h4"} className="mb-4">Welcome</Typography>
137
- <Typography paragraph={true}>Your admin panel is ready ✌️</Typography>
138
- <Typography paragraph={true}>
133
+ <Paper
134
+ className={"my-4 px-4 py-6 flex flex-col bg-white dark:bg-slate-800 gap-2"}>
135
+ <Typography variant={"subtitle2"} className={"uppercase"}>No collections found</Typography>
136
+ <Typography>
139
137
  Start building collections in FireCMS easily. Map them to your existing
140
- database data, import from files, or use our templates. Simplify your data management process
141
- now.
138
+ database data, import from files, or use our templates.
142
139
  </Typography>
143
140
  {canCreateCollections && <Button
144
- className={"mt-4"}
145
141
  onClick={collectionEditorController && canCreateCollections
146
142
  ? () => collectionEditorController.createCollection({
147
143
  parentCollectionIds: [],
@@ -151,6 +147,9 @@ export function IntroWidget({ introMode }: {
151
147
  : undefined}>
152
148
  <AddIcon/>Create your first collection
153
149
  </Button>}
154
- </div>
150
+ <Typography variant={"caption"} color={"secondary"}>
151
+ You can also define collections programmatically.
152
+ </Typography>
153
+ </Paper>
155
154
  );
156
155
  }
@@ -1,3 +0,0 @@
1
- export declare function RootCollectionSuggestions({ introMode }: {
2
- introMode?: "new_project" | "existing_project";
3
- }): import("react/jsx-runtime").JSX.Element;
@@ -1,63 +0,0 @@
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
- }