@firecms/core 3.0.0-canary.169 → 3.0.0-canary.170
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/ArrayContainer.d.ts +7 -3
- package/dist/index.es.js +41 -34
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +41 -34
- package/dist/index.umd.js.map +1 -1
- package/dist/types/dialogs_controller.d.ts +7 -3
- package/package.json +5 -7
- package/src/components/ArrayContainer.tsx +47 -28
- package/src/contexts/DialogsProvider.tsx +3 -2
- package/src/core/DefaultDrawer.tsx +1 -1
- package/src/hooks/useBuildNavigationController.tsx +1 -0
- package/src/internal/useBuildSideDialogsController.tsx +0 -1
- package/src/types/dialogs_controller.tsx +7 -3
|
@@ -12,7 +12,7 @@ export interface DialogsController {
|
|
|
12
12
|
* Open a dialog
|
|
13
13
|
* @param props
|
|
14
14
|
*/
|
|
15
|
-
open: (props: DialogControllerEntryProps) => {
|
|
15
|
+
open: <T extends object = object>(props: DialogControllerEntryProps<T>) => {
|
|
16
16
|
closeDialog: () => void;
|
|
17
17
|
};
|
|
18
18
|
}
|
|
@@ -20,7 +20,7 @@ export interface DialogsController {
|
|
|
20
20
|
* Props used to open a side dialog
|
|
21
21
|
* @group Hooks and utilities
|
|
22
22
|
*/
|
|
23
|
-
export interface DialogControllerEntryProps {
|
|
23
|
+
export interface DialogControllerEntryProps<T extends object = object> {
|
|
24
24
|
key: string;
|
|
25
25
|
/**
|
|
26
26
|
* The component type that will be rendered
|
|
@@ -28,5 +28,9 @@ export interface DialogControllerEntryProps {
|
|
|
28
28
|
Component: React.ComponentType<{
|
|
29
29
|
open: boolean;
|
|
30
30
|
closeDialog: () => void;
|
|
31
|
-
}>;
|
|
31
|
+
} & T>;
|
|
32
|
+
/**
|
|
33
|
+
* Props to pass to the dialog component
|
|
34
|
+
*/
|
|
35
|
+
props?: T;
|
|
32
36
|
}
|
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.170",
|
|
5
5
|
"description": "Awesome Firebase/Firestore-based headless open-source CMS",
|
|
6
6
|
"funding": {
|
|
7
7
|
"url": "https://github.com/sponsors/firecmsco"
|
|
@@ -50,9 +50,9 @@
|
|
|
50
50
|
"./package.json": "./package.json"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@firecms/editor": "^3.0.0-canary.
|
|
54
|
-
"@firecms/formex": "^3.0.0-canary.
|
|
55
|
-
"@firecms/ui": "^3.0.0-canary.
|
|
53
|
+
"@firecms/editor": "^3.0.0-canary.170",
|
|
54
|
+
"@firecms/formex": "^3.0.0-canary.170",
|
|
55
|
+
"@firecms/ui": "^3.0.0-canary.170",
|
|
56
56
|
"@hello-pangea/dnd": "^17.0.0",
|
|
57
57
|
"@radix-ui/react-portal": "^1.1.2",
|
|
58
58
|
"clsx": "^2.1.1",
|
|
@@ -71,7 +71,6 @@
|
|
|
71
71
|
"yup": "^0.32.11"
|
|
72
72
|
},
|
|
73
73
|
"peerDependencies": {
|
|
74
|
-
"firebase": "^10.5.2",
|
|
75
74
|
"react": "^18.3.1",
|
|
76
75
|
"react-dom": "^18.3.1",
|
|
77
76
|
"react-router": "^6.28.0",
|
|
@@ -91,7 +90,6 @@
|
|
|
91
90
|
"babel-plugin-react-compiler": "beta",
|
|
92
91
|
"cross-env": "^7.0.3",
|
|
93
92
|
"eslint-plugin-react-compiler": "beta",
|
|
94
|
-
"firebase": "^10.14.1",
|
|
95
93
|
"jest": "^29.7.0",
|
|
96
94
|
"npm-run-all": "^4.1.5",
|
|
97
95
|
"react-router": "^6.28.0",
|
|
@@ -106,7 +104,7 @@
|
|
|
106
104
|
"dist",
|
|
107
105
|
"src"
|
|
108
106
|
],
|
|
109
|
-
"gitHead": "
|
|
107
|
+
"gitHead": "21c8b5f6236a1824f5896b69bb4810c05326c5c7",
|
|
110
108
|
"publishConfig": {
|
|
111
109
|
"access": "public"
|
|
112
110
|
},
|
|
@@ -41,6 +41,8 @@ export interface ArrayContainerProps<T> {
|
|
|
41
41
|
newDefaultEntry: T;
|
|
42
42
|
onValueChange: (value: T[]) => void,
|
|
43
43
|
className?: string;
|
|
44
|
+
min?: number;
|
|
45
|
+
max?: number;
|
|
44
46
|
}
|
|
45
47
|
|
|
46
48
|
const buildIdsMap = (value: any[]) =>
|
|
@@ -67,7 +69,9 @@ export function ArrayContainer<T>({
|
|
|
67
69
|
includeAddButton,
|
|
68
70
|
newDefaultEntry,
|
|
69
71
|
onValueChange,
|
|
70
|
-
className
|
|
72
|
+
className,
|
|
73
|
+
min = 0,
|
|
74
|
+
max = Infinity
|
|
71
75
|
}: ArrayContainerProps<T>) {
|
|
72
76
|
|
|
73
77
|
const hasValue = value && Array.isArray(value) && value.length > 0;
|
|
@@ -78,7 +82,8 @@ export function ArrayContainer<T>({
|
|
|
78
82
|
const [internalIds, setInternalIds] = useState<number[]>(
|
|
79
83
|
hasValue
|
|
80
84
|
? Object.values(internalIdsRef.current)
|
|
81
|
-
: []
|
|
85
|
+
: []
|
|
86
|
+
);
|
|
82
87
|
|
|
83
88
|
const itemCustomPropsRef = useRef<Record<number, object>>({});
|
|
84
89
|
|
|
@@ -104,7 +109,7 @@ export function ArrayContainer<T>({
|
|
|
104
109
|
|
|
105
110
|
const insertInEnd = (e: React.SyntheticEvent) => {
|
|
106
111
|
e.preventDefault();
|
|
107
|
-
if (disabled) return;
|
|
112
|
+
if (disabled || value.length >= max) return;
|
|
108
113
|
const id = getRandomId();
|
|
109
114
|
const newIds: number[] = [...internalIds, id];
|
|
110
115
|
if (onInternalIdAdded)
|
|
@@ -114,6 +119,7 @@ export function ArrayContainer<T>({
|
|
|
114
119
|
};
|
|
115
120
|
|
|
116
121
|
const remove = (index: number) => {
|
|
122
|
+
if (value.length <= min) return;
|
|
117
123
|
const newIds = [...internalIds];
|
|
118
124
|
newIds.splice(index, 1);
|
|
119
125
|
setInternalIds(newIds);
|
|
@@ -121,12 +127,14 @@ export function ArrayContainer<T>({
|
|
|
121
127
|
};
|
|
122
128
|
|
|
123
129
|
const copy = (index: number) => {
|
|
130
|
+
if (value.length >= max) return;
|
|
124
131
|
const id = getRandomId();
|
|
125
132
|
const copyingItem = value[index];
|
|
126
133
|
const newIds: number[] = [
|
|
127
|
-
...internalIds.
|
|
134
|
+
...internalIds.slice(0, index + 1),
|
|
128
135
|
id,
|
|
129
|
-
...internalIds.
|
|
136
|
+
...internalIds.slice(index + 1)
|
|
137
|
+
];
|
|
130
138
|
if (onInternalIdAdded)
|
|
131
139
|
onInternalIdAdded(id);
|
|
132
140
|
setInternalIds(newIds);
|
|
@@ -135,11 +143,13 @@ export function ArrayContainer<T>({
|
|
|
135
143
|
};
|
|
136
144
|
|
|
137
145
|
const addInIndex = (index: number) => {
|
|
146
|
+
if (value.length >= max) return;
|
|
138
147
|
const id = getRandomId();
|
|
139
148
|
const newIds: number[] = [
|
|
140
|
-
...internalIds.
|
|
149
|
+
...internalIds.slice(0, index),
|
|
141
150
|
id,
|
|
142
|
-
...internalIds.slice(index)
|
|
151
|
+
...internalIds.slice(index)
|
|
152
|
+
];
|
|
143
153
|
if (onInternalIdAdded)
|
|
144
154
|
onInternalIdAdded(id);
|
|
145
155
|
setInternalIds(newIds);
|
|
@@ -183,6 +193,7 @@ export function ArrayContainer<T>({
|
|
|
183
193
|
storedProps={itemCustomPropsRef.current[internalId]}
|
|
184
194
|
updateItemCustomProps={updateItemCustomProps}
|
|
185
195
|
addInIndex={addInIndex}
|
|
196
|
+
includeAddButton={includeAddButton}
|
|
186
197
|
/>
|
|
187
198
|
);
|
|
188
199
|
}}
|
|
@@ -213,6 +224,7 @@ export function ArrayContainer<T>({
|
|
|
213
224
|
storedProps={itemCustomPropsRef.current[internalId]}
|
|
214
225
|
updateItemCustomProps={updateItemCustomProps}
|
|
215
226
|
addInIndex={addInIndex}
|
|
227
|
+
includeAddButton={includeAddButton}
|
|
216
228
|
/>
|
|
217
229
|
)}
|
|
218
230
|
</Draggable>
|
|
@@ -221,17 +233,19 @@ export function ArrayContainer<T>({
|
|
|
221
233
|
|
|
222
234
|
{droppableProvided.placeholder}
|
|
223
235
|
|
|
224
|
-
{includeAddButton &&
|
|
225
|
-
<
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
236
|
+
{includeAddButton && (
|
|
237
|
+
<div className="my-4 justify-center text-left">
|
|
238
|
+
<Button
|
|
239
|
+
variant={"text"}
|
|
240
|
+
size={size === "small" ? "small" : "medium"}
|
|
241
|
+
color="primary"
|
|
242
|
+
disabled={disabled || value.length >= max}
|
|
243
|
+
startIcon={<AddIcon/>}
|
|
244
|
+
onClick={insertInEnd}>
|
|
245
|
+
{addLabel ?? "Add"}
|
|
246
|
+
</Button>
|
|
247
|
+
</div>
|
|
248
|
+
)}
|
|
235
249
|
</div>
|
|
236
250
|
)}
|
|
237
251
|
</Droppable>
|
|
@@ -249,6 +263,7 @@ type ArrayContainerItemProps = {
|
|
|
249
263
|
remove: (index: number) => void,
|
|
250
264
|
copy: (index: number) => void,
|
|
251
265
|
addInIndex?: (index: number) => void,
|
|
266
|
+
includeAddButton?: boolean,
|
|
252
267
|
isDragging: boolean,
|
|
253
268
|
storedProps?: object,
|
|
254
269
|
updateItemCustomProps: (internalId: number, props: object) => void
|
|
@@ -263,6 +278,7 @@ export function ArrayContainerItem({
|
|
|
263
278
|
buildEntry,
|
|
264
279
|
remove,
|
|
265
280
|
addInIndex,
|
|
281
|
+
includeAddButton,
|
|
266
282
|
copy,
|
|
267
283
|
isDragging,
|
|
268
284
|
storedProps,
|
|
@@ -295,6 +311,7 @@ export function ArrayContainerItem({
|
|
|
295
311
|
index={index}
|
|
296
312
|
provided={provided}
|
|
297
313
|
addInIndex={addInIndex}
|
|
314
|
+
includeAddButton={includeAddButton}
|
|
298
315
|
copy={copy}/>
|
|
299
316
|
</div>
|
|
300
317
|
</div>;
|
|
@@ -307,6 +324,7 @@ export function ArrayItemOptions({
|
|
|
307
324
|
index,
|
|
308
325
|
provided,
|
|
309
326
|
copy,
|
|
327
|
+
includeAddButton,
|
|
310
328
|
addInIndex
|
|
311
329
|
}: {
|
|
312
330
|
direction?: "row" | "column",
|
|
@@ -315,6 +333,7 @@ export function ArrayItemOptions({
|
|
|
315
333
|
index: number,
|
|
316
334
|
provided: any,
|
|
317
335
|
copy: (index: number) => void,
|
|
336
|
+
includeAddButton?: boolean,
|
|
318
337
|
addInIndex?: (index: number) => void
|
|
319
338
|
}) {
|
|
320
339
|
|
|
@@ -365,20 +384,20 @@ export function ArrayItemOptions({
|
|
|
365
384
|
Copy
|
|
366
385
|
</MenuItem>
|
|
367
386
|
|
|
368
|
-
{addInIndex && <MenuItem dense
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
387
|
+
{includeAddButton && addInIndex && <MenuItem dense
|
|
388
|
+
onClick={() => {
|
|
389
|
+
setMenuOpen(false);
|
|
390
|
+
addInIndex(index);
|
|
391
|
+
}}>
|
|
373
392
|
<KeyboardArrowUpIcon size={"small"}/>
|
|
374
393
|
Add on top
|
|
375
394
|
</MenuItem>}
|
|
376
395
|
|
|
377
|
-
{addInIndex && <MenuItem dense
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
396
|
+
{includeAddButton && addInIndex && <MenuItem dense
|
|
397
|
+
onClick={() => {
|
|
398
|
+
setMenuOpen(false);
|
|
399
|
+
addInIndex(index + 1);
|
|
400
|
+
}}>
|
|
382
401
|
<KeyboardArrowDownIcon size={"small"}/>
|
|
383
402
|
Add below
|
|
384
403
|
</MenuItem>}
|
|
@@ -8,7 +8,7 @@ export const DialogsProvider: React.FC<PropsWithChildren<{}>> = ({ children }) =
|
|
|
8
8
|
const [dialogEntries, setDialogEntries] = useState<DialogControllerEntryProps[]>([]);
|
|
9
9
|
const dialogEntriesRef = useRef<DialogControllerEntryProps[]>(dialogEntries);
|
|
10
10
|
|
|
11
|
-
const updateDialogEntries = (newPanels: DialogControllerEntryProps[]) => {
|
|
11
|
+
const updateDialogEntries = (newPanels: DialogControllerEntryProps<any>[]) => {
|
|
12
12
|
dialogEntriesRef.current = newPanels;
|
|
13
13
|
setDialogEntries(newPanels);
|
|
14
14
|
};
|
|
@@ -23,7 +23,7 @@ export const DialogsProvider: React.FC<PropsWithChildren<{}>> = ({ children }) =
|
|
|
23
23
|
|
|
24
24
|
}, [dialogEntries]);
|
|
25
25
|
|
|
26
|
-
const open = useCallback((dialogEntry: DialogControllerEntryProps) => {
|
|
26
|
+
const open = useCallback(<T extends object = object>(dialogEntry: DialogControllerEntryProps<T>) => {
|
|
27
27
|
|
|
28
28
|
const updatedPanels = [...dialogEntriesRef.current, dialogEntry];
|
|
29
29
|
updateDialogEntries(updatedPanels);
|
|
@@ -46,6 +46,7 @@ export const DialogsProvider: React.FC<PropsWithChildren<{}>> = ({ children }) =
|
|
|
46
46
|
key={`dialog_${i}`}
|
|
47
47
|
open={true}
|
|
48
48
|
closeDialog={close}
|
|
49
|
+
{...entry.props}
|
|
49
50
|
/>)}
|
|
50
51
|
</DialogsControllerContext.Provider>
|
|
51
52
|
);
|
|
@@ -175,7 +175,7 @@ export function DrawerLogo({ logo }: {
|
|
|
175
175
|
{logo
|
|
176
176
|
? <img src={logo}
|
|
177
177
|
alt="Logo"
|
|
178
|
-
className={cls("max-w-full max-h-full transition-all",
|
|
178
|
+
className={cls("max-w-full max-h-full transition-all object-contain",
|
|
179
179
|
drawerOpen ? "w-[96px] h-[96px]" : "w-[32px] h-[32px]")}/>
|
|
180
180
|
: <FireCMSLogo/>}
|
|
181
181
|
|
|
@@ -414,6 +414,7 @@ function encodePath(input: string) {
|
|
|
414
414
|
|
|
415
415
|
function filterOutNotAllowedCollections(resolvedCollections: EntityCollection[], authController: AuthController<User>): EntityCollection[] {
|
|
416
416
|
return resolvedCollections
|
|
417
|
+
.filter((c) => Boolean(c.path))
|
|
417
418
|
.filter((c) => {
|
|
418
419
|
if (!c.permissions) return true;
|
|
419
420
|
const resolvedPermissions = resolvePermissions(c, authController, c.path, null);
|
|
@@ -90,7 +90,6 @@ export function useBuildSideDialogsController(): SideDialogsController {
|
|
|
90
90
|
|
|
91
91
|
const replace = useCallback((panelProps: SideDialogPanelProps | SideDialogPanelProps[]) => {
|
|
92
92
|
|
|
93
|
-
console.log("replace", panelProps);
|
|
94
93
|
const newPanels: SideDialogPanelProps[] = Array.isArray(panelProps) ? panelProps : [panelProps];
|
|
95
94
|
newPanels.forEach((panel) => {
|
|
96
95
|
routesStore.current[panel.key] = panel;
|
|
@@ -15,19 +15,23 @@ export interface DialogsController {
|
|
|
15
15
|
* Open a dialog
|
|
16
16
|
* @param props
|
|
17
17
|
*/
|
|
18
|
-
open: (props: DialogControllerEntryProps) => { closeDialog: () => void };
|
|
18
|
+
open: <T extends object = object>(props: DialogControllerEntryProps<T>) => { closeDialog: () => void };
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* Props used to open a side dialog
|
|
23
23
|
* @group Hooks and utilities
|
|
24
24
|
*/
|
|
25
|
-
export interface DialogControllerEntryProps {
|
|
25
|
+
export interface DialogControllerEntryProps<T extends object = object> {
|
|
26
26
|
|
|
27
27
|
key: string;
|
|
28
28
|
/**
|
|
29
29
|
* The component type that will be rendered
|
|
30
30
|
*/
|
|
31
|
-
Component: React.ComponentType<{ open: boolean, closeDialog: () => void }>;
|
|
31
|
+
Component: React.ComponentType<{ open: boolean, closeDialog: () => void } & T>;
|
|
32
|
+
/**
|
|
33
|
+
* Props to pass to the dialog component
|
|
34
|
+
*/
|
|
35
|
+
props?: T;
|
|
32
36
|
|
|
33
37
|
}
|