@firecms/core 3.0.0-beta.4.pre.2 → 3.0.0-beta.6
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.
- package/README.md +1 -1
- package/dist/components/ClearFilterSortButton.d.ts +5 -0
- package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +11 -11
- package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +1 -1
- package/dist/components/EntityCollectionTable/internal/CollectionTableToolbar.d.ts +1 -4
- package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +11 -1
- package/dist/components/EntityCollectionView/EntityCollectionViewStartActions.d.ts +11 -0
- package/dist/components/EntityPreview.d.ts +2 -2
- package/dist/components/SelectableTable/SelectableTable.d.ts +1 -1
- package/dist/components/common/types.d.ts +1 -1
- package/dist/contexts/AuthControllerContext.d.ts +1 -1
- package/dist/form/components/ErrorFocus.d.ts +1 -1
- package/dist/hooks/data/delete.d.ts +2 -2
- package/dist/hooks/data/save.d.ts +1 -1
- package/dist/hooks/data/useDataSource.d.ts +1 -1
- package/dist/hooks/data/useEntityFetch.d.ts +3 -3
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/useBuildNavigationController.d.ts +1 -2
- package/dist/hooks/useProjectLog.d.ts +2 -2
- package/dist/hooks/useValidateAuthenticator.d.ts +21 -0
- package/dist/index.es.js +3948 -3737
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +5 -5
- package/dist/index.umd.js.map +1 -1
- package/dist/internal/useBuildDataSource.d.ts +1 -16
- package/dist/internal/useRestoreScroll.d.ts +1 -1
- package/dist/preview/PropertyPreviewProps.d.ts +1 -4
- package/dist/types/auth.d.ts +30 -1
- package/dist/types/collections.d.ts +8 -4
- package/dist/types/datasource.d.ts +3 -6
- package/dist/types/entities.d.ts +5 -1
- package/dist/types/entity_callbacks.d.ts +2 -2
- package/dist/types/index.d.ts +1 -1
- package/dist/types/navigation.d.ts +4 -4
- package/dist/types/plugins.d.ts +5 -3
- package/dist/types/properties.d.ts +2 -2
- package/dist/types/roles.d.ts +31 -0
- package/dist/types/storage.d.ts +11 -3
- package/dist/types/user.d.ts +5 -0
- package/dist/util/collections.d.ts +1 -1
- package/dist/util/entities.d.ts +1 -1
- package/dist/util/navigation_utils.d.ts +2 -2
- package/dist/util/resolutions.d.ts +5 -5
- package/dist/util/useTraceUpdate.d.ts +1 -0
- package/package.json +23 -20
- package/src/components/ClearFilterSortButton.tsx +41 -0
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +10 -11
- package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +1 -1
- package/src/components/EntityCollectionTable/PropertyTableCell.tsx +16 -19
- package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +1 -1
- package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +27 -32
- package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +11 -6
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +28 -5
- package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +68 -0
- package/src/components/EntityPreview.tsx +5 -2
- package/src/components/EntityView.tsx +1 -1
- package/src/components/HomePage/DefaultHomePage.tsx +2 -2
- package/src/components/HomePage/NavigationCard.tsx +1 -1
- package/src/components/ReferenceWidget.tsx +1 -1
- package/src/components/SelectableTable/SelectableTable.tsx +1 -1
- package/src/components/SelectableTable/filters/BooleanFilterField.tsx +2 -3
- package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +23 -8
- package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +24 -5
- package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +35 -15
- package/src/components/VirtualTable/VirtualTable.tsx +28 -20
- package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +1 -1
- package/src/components/common/types.tsx +1 -1
- package/src/contexts/AuthControllerContext.tsx +1 -1
- package/src/core/FireCMS.tsx +2 -3
- package/src/core/field_configs.tsx +1 -2
- package/src/form/EntityForm.tsx +1 -1
- package/src/form/field_bindings/DateTimeFieldBinding.tsx +1 -1
- package/src/hooks/data/delete.ts +3 -3
- package/src/hooks/data/save.ts +2 -1
- package/src/hooks/data/useDataSource.tsx +1 -1
- package/src/hooks/data/useEntityFetch.tsx +3 -3
- package/src/hooks/index.tsx +2 -0
- package/src/hooks/useBuildLocalConfigurationPersistence.tsx +9 -10
- package/src/hooks/useBuildModeController.tsx +11 -5
- package/src/hooks/useBuildNavigationController.tsx +136 -59
- package/src/hooks/useProjectLog.tsx +8 -6
- package/src/hooks/useValidateAuthenticator.tsx +115 -0
- package/src/internal/useBuildDataSource.ts +42 -47
- package/src/internal/useBuildSideEntityController.tsx +18 -12
- package/src/preview/PropertyPreview.tsx +2 -12
- package/src/preview/PropertyPreviewProps.tsx +1 -11
- package/src/preview/components/BooleanPreview.tsx +4 -2
- package/src/preview/components/ReferencePreview.tsx +1 -1
- package/src/types/auth.tsx +40 -1
- package/src/types/collections.ts +8 -4
- package/src/types/datasource.ts +8 -5
- package/src/types/entities.ts +9 -1
- package/src/types/entity_callbacks.ts +2 -2
- package/src/types/index.ts +1 -1
- package/src/types/navigation.ts +6 -6
- package/src/types/plugins.tsx +6 -5
- package/src/types/properties.ts +5 -4
- package/src/types/roles.ts +41 -0
- package/src/types/storage.ts +12 -3
- package/src/types/user.ts +7 -0
- package/src/util/collections.ts +1 -1
- package/src/util/entities.ts +1 -1
- package/src/util/navigation_utils.ts +6 -6
- package/src/util/strings.ts +2 -2
- package/src/util/useTraceUpdate.tsx +2 -1
- package/dist/internal/useLocaleConfig.d.ts +0 -1
- package/dist/types/appcheck.d.ts +0 -26
- package/src/internal/useLocaleConfig.tsx +0 -18
- package/src/types/appcheck.ts +0 -29
|
@@ -34,6 +34,7 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
34
34
|
// only on initialisation, create panels from URL
|
|
35
35
|
useEffect(() => {
|
|
36
36
|
if (!navigation.loading && !initialised.current) {
|
|
37
|
+
console.debug("Initialising side entity controller");
|
|
37
38
|
if (navigation.isUrlCollectionPath(location.pathname)) {
|
|
38
39
|
const newFlag = location.hash === `#${NEW_URL_HASH}`;
|
|
39
40
|
const entityOrCollectionPath = navigation.urlPathToDataPath(location.pathname);
|
|
@@ -42,15 +43,17 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
42
43
|
const panel = panelsFromUrl[i];
|
|
43
44
|
setTimeout(() => {
|
|
44
45
|
if (i === 0)
|
|
45
|
-
sideDialogsController.replace(propsToSidePanel(panel, navigation, smallLayout));
|
|
46
|
+
sideDialogsController.replace(propsToSidePanel(panel, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, smallLayout));
|
|
46
47
|
else
|
|
47
|
-
sideDialogsController.open(propsToSidePanel(panel, navigation, smallLayout))
|
|
48
|
+
sideDialogsController.open(propsToSidePanel(panel, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, smallLayout))
|
|
48
49
|
}, 1);
|
|
49
50
|
}
|
|
51
|
+
} else {
|
|
52
|
+
// console.warn("Location path is not a collection path");
|
|
50
53
|
}
|
|
51
54
|
initialised.current = true;
|
|
52
55
|
}
|
|
53
|
-
}, [location, navigation, sideDialogsController, smallLayout]);
|
|
56
|
+
}, [location, navigation.loading, navigation.isUrlCollectionPath, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, sideDialogsController, smallLayout, navigation]);
|
|
54
57
|
|
|
55
58
|
const close = useCallback(() => {
|
|
56
59
|
sideDialogsController.close();
|
|
@@ -73,9 +76,9 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
73
76
|
sideDialogsController.open(propsToSidePanel({
|
|
74
77
|
selectedSubPath: defaultSelectedView,
|
|
75
78
|
...props,
|
|
76
|
-
}, navigation, smallLayout));
|
|
79
|
+
}, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, smallLayout));
|
|
77
80
|
|
|
78
|
-
}, [sideDialogsController, navigation, smallLayout]);
|
|
81
|
+
}, [sideDialogsController, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, smallLayout]);
|
|
79
82
|
|
|
80
83
|
const replace = useCallback((props: EntitySidePanelProps<any>) => {
|
|
81
84
|
|
|
@@ -83,9 +86,9 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
83
86
|
throw Error("If you want to copy an entity you need to provide an entityId");
|
|
84
87
|
}
|
|
85
88
|
|
|
86
|
-
sideDialogsController.replace(propsToSidePanel(props, navigation, smallLayout));
|
|
89
|
+
sideDialogsController.replace(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, smallLayout));
|
|
87
90
|
|
|
88
|
-
}, [navigation, sideDialogsController, smallLayout]);
|
|
91
|
+
}, [navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, sideDialogsController, smallLayout]);
|
|
89
92
|
|
|
90
93
|
return {
|
|
91
94
|
close,
|
|
@@ -146,14 +149,17 @@ export function buildSidePanelsFromUrl(path: string, collections: EntityCollecti
|
|
|
146
149
|
return sidePanels;
|
|
147
150
|
}
|
|
148
151
|
|
|
149
|
-
const propsToSidePanel = (props: EntitySidePanelProps<any>,
|
|
152
|
+
const propsToSidePanel = (props: EntitySidePanelProps<any>,
|
|
153
|
+
buildUrlCollectionPath: (path: string) => string,
|
|
154
|
+
resolveAliasesFrom: (pathWithAliases: string) => string,
|
|
155
|
+
smallLayout: boolean): SideDialogPanelProps => {
|
|
150
156
|
|
|
151
157
|
const collectionPath = removeInitialAndTrailingSlashes(props.path);
|
|
152
158
|
|
|
153
159
|
const newPath = props.entityId
|
|
154
|
-
?
|
|
155
|
-
:
|
|
156
|
-
const resolvedPath =
|
|
160
|
+
? buildUrlCollectionPath(`${collectionPath}/${props.entityId}/${props.selectedSubPath || ""}`)
|
|
161
|
+
: buildUrlCollectionPath(`${collectionPath}#${NEW_URL_HASH}`);
|
|
162
|
+
const resolvedPath = resolveAliasesFrom(props.path);
|
|
157
163
|
|
|
158
164
|
const resolvedPanelProps: EntitySidePanelProps<any> = {
|
|
159
165
|
...props,
|
|
@@ -164,7 +170,7 @@ const propsToSidePanel = (props: EntitySidePanelProps<any>, navigation: Navigati
|
|
|
164
170
|
key: `${props.path}/${props.entityId}`,
|
|
165
171
|
component: <EntitySidePanel {...resolvedPanelProps}/>,
|
|
166
172
|
urlPath: newPath,
|
|
167
|
-
parentUrlPath:
|
|
173
|
+
parentUrlPath: buildUrlCollectionPath(collectionPath),
|
|
168
174
|
width: getEntityViewWidth(props, smallLayout),
|
|
169
175
|
onClose: props.onClose
|
|
170
176
|
});
|
|
@@ -92,7 +92,7 @@ export const PropertyPreview = React.memo(function PropertyPreview<T extends CMS
|
|
|
92
92
|
size={props.size}
|
|
93
93
|
storagePathOrDownloadUrl={value}/>;
|
|
94
94
|
} else if (stringProperty.markdown) {
|
|
95
|
-
content = <Markdown source={value}/>;
|
|
95
|
+
content = <Markdown source={value} size={"small"}/>;
|
|
96
96
|
} else {
|
|
97
97
|
content = <StringPropertyPreview {...props}
|
|
98
98
|
property={stringProperty}
|
|
@@ -113,17 +113,7 @@ export const PropertyPreview = React.memo(function PropertyPreview<T extends CMS
|
|
|
113
113
|
content = <ArrayPropertyPreview {...props}
|
|
114
114
|
value={value}
|
|
115
115
|
property={property as ResolvedArrayProperty}/>;
|
|
116
|
-
}
|
|
117
|
-
// else if (arrayProperty.of.dataType === "map") {
|
|
118
|
-
// content =
|
|
119
|
-
// <ArrayOfMapsPreview propertyKey={propertyKey}
|
|
120
|
-
// property={property as ResolvedArrayProperty}
|
|
121
|
-
// value={value as Record<string, any>[]} // This might be wrong
|
|
122
|
-
// entity={entity}
|
|
123
|
-
// size={size}
|
|
124
|
-
// />;
|
|
125
|
-
// }
|
|
126
|
-
else if (arrayProperty.of.dataType === "reference") {
|
|
116
|
+
} else if (arrayProperty.of.dataType === "reference") {
|
|
127
117
|
content = <ArrayOfReferencesPreview {...props}
|
|
128
118
|
value={value}
|
|
129
119
|
property={property as ResolvedArrayProperty}/>;
|
|
@@ -8,7 +8,7 @@ export type PreviewSize = "medium" | "small" | "tiny";
|
|
|
8
8
|
/**
|
|
9
9
|
* @group Preview components
|
|
10
10
|
*/
|
|
11
|
-
export interface PropertyPreviewProps<T extends CMSType = any, CustomProps = any
|
|
11
|
+
export interface PropertyPreviewProps<T extends CMSType = any, CustomProps = any> {
|
|
12
12
|
/**
|
|
13
13
|
* Name of the property
|
|
14
14
|
*/
|
|
@@ -24,11 +24,6 @@ export interface PropertyPreviewProps<T extends CMSType = any, CustomProps = any
|
|
|
24
24
|
*/
|
|
25
25
|
property: Property<T> | ResolvedProperty<T>;
|
|
26
26
|
|
|
27
|
-
/**
|
|
28
|
-
* Click handler
|
|
29
|
-
*/
|
|
30
|
-
// onClick?: () => void;
|
|
31
|
-
|
|
32
27
|
/**
|
|
33
28
|
* Desired size of the preview, depending on the context.
|
|
34
29
|
*/
|
|
@@ -51,9 +46,4 @@ export interface PropertyPreviewProps<T extends CMSType = any, CustomProps = any
|
|
|
51
46
|
*/
|
|
52
47
|
customProps?: CustomProps;
|
|
53
48
|
|
|
54
|
-
/**
|
|
55
|
-
* Entity this property refers to
|
|
56
|
-
*/
|
|
57
|
-
// entity?: Entity<M>;
|
|
58
|
-
|
|
59
49
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { Checkbox } from "@firecms/ui";
|
|
2
|
+
import { Checkbox, cn } from "@firecms/ui";
|
|
3
3
|
import { PreviewSize } from "../PropertyPreviewProps";
|
|
4
4
|
import { Property } from "../../types";
|
|
5
5
|
|
|
@@ -17,8 +17,10 @@ export function BooleanPreview({
|
|
|
17
17
|
}): React.ReactElement {
|
|
18
18
|
return <div className={"flex flex-row gap-2 items-center"}>
|
|
19
19
|
<Checkbox checked={value}
|
|
20
|
+
padding={false}
|
|
20
21
|
size={size}
|
|
21
22
|
color={"secondary"}/>
|
|
22
|
-
{property.name && <span
|
|
23
|
+
{property.name && <span
|
|
24
|
+
className={cn("text-text-secondary dark:text-text-secondary-dark", size === "tiny" ? "text-sm" : "")}>{property.name}</span>}
|
|
23
25
|
</div>;
|
|
24
26
|
}
|
|
@@ -64,7 +64,7 @@ function ReferencePreviewInternal<M extends Record<string, any>>({
|
|
|
64
64
|
|
|
65
65
|
const navigationController = useNavigationController();
|
|
66
66
|
|
|
67
|
-
const collection = navigationController.getCollection
|
|
67
|
+
const collection = navigationController.getCollection(reference.path);
|
|
68
68
|
if (!collection) {
|
|
69
69
|
if (customizationController.components?.missingReference) {
|
|
70
70
|
return <customizationController.components.missingReference path={reference.path}/>;
|
package/src/types/auth.tsx
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { User } from "./user";
|
|
2
|
+
import { Role } from "./roles";
|
|
3
|
+
import { DataSourceDelegate } from "./datasource";
|
|
4
|
+
import { StorageSource } from "./storage";
|
|
2
5
|
|
|
3
6
|
/**
|
|
4
7
|
* Controller for retrieving the logged user or performing auth related operations.
|
|
@@ -6,7 +9,7 @@ import { User } from "./user";
|
|
|
6
9
|
* to do it as the result of a hook.
|
|
7
10
|
* @group Hooks and utilities
|
|
8
11
|
*/
|
|
9
|
-
export type AuthController<UserType extends User =
|
|
12
|
+
export type AuthController<UserType extends User = any, ExtraData extends any = any> = {
|
|
10
13
|
|
|
11
14
|
/**
|
|
12
15
|
* The user currently logged in
|
|
@@ -14,6 +17,11 @@ export type AuthController<UserType extends User = User, ExtraData extends any =
|
|
|
14
17
|
*/
|
|
15
18
|
user: UserType | null;
|
|
16
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Roles related to the logged user
|
|
22
|
+
*/
|
|
23
|
+
roles?: Role[];
|
|
24
|
+
|
|
17
25
|
/**
|
|
18
26
|
* Initial loading flag. It is used not to display the login screen
|
|
19
27
|
* when the app first loads, and it has not been checked whether the user
|
|
@@ -56,4 +64,35 @@ export type AuthController<UserType extends User = User, ExtraData extends any =
|
|
|
56
64
|
|
|
57
65
|
setExtra: (extra: ExtraData) => void;
|
|
58
66
|
|
|
67
|
+
// setUser?: (user: UserType | null) => void;
|
|
68
|
+
|
|
69
|
+
// setRoles?: (roles: Role[]) => void;
|
|
59
70
|
};
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Implement this function to allow access to specific users.
|
|
74
|
+
* @group Hooks and utilities
|
|
75
|
+
*/
|
|
76
|
+
export type Authenticator<UserType extends User = User, Controller extends AuthController<UserType> = AuthController<UserType>> = (props: {
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Logged-in user or null
|
|
80
|
+
*/
|
|
81
|
+
user: UserType | null;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* AuthController
|
|
85
|
+
*/
|
|
86
|
+
authController: Controller;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Connector to your database, e.g. your Firestore database
|
|
90
|
+
*/
|
|
91
|
+
dataSourceDelegate: DataSourceDelegate;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Used storage implementation
|
|
95
|
+
*/
|
|
96
|
+
storageSource: StorageSource;
|
|
97
|
+
|
|
98
|
+
}) => boolean | Promise<boolean>;
|
package/src/types/collections.ts
CHANGED
|
@@ -17,7 +17,7 @@ import { EntityOverrides } from "./entity_overrides";
|
|
|
17
17
|
*
|
|
18
18
|
* @group Models
|
|
19
19
|
*/
|
|
20
|
-
export interface EntityCollection<M extends Record<string, any> = any, UserType extends User =
|
|
20
|
+
export interface EntityCollection<M extends Record<string, any> = any, UserType extends User = any> {
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* You can set an alias that will be used internally instead of the `path`.
|
|
@@ -107,6 +107,10 @@ export interface EntityCollection<M extends Record<string, any> = any, UserType
|
|
|
107
107
|
* `subcollection:`. e.g. `subcollection:orders`.
|
|
108
108
|
* - If you are using a collection group, you will also have an
|
|
109
109
|
* additional `collectionGroupParent` column.
|
|
110
|
+
* You can use this prop to hide some properties from the table view.
|
|
111
|
+
* Note that if you set this prop, other ways to hide fields, like
|
|
112
|
+
* `hidden` in the property definition,will be ignored.
|
|
113
|
+
* `propertiesOrder` has precedence over `hidden`.
|
|
110
114
|
*/
|
|
111
115
|
propertiesOrder?: Extract<keyof M, string>[];
|
|
112
116
|
|
|
@@ -147,7 +151,7 @@ export interface EntityCollection<M extends Record<string, any> = any, UserType
|
|
|
147
151
|
* is being created, updated or deleted.
|
|
148
152
|
* Useful for adding your own logic or blocking the execution of the operation.
|
|
149
153
|
*/
|
|
150
|
-
callbacks?: EntityCallbacks<M>;
|
|
154
|
+
callbacks?: EntityCallbacks<M, UserType>;
|
|
151
155
|
|
|
152
156
|
/**
|
|
153
157
|
* Builder for rendering additional components such as buttons in the
|
|
@@ -451,7 +455,7 @@ export interface AdditionalFieldDelegate<M extends Record<string, any> = any,
|
|
|
451
455
|
* view.
|
|
452
456
|
* @param entity
|
|
453
457
|
*/
|
|
454
|
-
value?: (props: { entity: Entity<M>, context: FireCMSContext }) => string | number | Promise<string | number> | undefined;
|
|
458
|
+
value?: (props: { entity: Entity<M>, context: FireCMSContext<any> }) => string | number | Promise<string | number> | undefined;
|
|
455
459
|
}
|
|
456
460
|
|
|
457
461
|
/**
|
|
@@ -523,7 +527,7 @@ export type EntityTableController<M extends Record<string, any> = any> = {
|
|
|
523
527
|
filterValues?: FilterValues<Extract<keyof M, string>>;
|
|
524
528
|
setFilterValues?: (filterValues: FilterValues<Extract<keyof M, string>>) => void;
|
|
525
529
|
sortBy?: [Extract<keyof M, string>, "asc" | "desc"];
|
|
526
|
-
setSortBy?: (sortBy
|
|
530
|
+
setSortBy?: (sortBy?: [Extract<keyof M, string>, "asc" | "desc"]) => void;
|
|
527
531
|
searchString?: string;
|
|
528
532
|
setSearchString?: (searchString?: string) => void;
|
|
529
533
|
clearFilter?: () => void;
|
package/src/types/datasource.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { ResolvedEntityCollection } from "./resolved_entities";
|
|
|
8
8
|
export interface FetchEntityProps<M extends Record<string, any> = any> {
|
|
9
9
|
path: string;
|
|
10
10
|
entityId: string;
|
|
11
|
-
collection?: EntityCollection<M>
|
|
11
|
+
collection?: EntityCollection<M, any>
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
/**
|
|
@@ -216,6 +216,7 @@ export interface DataSource {
|
|
|
216
216
|
* @param props
|
|
217
217
|
*/
|
|
218
218
|
isFilterCombinationValid?(props: FilterCombinationValidProps): boolean;
|
|
219
|
+
|
|
219
220
|
}
|
|
220
221
|
|
|
221
222
|
export type FilterCombinationValidProps = {
|
|
@@ -366,24 +367,26 @@ export interface DataSourceDelegate {
|
|
|
366
367
|
* Convert a FireCMS reference to a reference that can be used by the datasource
|
|
367
368
|
* @param reference
|
|
368
369
|
*/
|
|
369
|
-
buildReference: (reference: EntityReference) => any,
|
|
370
|
+
// buildReference: (reference: EntityReference) => any,
|
|
370
371
|
|
|
371
372
|
/**
|
|
372
373
|
* Convert a FireCMS GeoPoint to a GeoPoint that can be used by the datasource
|
|
373
374
|
* @param geoPoint
|
|
374
375
|
*/
|
|
375
|
-
buildGeoPoint: (geoPoint: GeoPoint) => any,
|
|
376
|
+
// buildGeoPoint: (geoPoint: GeoPoint) => any,
|
|
376
377
|
|
|
377
378
|
/**
|
|
378
379
|
* Get the object to generate the current time in the datasource
|
|
379
380
|
*/
|
|
380
381
|
currentTime(): any;
|
|
381
382
|
|
|
382
|
-
buildDate: (date: Date) => any;
|
|
383
|
+
// buildDate: (date: Date) => any;
|
|
383
384
|
|
|
384
|
-
buildDeleteFieldValue: () => any;
|
|
385
|
+
// buildDeleteFieldValue: () => any;
|
|
385
386
|
|
|
386
387
|
delegateToCMSModel: (data: any) => any;
|
|
387
388
|
|
|
389
|
+
cmsToDelegateModel: (data: any) => any;
|
|
390
|
+
|
|
388
391
|
setDateToMidnight: (input?: any) => any;
|
|
389
392
|
}
|
package/src/types/entities.ts
CHANGED
|
@@ -37,7 +37,7 @@ export type EntityValues<M extends object> = M;
|
|
|
37
37
|
/**
|
|
38
38
|
* Class used to create a reference to an entity in a different path
|
|
39
39
|
*/
|
|
40
|
-
export class EntityReference
|
|
40
|
+
export class EntityReference {
|
|
41
41
|
/**
|
|
42
42
|
* ID of the entity
|
|
43
43
|
*/
|
|
@@ -78,3 +78,11 @@ export class GeoPoint {
|
|
|
78
78
|
this.longitude = longitude;
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
|
+
|
|
82
|
+
export class Vector {
|
|
83
|
+
readonly value: number[];
|
|
84
|
+
|
|
85
|
+
constructor(value: number[]) {
|
|
86
|
+
this.value = value;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -78,7 +78,7 @@ export interface EntityOnFetchProps<M extends Record<string, any> = any, UserTyp
|
|
|
78
78
|
/**
|
|
79
79
|
* Collection of the entity
|
|
80
80
|
*/
|
|
81
|
-
collection: EntityCollection<M>;
|
|
81
|
+
collection: EntityCollection<M, UserType>;
|
|
82
82
|
|
|
83
83
|
/**
|
|
84
84
|
* Full path of the CMS where this collection is being fetched.
|
|
@@ -193,7 +193,7 @@ export interface EntityOnDeleteProps<M extends Record<string, any> = any, UserTy
|
|
|
193
193
|
/**
|
|
194
194
|
* Context of the app status
|
|
195
195
|
*/
|
|
196
|
-
context: FireCMSContext
|
|
196
|
+
context: FireCMSContext<UserType>;
|
|
197
197
|
}
|
|
198
198
|
|
|
199
199
|
/**
|
package/src/types/index.ts
CHANGED
|
@@ -22,7 +22,7 @@ export * from "./local_config_persistence";
|
|
|
22
22
|
export * from "./plugins";
|
|
23
23
|
export * from "./analytics";
|
|
24
24
|
export * from "./firecms";
|
|
25
|
-
export * from "./
|
|
25
|
+
export * from "./roles";
|
|
26
26
|
export * from "./export_import";
|
|
27
27
|
export * from "./modify_collections";
|
|
28
28
|
export * from "./analytics_controller";
|
package/src/types/navigation.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { EntityReference } from "./entities";
|
|
|
7
7
|
* attributes.
|
|
8
8
|
* @group Models
|
|
9
9
|
*/
|
|
10
|
-
export type NavigationController = {
|
|
10
|
+
export type NavigationController<EC extends EntityCollection = EntityCollection<any>> = {
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* List of the mapped collections in the CMS.
|
|
@@ -56,18 +56,18 @@ export type NavigationController = {
|
|
|
56
56
|
* Get the collection configuration for a given path.
|
|
57
57
|
* The collection is resolved from the given path or alias.
|
|
58
58
|
*/
|
|
59
|
-
getCollection:
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
getCollection: (pathOrId: string,
|
|
60
|
+
entityId?: string,
|
|
61
|
+
includeUserOverride?: boolean) => EC | undefined;
|
|
62
62
|
/**
|
|
63
63
|
* Get the collection configuration from its parent path segments.
|
|
64
64
|
*/
|
|
65
|
-
getCollectionFromIds:
|
|
65
|
+
getCollectionFromIds: (ids: string[]) => EC | undefined;
|
|
66
66
|
|
|
67
67
|
/**
|
|
68
68
|
* Get the collection configuration from its parent path segments.
|
|
69
69
|
*/
|
|
70
|
-
getCollectionFromPaths:
|
|
70
|
+
getCollectionFromPaths: (pathSegments: string[]) => EC | undefined;
|
|
71
71
|
|
|
72
72
|
/**
|
|
73
73
|
* Default path under the navigation routes of the CMS will be created
|
package/src/types/plugins.tsx
CHANGED
|
@@ -7,19 +7,18 @@ import { FieldProps, FormContext } from "./fields";
|
|
|
7
7
|
import { CMSType, Property } from "./properties";
|
|
8
8
|
import { EntityStatus } from "./entities";
|
|
9
9
|
import { ResolvedProperty } from "./resolved_entities";
|
|
10
|
-
import { CMSView } from "./navigation";
|
|
11
10
|
|
|
12
11
|
/**
|
|
13
12
|
* Interface used to define plugins for FireCMS.
|
|
14
13
|
* NOTE: This is a work in progress and the API is not stable yet.
|
|
15
14
|
* @group Core
|
|
16
15
|
*/
|
|
17
|
-
export type FireCMSPlugin<PROPS = any, FORM_PROPS = any, EC extends EntityCollection = EntityCollection, COL_ACTIONS_PROPS = any> = {
|
|
16
|
+
export type FireCMSPlugin<PROPS = any, FORM_PROPS = any, EC extends EntityCollection = EntityCollection, COL_ACTIONS_PROPS = any, COL_ACTIONS_START__PROPS = any> = {
|
|
18
17
|
|
|
19
18
|
/**
|
|
20
|
-
*
|
|
19
|
+
* Key of the plugin. This is used to identify the plugin in the CMS.
|
|
21
20
|
*/
|
|
22
|
-
|
|
21
|
+
key: string;
|
|
23
22
|
|
|
24
23
|
/**
|
|
25
24
|
* If this flag is set to true, no content will be shown in the CMS
|
|
@@ -94,9 +93,11 @@ export type FireCMSPlugin<PROPS = any, FORM_PROPS = any, EC extends EntityCollec
|
|
|
94
93
|
* toolbar.
|
|
95
94
|
*/
|
|
96
95
|
CollectionActions?: React.ComponentType<CollectionActionsProps<any, any, EC> & COL_ACTIONS_PROPS> | React.ComponentType<CollectionActionsProps<any, any, EC> & COL_ACTIONS_PROPS>[];
|
|
97
|
-
|
|
98
96
|
collectionActionsProps?: COL_ACTIONS_PROPS;
|
|
99
97
|
|
|
98
|
+
CollectionActionsStart?: React.ComponentType<CollectionActionsProps<any, any, EC> & COL_ACTIONS_START__PROPS> | React.ComponentType<CollectionActionsProps<any, any, EC> & COL_ACTIONS_START__PROPS>[];
|
|
99
|
+
collectionActionsStartProps?: COL_ACTIONS_START__PROPS;
|
|
100
|
+
|
|
100
101
|
showTextSearchBar?: (props: {
|
|
101
102
|
context: FireCMSContext,
|
|
102
103
|
path: string,
|
package/src/types/properties.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { FieldProps } from "./fields";
|
|
3
3
|
import { PropertyPreviewProps } from "../preview";
|
|
4
|
-
import { EntityReference, EntityValues, GeoPoint } from "./entities";
|
|
4
|
+
import { EntityReference, EntityValues, GeoPoint, Vector } from "./entities";
|
|
5
5
|
import { ResolvedArrayProperty, ResolvedStringProperty } from "./resolved_entities";
|
|
6
6
|
import { FilterValues } from "./collections";
|
|
7
7
|
import { ChipColorKey, ChipColorScheme } from "@firecms/ui";
|
|
@@ -15,9 +15,10 @@ export type DataType<T extends CMSType = CMSType> =
|
|
|
15
15
|
T extends boolean ? "boolean" :
|
|
16
16
|
T extends Date ? "date" :
|
|
17
17
|
T extends GeoPoint ? "geopoint" :
|
|
18
|
-
T extends
|
|
19
|
-
T extends
|
|
20
|
-
T extends
|
|
18
|
+
T extends Vector ? "vector" :
|
|
19
|
+
T extends EntityReference ? "reference" :
|
|
20
|
+
T extends Array<CMSType> ? "array" :
|
|
21
|
+
T extends Record<string, any> ? "map" : never;
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* @group Entity properties
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Permissions } from "../index";
|
|
2
|
+
|
|
3
|
+
export type Role = {
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* ID of the role
|
|
7
|
+
*/
|
|
8
|
+
id: string;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Name of the role
|
|
12
|
+
*/
|
|
13
|
+
name: string;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* If this flag is true, the user can perform any action
|
|
17
|
+
*/
|
|
18
|
+
isAdmin?: boolean;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Default permissions for all collections for this role.
|
|
22
|
+
* You can override this values at the collection level using
|
|
23
|
+
* {@link collectionPermissions}
|
|
24
|
+
*/
|
|
25
|
+
defaultPermissions?: Permissions;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Record of stripped collection ids to their permissions.
|
|
29
|
+
* @see stripCollectionPath
|
|
30
|
+
*/
|
|
31
|
+
collectionPermissions?: Record<string, Permissions>;
|
|
32
|
+
|
|
33
|
+
config?: {
|
|
34
|
+
|
|
35
|
+
createCollections?: boolean;
|
|
36
|
+
|
|
37
|
+
editCollections?: boolean | "own";
|
|
38
|
+
|
|
39
|
+
deleteCollections?: boolean | "own";
|
|
40
|
+
}
|
|
41
|
+
}
|
package/src/types/storage.ts
CHANGED
|
@@ -6,6 +6,7 @@ export interface UploadFileProps {
|
|
|
6
6
|
fileName?: string,
|
|
7
7
|
path?: string,
|
|
8
8
|
metadata?: any,
|
|
9
|
+
bucket?: string
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
/**
|
|
@@ -16,6 +17,10 @@ export interface UploadFileResult {
|
|
|
16
17
|
* Storage path including the file name where the file was uploaded.
|
|
17
18
|
*/
|
|
18
19
|
path: string;
|
|
20
|
+
/**
|
|
21
|
+
* Bucket where the file was uploaded
|
|
22
|
+
*/
|
|
23
|
+
bucket: string;
|
|
19
24
|
}
|
|
20
25
|
|
|
21
26
|
/**
|
|
@@ -73,24 +78,28 @@ export interface StorageSource {
|
|
|
73
78
|
* @param fileName
|
|
74
79
|
* @param path
|
|
75
80
|
* @param metadata
|
|
81
|
+
* @param bucket
|
|
76
82
|
*/
|
|
77
83
|
uploadFile: ({
|
|
78
84
|
file,
|
|
79
85
|
fileName,
|
|
80
86
|
path,
|
|
81
|
-
metadata
|
|
87
|
+
metadata,
|
|
88
|
+
bucket
|
|
82
89
|
}: UploadFileProps) => Promise<UploadFileResult>;
|
|
83
90
|
|
|
84
91
|
/**
|
|
85
92
|
* Convert a storage path or URL into a download configuration
|
|
86
93
|
* @param path
|
|
94
|
+
* @param bucket
|
|
87
95
|
*/
|
|
88
|
-
getDownloadURL: (pathOrUrl: string) => Promise<DownloadConfig>;
|
|
96
|
+
getDownloadURL: (pathOrUrl: string, bucket?: string) => Promise<DownloadConfig>;
|
|
89
97
|
|
|
90
98
|
/**
|
|
91
99
|
* Get a file from a storage path.
|
|
92
100
|
* It returns null if the file does not exist.
|
|
93
101
|
* @param props
|
|
102
|
+
* @param bucket
|
|
94
103
|
*/
|
|
95
|
-
getFile: (path:string) => Promise<File | null>;
|
|
104
|
+
getFile: (path:string, bucket?: string) => Promise<File | null>;
|
|
96
105
|
}
|
package/src/types/user.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { Role } from "./roles";
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* This interface represents a user.
|
|
3
5
|
* It has some of the same fields as a Firebase User.
|
|
@@ -34,4 +36,9 @@ export type User = {
|
|
|
34
36
|
*/
|
|
35
37
|
readonly isAnonymous: boolean;
|
|
36
38
|
|
|
39
|
+
/**
|
|
40
|
+
*
|
|
41
|
+
*/
|
|
42
|
+
roles?: Role[];
|
|
43
|
+
|
|
37
44
|
};
|
package/src/util/collections.ts
CHANGED
|
@@ -58,7 +58,7 @@ export function resolveDefaultSelectedView(
|
|
|
58
58
|
* @param collections
|
|
59
59
|
* @param permissionsBuilder
|
|
60
60
|
*/
|
|
61
|
-
export const applyPermissionsFunctionIfEmpty = (collections: EntityCollection[], permissionsBuilder?: PermissionsBuilder): EntityCollection[] => {
|
|
61
|
+
export const applyPermissionsFunctionIfEmpty = (collections: EntityCollection[], permissionsBuilder?: PermissionsBuilder<any, any>): EntityCollection[] => {
|
|
62
62
|
|
|
63
63
|
return collections.map(collection => {
|
|
64
64
|
if (collection.permissions) {
|
package/src/util/entities.ts
CHANGED
|
@@ -139,7 +139,7 @@ export function sanitizeData<M extends Record<string, any>>
|
|
|
139
139
|
return result;
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
-
export function getReferenceFrom<M extends Record<string, any>>(entity: Entity<M>): EntityReference
|
|
142
|
+
export function getReferenceFrom<M extends Record<string, any>>(entity: Entity<M>): EntityReference {
|
|
143
143
|
return new EntityReference(entity.id, entity.path);
|
|
144
144
|
}
|
|
145
145
|
|
|
@@ -60,14 +60,14 @@ export function resolveCollectionPathIds(path: string, allCollections: EntityCol
|
|
|
60
60
|
/**
|
|
61
61
|
* Find the corresponding view at any depth for a given path.
|
|
62
62
|
* Note that path or segments of the paths can be collection aliases.
|
|
63
|
-
* @param
|
|
63
|
+
* @param pathOrId
|
|
64
64
|
* @param collections
|
|
65
65
|
*/
|
|
66
|
-
export function getCollectionByPathOrId(
|
|
66
|
+
export function getCollectionByPathOrId(pathOrId: string, collections: EntityCollection[]): EntityCollection | undefined {
|
|
67
67
|
|
|
68
|
-
const subpaths = removeInitialAndTrailingSlashes(
|
|
68
|
+
const subpaths = removeInitialAndTrailingSlashes(pathOrId).split("/");
|
|
69
69
|
if (subpaths.length % 2 === 0) {
|
|
70
|
-
throw Error(`
|
|
70
|
+
throw Error(`getCollectionByPathOrId: Collection paths must have an odd number of segments: ${pathOrId}`);
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
const subpathCombinations = getCollectionPathsCombinations(subpaths);
|
|
@@ -80,10 +80,10 @@ export function getCollectionByPathOrId(pathOrAlias: string, collections: Entity
|
|
|
80
80
|
|
|
81
81
|
if (navigationEntry) {
|
|
82
82
|
|
|
83
|
-
if (subpathCombination ===
|
|
83
|
+
if (subpathCombination === pathOrId) {
|
|
84
84
|
result = navigationEntry;
|
|
85
85
|
} else if (navigationEntry.subcollections) {
|
|
86
|
-
const newPath =
|
|
86
|
+
const newPath = pathOrId.replace(subpathCombination, "").split("/").slice(2).join("/");
|
|
87
87
|
if (newPath.length > 0)
|
|
88
88
|
result = getCollectionByPathOrId(newPath, navigationEntry.subcollections);
|
|
89
89
|
}
|
package/src/util/strings.ts
CHANGED
|
@@ -56,8 +56,8 @@ export function unslugify(slug?: string): string {
|
|
|
56
56
|
const result = slug.replace(/[-_]/g, " ");
|
|
57
57
|
return result.replace(/\w\S*/g, function (txt) {
|
|
58
58
|
return txt.charAt(0).toUpperCase() + txt.substr(1);
|
|
59
|
-
});
|
|
59
|
+
}).trim();
|
|
60
60
|
} else {
|
|
61
|
-
return slug;
|
|
61
|
+
return slug.trim();
|
|
62
62
|
}
|
|
63
63
|
}
|