@firecms/core 3.0.0-canary.43 → 3.0.0-canary.45
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/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +1 -1
- package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +3 -1
- package/dist/components/EntityCollectionTable/PropertyTableCell.d.ts +1 -0
- package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +1 -1
- package/dist/components/FireCMSAppBar.d.ts +3 -2
- package/dist/components/common/types.d.ts +3 -5
- package/dist/core/NavigationRoutes.d.ts +1 -1
- package/dist/core/Scaffold.d.ts +1 -1
- package/dist/hooks/data/save.d.ts +1 -2
- package/dist/index.es.js +3829 -3813
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +5 -5
- package/dist/index.umd.js.map +1 -1
- package/package.json +4 -4
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +6 -2
- package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +5 -3
- package/src/components/EntityCollectionTable/PropertyTableCell.tsx +17 -13
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +2 -4
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +6 -5
- package/src/components/FireCMSAppBar.tsx +23 -8
- package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +1 -0
- package/src/components/VirtualTable/VirtualTable.tsx +1 -1
- package/src/components/common/types.tsx +3 -5
- package/src/core/NavigationRoutes.tsx +3 -4
- package/src/core/Scaffold.tsx +5 -4
- package/src/hooks/data/save.ts +0 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@firecms/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "3.0.0-canary.
|
|
4
|
+
"version": "3.0.0-canary.45",
|
|
5
5
|
"description": "Awesome Firebase/Firestore-based headless open-source CMS",
|
|
6
6
|
"funding": {
|
|
7
7
|
"url": "https://github.com/sponsors/firecmsco"
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"./package.json": "./package.json"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@firecms/formex": "^3.0.0-canary.
|
|
50
|
-
"@firecms/ui": "^3.0.0-canary.
|
|
49
|
+
"@firecms/formex": "^3.0.0-canary.45",
|
|
50
|
+
"@firecms/ui": "^3.0.0-canary.45",
|
|
51
51
|
"@fontsource/jetbrains-mono": "^5.0.19",
|
|
52
52
|
"@hello-pangea/dnd": "^16.6.0",
|
|
53
53
|
"@radix-ui/react-portal": "^1.0.4",
|
|
@@ -118,7 +118,7 @@
|
|
|
118
118
|
"dist",
|
|
119
119
|
"src"
|
|
120
120
|
],
|
|
121
|
-
"gitHead": "
|
|
121
|
+
"gitHead": "7f22bfa3bb20479ad23becd9c10f78cac1a3bc32",
|
|
122
122
|
"publishConfig": {
|
|
123
123
|
"access": "public"
|
|
124
124
|
}
|
|
@@ -15,6 +15,7 @@ import { renderSkeletonText } from "../../preview";
|
|
|
15
15
|
import { propertiesToColumns } from "./column_utils";
|
|
16
16
|
import { ErrorView } from "../ErrorView";
|
|
17
17
|
import { SelectableTable } from "../SelectableTable/SelectableTable";
|
|
18
|
+
import { cn } from "@firecms/ui";
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* This component is in charge of rendering a collection table with a high
|
|
@@ -42,6 +43,7 @@ import { SelectableTable } from "../SelectableTable/SelectableTable";
|
|
|
42
43
|
*/
|
|
43
44
|
export const EntityCollectionTable = function EntityCollectionTable<M extends Record<string, any>, UserType extends User>
|
|
44
45
|
({
|
|
46
|
+
className,
|
|
45
47
|
forceFilter,
|
|
46
48
|
actionsStart,
|
|
47
49
|
actions,
|
|
@@ -72,7 +74,8 @@ export const EntityCollectionTable = function EntityCollectionTable<M extends Re
|
|
|
72
74
|
emptyComponent,
|
|
73
75
|
getIdColumnWidth,
|
|
74
76
|
onTextSearchClick,
|
|
75
|
-
textSearchLoading
|
|
77
|
+
textSearchLoading,
|
|
78
|
+
enablePopupIcon
|
|
76
79
|
}: EntityCollectionTableProps<M>) {
|
|
77
80
|
|
|
78
81
|
const ref = useRef<HTMLDivElement>(null);
|
|
@@ -147,6 +150,7 @@ export const EntityCollectionTable = function EntityCollectionTable<M extends Re
|
|
|
147
150
|
height={getRowHeight(size)}
|
|
148
151
|
entity={entity}
|
|
149
152
|
disabled={disabled}
|
|
153
|
+
enablePopupIcon={enablePopupIcon}
|
|
150
154
|
path={entity.path}/>
|
|
151
155
|
: renderSkeletonText()
|
|
152
156
|
}
|
|
@@ -290,7 +294,7 @@ export const EntityCollectionTable = function EntityCollectionTable<M extends Re
|
|
|
290
294
|
return (
|
|
291
295
|
|
|
292
296
|
<div ref={ref}
|
|
293
|
-
className="h-full w-full flex flex-col bg-white dark:bg-gray-950">
|
|
297
|
+
className={cn("h-full w-full flex flex-col bg-white dark:bg-gray-950", className)}>
|
|
294
298
|
|
|
295
299
|
<CollectionTableToolbar
|
|
296
300
|
onTextSearch={textSearchEnabled ? onTextSearch : undefined}
|
|
@@ -12,13 +12,13 @@ import {
|
|
|
12
12
|
} from "../../types";
|
|
13
13
|
import { OnCellValueChange, OnColumnResizeParams, UniqueFieldValidator } from "../common/types";
|
|
14
14
|
|
|
15
|
-
|
|
16
15
|
/**
|
|
17
16
|
* @group Collection components
|
|
18
17
|
*/
|
|
19
18
|
export type EntityCollectionTableProps<M extends Record<string, any>,
|
|
20
19
|
UserType extends User = User> = {
|
|
21
20
|
|
|
21
|
+
className?: string;
|
|
22
22
|
/**
|
|
23
23
|
* Display these entities as selected
|
|
24
24
|
*/
|
|
@@ -131,7 +131,9 @@ export type EntityCollectionTableProps<M extends Record<string, any>,
|
|
|
131
131
|
onTextSearchClick?: () => void;
|
|
132
132
|
|
|
133
133
|
textSearchLoading?: boolean;
|
|
134
|
-
|
|
134
|
+
|
|
135
|
+
enablePopupIcon: boolean;
|
|
136
|
+
};
|
|
135
137
|
|
|
136
138
|
export type GetPropertyForProps<M extends Record<string, any>> = {
|
|
137
139
|
propertyKey: string,
|
|
@@ -141,5 +143,5 @@ export type GetPropertyForProps<M extends Record<string, any>> = {
|
|
|
141
143
|
|
|
142
144
|
export type PropertyColumnConfig = {
|
|
143
145
|
key: string,
|
|
144
|
-
disabled
|
|
146
|
+
disabled?: boolean,
|
|
145
147
|
};
|
|
@@ -46,6 +46,7 @@ export interface PropertyTableCellProps<T extends CMSType> {
|
|
|
46
46
|
entity: Entity<any>;
|
|
47
47
|
path: string;
|
|
48
48
|
disabled: boolean;
|
|
49
|
+
enablePopupIcon?: boolean;
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
function isStorageProperty(property: ResolvedProperty) {
|
|
@@ -74,11 +75,10 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any>>(
|
|
|
74
75
|
path,
|
|
75
76
|
entity,
|
|
76
77
|
readonly,
|
|
77
|
-
disabled: disabledProp
|
|
78
|
+
disabled: disabledProp,
|
|
79
|
+
enablePopupIcon = true
|
|
78
80
|
}: PropertyTableCellProps<T>) {
|
|
79
81
|
|
|
80
|
-
const context = useFireCMSContext();
|
|
81
|
-
|
|
82
82
|
const {
|
|
83
83
|
onValueChange,
|
|
84
84
|
size,
|
|
@@ -140,15 +140,19 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any>>(
|
|
|
140
140
|
setValidationError(undefined);
|
|
141
141
|
internalValueRef.current = value;
|
|
142
142
|
if (onValueChange) {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
})
|
|
143
|
+
try {
|
|
144
|
+
onValueChange({
|
|
145
|
+
value,
|
|
146
|
+
propertyKey,
|
|
147
|
+
setError,
|
|
148
|
+
onValueUpdated,
|
|
149
|
+
data: entity,
|
|
150
|
+
});
|
|
151
|
+
} catch (e:any) {
|
|
152
|
+
console.error("onValueChange error", e);
|
|
153
|
+
setError(e);
|
|
154
|
+
}
|
|
155
|
+
|
|
152
156
|
}
|
|
153
157
|
})
|
|
154
158
|
.catch((e) => {
|
|
@@ -399,7 +403,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any>>(
|
|
|
399
403
|
|
|
400
404
|
if (!innerComponent) {
|
|
401
405
|
allowScroll = false;
|
|
402
|
-
showExpandIcon = selected && !innerComponent && !disabled && !readOnlyProperty;
|
|
406
|
+
showExpandIcon = enablePopupIcon && selected && !innerComponent && !disabled && !readOnlyProperty;
|
|
403
407
|
innerComponent = (
|
|
404
408
|
<PropertyPreview width={width}
|
|
405
409
|
height={height}
|
|
@@ -41,7 +41,7 @@ interface PopupFormFieldProps<M extends Record<string, any>> {
|
|
|
41
41
|
* Callback when the value of a cell has been edited
|
|
42
42
|
* @param params
|
|
43
43
|
*/
|
|
44
|
-
onCellValueChange?: (params: OnCellValueChangeParams<any,
|
|
44
|
+
onCellValueChange?: (params: OnCellValueChangeParams<any, any>) => Promise<void> | void;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
export function PopupFormField<M extends Record<string, any>>(props: PopupFormFieldProps<M>) {
|
|
@@ -205,12 +205,10 @@ export function PopupFormFieldInternal<M extends Record<string, any>>({
|
|
|
205
205
|
return onCellValueChange({
|
|
206
206
|
value: values[propertyKey as string],
|
|
207
207
|
propertyKey: propertyKey as string,
|
|
208
|
-
entity,
|
|
208
|
+
data: entity,
|
|
209
209
|
setError: setSavingError,
|
|
210
210
|
onValueUpdated: () => {
|
|
211
211
|
},
|
|
212
|
-
fullPath: path,
|
|
213
|
-
context: fireCMSContext
|
|
214
212
|
});
|
|
215
213
|
}
|
|
216
214
|
return Promise.resolve();
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
saveEntityWithCallbacks,
|
|
35
35
|
useAuthController,
|
|
36
36
|
useCustomizationController,
|
|
37
|
-
useDataSource,
|
|
37
|
+
useDataSource, useFireCMSContext,
|
|
38
38
|
useLargeLayout,
|
|
39
39
|
useNavigationController,
|
|
40
40
|
useSideEntityController
|
|
@@ -94,7 +94,9 @@ export type EntityCollectionViewProps<M extends Record<string, any>> = {
|
|
|
94
94
|
* Whether this is a subcollection or not.
|
|
95
95
|
*/
|
|
96
96
|
isSubCollection?: boolean;
|
|
97
|
+
|
|
97
98
|
className?: string;
|
|
99
|
+
|
|
98
100
|
} & EntityCollection<M>;
|
|
99
101
|
|
|
100
102
|
/**
|
|
@@ -131,6 +133,7 @@ export const EntityCollectionView = React.memo(
|
|
|
131
133
|
}: EntityCollectionViewProps<M>
|
|
132
134
|
) {
|
|
133
135
|
|
|
136
|
+
const context = useFireCMSContext();
|
|
134
137
|
const fullPath = fullPathProp ?? collectionProp.path;
|
|
135
138
|
const dataSource = useDataSource(collectionProp);
|
|
136
139
|
const navigation = useNavigationController();
|
|
@@ -311,13 +314,11 @@ export const EntityCollectionView = React.memo(
|
|
|
311
314
|
[fullPath]);
|
|
312
315
|
|
|
313
316
|
const onValueChange: OnCellValueChange<any, any> = ({
|
|
314
|
-
fullPath,
|
|
315
|
-
context,
|
|
316
317
|
value,
|
|
317
318
|
propertyKey,
|
|
318
319
|
onValueUpdated,
|
|
319
320
|
setError,
|
|
320
|
-
entity,
|
|
321
|
+
data: entity,
|
|
321
322
|
}) => {
|
|
322
323
|
|
|
323
324
|
const updatedValues = setIn({ ...entity.values }, propertyKey, value);
|
|
@@ -334,7 +335,6 @@ export const EntityCollectionView = React.memo(
|
|
|
334
335
|
return saveEntityWithCallbacks({
|
|
335
336
|
...saveProps,
|
|
336
337
|
collection,
|
|
337
|
-
callbacks: collection.callbacks,
|
|
338
338
|
dataSource,
|
|
339
339
|
context,
|
|
340
340
|
onSaveSuccess: () => {
|
|
@@ -603,6 +603,7 @@ export const EntityCollectionView = React.memo(
|
|
|
603
603
|
key={`collection_table_${fullPath}`}
|
|
604
604
|
additionalFields={additionalFields}
|
|
605
605
|
tableController={tableController}
|
|
606
|
+
enablePopupIcon={true}
|
|
606
607
|
displayedColumnIds={displayedColumnIds}
|
|
607
608
|
onSizeChanged={onSizeChanged}
|
|
608
609
|
onEntityClick={onEntityClick}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
|
|
3
3
|
import { Link as ReactLink } from "react-router-dom";
|
|
4
|
-
import { ErrorBoundary } from "../components";
|
|
4
|
+
import { ErrorBoundary, FireCMSLogo } from "../components";
|
|
5
5
|
import {
|
|
6
6
|
Avatar,
|
|
7
7
|
cn,
|
|
@@ -18,7 +18,8 @@ import { useAuthController, useLargeLayout, useModeController, useNavigationCont
|
|
|
18
18
|
import { User } from "../types";
|
|
19
19
|
|
|
20
20
|
export type FireCMSAppBarProps<ADDITIONAL_PROPS = object> = {
|
|
21
|
-
|
|
21
|
+
|
|
22
|
+
title: React.ReactNode;
|
|
22
23
|
/**
|
|
23
24
|
* A component that gets rendered on the upper side of the main toolbar
|
|
24
25
|
*/
|
|
@@ -36,6 +37,8 @@ export type FireCMSAppBarProps<ADDITIONAL_PROPS = object> = {
|
|
|
36
37
|
|
|
37
38
|
style?: React.CSSProperties;
|
|
38
39
|
|
|
40
|
+
logo?: string;
|
|
41
|
+
|
|
39
42
|
user?: User;
|
|
40
43
|
} & ADDITIONAL_PROPS;
|
|
41
44
|
|
|
@@ -57,6 +60,7 @@ export const FireCMSAppBar = function FireCMSAppBar({
|
|
|
57
60
|
includeDrawer,
|
|
58
61
|
className,
|
|
59
62
|
style,
|
|
63
|
+
logo,
|
|
60
64
|
user: userProp
|
|
61
65
|
}: FireCMSAppBarProps) {
|
|
62
66
|
const navigation = useNavigationController();
|
|
@@ -102,7 +106,7 @@ export const FireCMSAppBar = function FireCMSAppBar({
|
|
|
102
106
|
"w-[calc(100%-64px)]": includeDrawer && !(drawerOpen && largeLayout),
|
|
103
107
|
"w-[calc(100%-17rem)]": includeDrawer && (drawerOpen && largeLayout),
|
|
104
108
|
"duration-150": drawerOpen && largeLayout,
|
|
105
|
-
fixed: true
|
|
109
|
+
fixed: true
|
|
106
110
|
},
|
|
107
111
|
className)}>
|
|
108
112
|
|
|
@@ -110,16 +114,27 @@ export const FireCMSAppBar = function FireCMSAppBar({
|
|
|
110
114
|
|
|
111
115
|
{startAdornment}
|
|
112
116
|
|
|
117
|
+
|
|
113
118
|
{navigation && <div className="mr-8 hidden lg:block">
|
|
114
119
|
<ReactLink
|
|
115
120
|
className="visited:text-inherit visited:dark:text-inherit"
|
|
116
121
|
to={navigation?.basePath ?? "/"}
|
|
117
122
|
>
|
|
118
|
-
<
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
+
<div className={"flex flex-row gap-4"}>
|
|
124
|
+
{!includeDrawer && (logo
|
|
125
|
+
? <img src={logo}
|
|
126
|
+
alt="Logo"
|
|
127
|
+
className={cn("w-[32px] h-[32px]")}/>
|
|
128
|
+
: <FireCMSLogo width={"32px"} height={"32px"}/>)}
|
|
129
|
+
|
|
130
|
+
{typeof title === "string"
|
|
131
|
+
? <Typography variant="subtitle1"
|
|
132
|
+
noWrap
|
|
133
|
+
className={"ml-2 !font-medium"}>
|
|
134
|
+
{title}
|
|
135
|
+
</Typography>
|
|
136
|
+
: title}
|
|
137
|
+
</div>
|
|
123
138
|
</ReactLink>
|
|
124
139
|
</div>}
|
|
125
140
|
|
|
@@ -291,6 +291,7 @@ export function ReferenceSelectionTable<M extends Record<string, any>>(
|
|
|
291
291
|
displayedColumnIds={displayedColumnIds}
|
|
292
292
|
onEntityClick={onEntityClick}
|
|
293
293
|
tableController={tableController}
|
|
294
|
+
enablePopupIcon={false}
|
|
294
295
|
tableRowActionsBuilder={tableRowActionsBuilder}
|
|
295
296
|
title={<Typography variant={"subtitle2"}>
|
|
296
297
|
{collection.singularName ? `Select ${collection.singularName}` : `Select from ${collection.name}`}
|
|
@@ -404,7 +404,7 @@ const SafeLinkRenderer: React.FC<{
|
|
|
404
404
|
const urlRegex = /https?:\/\/[^\s]+/g;
|
|
405
405
|
const htmlContent = text.replace(urlRegex, (url) => {
|
|
406
406
|
// For each URL found, replace it with an HTML <a> tag
|
|
407
|
-
return `<a href="${url}" target="_blank">Link</a><br/>`;
|
|
407
|
+
return `<a href="${url}" class="underline" target="_blank">Link</a><br/>`;
|
|
408
408
|
});
|
|
409
409
|
|
|
410
410
|
return (
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CollectionSize,
|
|
1
|
+
import { CollectionSize, FireCMSContext, ResolvedProperty, SelectedCellProps } from "../../types";
|
|
2
2
|
|
|
3
3
|
export type EntityCollectionTableController<M extends Record<string, any>> = {
|
|
4
4
|
|
|
@@ -31,14 +31,12 @@ export type EntityCollectionTableController<M extends Record<string, any>> = {
|
|
|
31
31
|
* Props passed in a callback when the content of a cell in a table has been edited
|
|
32
32
|
* @group Collection components
|
|
33
33
|
*/
|
|
34
|
-
export interface OnCellValueChangeParams<T = any,
|
|
34
|
+
export interface OnCellValueChangeParams<T = any, D = any> {
|
|
35
35
|
value: T,
|
|
36
36
|
propertyKey: string,
|
|
37
|
-
|
|
37
|
+
data?: D,
|
|
38
38
|
onValueUpdated: () => void
|
|
39
39
|
setError: (e: Error | undefined) => void
|
|
40
|
-
fullPath: string
|
|
41
|
-
context: FireCMSContext
|
|
42
40
|
}
|
|
43
41
|
|
|
44
42
|
/**
|
|
@@ -13,7 +13,7 @@ export type NavigationRoutesProps = {
|
|
|
13
13
|
/**
|
|
14
14
|
* In case you need to override the home page
|
|
15
15
|
*/
|
|
16
|
-
|
|
16
|
+
homePage?: React.ReactNode;
|
|
17
17
|
|
|
18
18
|
customRoutes?: React.ReactNode[]
|
|
19
19
|
|
|
@@ -28,10 +28,9 @@ export type NavigationRoutesProps = {
|
|
|
28
28
|
* @constructor
|
|
29
29
|
* @group Components
|
|
30
30
|
*/
|
|
31
|
-
|
|
32
31
|
export const NavigationRoutes = React.memo<NavigationRoutesProps>(
|
|
33
32
|
function NavigationRoutes({
|
|
34
|
-
|
|
33
|
+
homePage = <DefaultHomePage/>,
|
|
35
34
|
customRoutes
|
|
36
35
|
}: NavigationRoutesProps) {
|
|
37
36
|
|
|
@@ -93,7 +92,7 @@ export const NavigationRoutes = React.memo<NavigationRoutesProps>(
|
|
|
93
92
|
|
|
94
93
|
const homeRoute = (
|
|
95
94
|
<Route path={"/"}
|
|
96
|
-
element={
|
|
95
|
+
element={homePage}/>
|
|
97
96
|
);
|
|
98
97
|
|
|
99
98
|
const notFoundRoute = <Route path={"*"}
|
package/src/core/Scaffold.tsx
CHANGED
|
@@ -17,7 +17,7 @@ export interface ScaffoldProps<ExtraDrawerProps = object, ExtraAppbarProps = obj
|
|
|
17
17
|
/**
|
|
18
18
|
* Name of the app, displayed as the main title and in the tab title
|
|
19
19
|
*/
|
|
20
|
-
name:
|
|
20
|
+
name: React.ReactNode;
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Logo to be displayed in the drawer of the CMS
|
|
@@ -112,9 +112,10 @@ export const Scaffold = React.memo<PropsWithChildren<ScaffoldProps>>(
|
|
|
112
112
|
}}>
|
|
113
113
|
|
|
114
114
|
<FireCMSAppBar title={name}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
115
|
+
includeDrawer={includeDrawer}
|
|
116
|
+
logo={logo}
|
|
117
|
+
drawerOpen={computedDrawerOpen}
|
|
118
|
+
{...fireCMSAppBarProps}/>
|
|
118
119
|
|
|
119
120
|
<StyledDrawer
|
|
120
121
|
displayed={includeDrawer}
|
package/src/hooks/data/save.ts
CHANGED
|
@@ -17,7 +17,6 @@ import { resolveCollection } from "../../util";
|
|
|
17
17
|
export type SaveEntityWithCallbacksProps<M extends Record<string, any>> =
|
|
18
18
|
SaveEntityProps<M> &
|
|
19
19
|
{
|
|
20
|
-
callbacks?: EntityCallbacks<M>;
|
|
21
20
|
onSaveSuccess?: (updatedEntity: Entity<M>) => void,
|
|
22
21
|
onSaveFailure?: (e: Error) => void,
|
|
23
22
|
onPreSaveHookError?: (e: Error) => void,
|