@firecms/core 3.0.0-canary.7 → 3.0.0-canary.9
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/EntityCollectionTable/EntityCollectionRowActions.d.ts +1 -1
- package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +2 -2
- package/dist/components/EntityCollectionTable/PropertyTableCell.d.ts +2 -2
- package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +1 -2
- package/dist/components/EntityCollectionView/useSelectionController.d.ts +2 -0
- package/dist/components/EntityPreview.d.ts +25 -7
- package/dist/components/EntityView.d.ts +11 -0
- package/dist/components/FieldCaption.d.ts +5 -0
- package/dist/components/HomePage/NavigationCard.d.ts +8 -0
- package/dist/components/HomePage/{NavigationCollectionCard.d.ts → NavigationCardBinding.d.ts} +2 -2
- package/dist/components/HomePage/SmallNavigationCard.d.ts +6 -0
- package/dist/components/HomePage/index.d.ts +3 -1
- package/dist/components/VirtualTable/VirtualTableProps.d.ts +1 -1
- package/dist/components/index.d.ts +4 -2
- package/dist/core/{EntityView.d.ts → EntityEditView.d.ts} +2 -2
- package/dist/core/SideEntityView.d.ts +2 -2
- package/dist/form/EntityForm.d.ts +1 -1
- package/dist/form/components/StorageItemPreview.d.ts +3 -2
- package/dist/form/components/StorageUploadProgress.d.ts +1 -1
- package/dist/form/field_bindings/KeyValueFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +4 -3
- package/dist/form/field_bindings/TextFieldBinding.d.ts +2 -2
- package/dist/form/validation.d.ts +1 -1
- package/dist/hooks/data/useDataSource.d.ts +2 -2
- package/dist/hooks/useBuildNavigationController.d.ts +5 -2
- package/dist/hooks/useProjectLog.d.ts +5 -1
- package/dist/hooks/useStorageSource.d.ts +2 -2
- package/dist/index.es.js +8333 -8060
- 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/useRestoreScroll.d.ts +1 -1
- package/dist/preview/PropertyPreview.d.ts +1 -1
- package/dist/preview/components/BooleanPreview.d.ts +5 -1
- package/dist/preview/components/EnumValuesChip.d.ts +1 -1
- package/dist/preview/components/ReferencePreview.d.ts +1 -7
- package/dist/types/analytics.d.ts +1 -1
- package/dist/types/auth.d.ts +13 -1
- package/dist/types/collections.d.ts +14 -1
- package/dist/types/entity_overrides.d.ts +6 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/navigation.d.ts +10 -9
- package/dist/types/permissions.d.ts +5 -1
- package/dist/types/plugins.d.ts +15 -17
- package/dist/types/properties.d.ts +2 -2
- package/dist/types/property_config.d.ts +2 -2
- package/dist/types/roles.d.ts +31 -0
- package/dist/types/user.d.ts +5 -0
- package/dist/util/collections.d.ts +9 -1
- package/dist/util/icons.d.ts +8 -2
- package/dist/util/permissions.d.ts +4 -4
- package/dist/util/references.d.ts +4 -2
- package/dist/util/resolutions.d.ts +1 -1
- package/package.json +23 -23
- package/src/components/DeleteEntityDialog.tsx +4 -4
- package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +2 -2
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +273 -277
- package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +1 -1
- package/src/components/EntityCollectionTable/PropertyTableCell.tsx +12 -13
- package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +8 -15
- package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +3 -3
- package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +1 -1
- package/src/components/EntityCollectionTable/internal/default_entity_actions.tsx +9 -5
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +28 -49
- package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +5 -6
- package/src/components/EntityCollectionView/useSelectionController.tsx +30 -0
- package/src/components/EntityPreview.tsx +204 -70
- package/src/components/EntityView.tsx +84 -0
- package/src/components/FieldCaption.tsx +14 -0
- package/src/components/FireCMSAppBar.tsx +8 -0
- package/src/components/HomePage/DefaultHomePage.tsx +13 -9
- package/src/components/HomePage/NavigationCard.tsx +69 -0
- package/src/components/HomePage/NavigationCardBinding.tsx +116 -0
- package/src/components/HomePage/SmallNavigationCard.tsx +45 -0
- package/src/components/HomePage/index.tsx +3 -1
- package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +3 -4
- package/src/components/ReferenceWidget.tsx +3 -3
- package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +11 -19
- package/src/components/VirtualTable/VirtualTableProps.tsx +1 -1
- package/src/components/common/useDataSourceEntityCollectionTableController.tsx +1 -1
- package/src/components/index.tsx +4 -2
- package/src/core/Drawer.tsx +66 -39
- package/src/core/{EntityView.tsx → EntityEditView.tsx} +20 -37
- package/src/core/EntitySidePanel.tsx +2 -2
- package/src/core/FireCMS.tsx +18 -2
- package/src/core/NavigationRoutes.tsx +8 -0
- package/src/core/SideEntityView.tsx +2 -2
- package/src/form/EntityForm.tsx +19 -11
- package/src/form/components/StorageItemPreview.tsx +5 -3
- package/src/form/components/StorageUploadProgress.tsx +6 -5
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +8 -12
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +15 -15
- package/src/form/field_bindings/MapFieldBinding.tsx +15 -15
- package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +1 -1
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +1 -0
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +14 -5
- package/src/form/field_bindings/TextFieldBinding.tsx +7 -5
- package/src/form/validation.ts +3 -4
- package/src/hooks/data/useCollectionFetch.tsx +1 -1
- package/src/hooks/data/useDataSource.tsx +8 -3
- package/src/hooks/data/useEntityFetch.tsx +1 -1
- package/src/hooks/useBuildNavigationController.tsx +79 -38
- package/src/hooks/useProjectLog.tsx +11 -3
- package/src/hooks/useReferenceDialog.tsx +2 -2
- package/src/hooks/useStorageSource.tsx +7 -2
- package/src/preview/PropertyPreview.tsx +1 -1
- package/src/preview/components/BooleanPreview.tsx +16 -3
- package/src/preview/components/EnumValuesChip.tsx +1 -1
- package/src/preview/components/ReferencePreview.tsx +54 -146
- package/src/preview/property_previews/StringPropertyPreview.tsx +8 -7
- package/src/types/analytics.ts +1 -0
- package/src/types/auth.tsx +17 -1
- package/src/types/collections.ts +16 -1
- package/src/types/entity_actions.tsx +4 -0
- package/src/types/entity_overrides.tsx +7 -0
- package/src/types/firecms.tsx +0 -1
- package/src/types/index.ts +2 -0
- package/src/types/navigation.ts +11 -10
- package/src/types/permissions.ts +6 -1
- package/src/types/plugins.tsx +22 -25
- package/src/types/properties.ts +3 -2
- package/src/types/property_config.tsx +2 -2
- package/src/types/roles.ts +41 -0
- package/src/types/side_entity_controller.tsx +1 -0
- package/src/types/user.ts +7 -0
- package/src/util/collections.ts +22 -0
- package/src/util/icons.tsx +11 -3
- package/src/util/permissions.ts +11 -8
- package/src/util/references.ts +36 -5
- package/src/components/HomePage/NavigationCollectionCard.tsx +0 -146
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useCallback, useState } from "react";
|
|
2
2
|
import equal from "react-fast-compare"
|
|
3
3
|
|
|
4
|
-
import { ReferencePreview
|
|
4
|
+
import { ReferencePreview } from "../../../preview";
|
|
5
5
|
import { CollectionSize, Entity, EntityCollection, EntityReference, FilterValues } from "../../../types";
|
|
6
6
|
|
|
7
7
|
import { getPreviewSizeFrom } from "../../../preview/util";
|
|
@@ -9,6 +9,7 @@ import { getReferenceFrom } from "../../../util";
|
|
|
9
9
|
import { useCustomizationController, useNavigationController, useReferenceDialog } from "../../../hooks";
|
|
10
10
|
import { ErrorView } from "../../ErrorView";
|
|
11
11
|
import { Button } from "@firecms/ui";
|
|
12
|
+
import { EntityPreviewContainer } from "../../EntityPreview";
|
|
12
13
|
|
|
13
14
|
type TableReferenceFieldProps = {
|
|
14
15
|
name: string;
|
|
@@ -57,11 +58,6 @@ export const TableReferenceFieldSuccess = React.memo(
|
|
|
57
58
|
collection
|
|
58
59
|
} = props;
|
|
59
60
|
|
|
60
|
-
const [onHover, setOnHover] = useState(false);
|
|
61
|
-
|
|
62
|
-
const hoverTrue = useCallback(() => setOnHover(true), []);
|
|
63
|
-
const hoverFalse = useCallback(() => setOnHover(false), []);
|
|
64
|
-
|
|
65
61
|
const onSingleEntitySelected = useCallback((entity: Entity<any>) => {
|
|
66
62
|
updateValue(entity ? getReferenceFrom(entity) : null);
|
|
67
63
|
}, [updateValue]);
|
|
@@ -101,29 +97,29 @@ export const TableReferenceFieldSuccess = React.memo(
|
|
|
101
97
|
onClick={disabled ? undefined : handleOpen}
|
|
102
98
|
size={getPreviewSizeFrom(size)}
|
|
103
99
|
reference={internalValue as EntityReference}
|
|
104
|
-
|
|
100
|
+
hover={!disabled}
|
|
105
101
|
disabled={!path}
|
|
106
102
|
previewProperties={previewProperties}
|
|
107
103
|
/>;
|
|
108
104
|
else
|
|
109
|
-
return <
|
|
105
|
+
return <EntityPreviewContainer
|
|
110
106
|
onClick={disabled ? undefined : handleOpen}
|
|
111
107
|
size={getPreviewSizeFrom(size)}>
|
|
112
108
|
<ErrorView title="Value is not a reference." error={"Click to edit"}/>
|
|
113
|
-
</
|
|
109
|
+
</EntityPreviewContainer>;
|
|
114
110
|
};
|
|
115
111
|
|
|
116
112
|
const buildMultipleReferenceField = () => {
|
|
117
113
|
if (Array.isArray(internalValue))
|
|
118
114
|
return <>
|
|
119
115
|
{internalValue.map((reference, index) =>
|
|
120
|
-
<div className="
|
|
116
|
+
<div className="w-full my-0.5"
|
|
121
117
|
key={`preview_array_ref_${name}_${index}`}>
|
|
122
118
|
<ReferencePreview
|
|
123
119
|
onClick={disabled ? undefined : handleOpen}
|
|
124
120
|
size={"tiny"}
|
|
125
121
|
reference={reference}
|
|
126
|
-
|
|
122
|
+
hover={!disabled}
|
|
127
123
|
disabled={!path}
|
|
128
124
|
previewProperties={previewProperties}
|
|
129
125
|
/>
|
|
@@ -139,10 +135,7 @@ export const TableReferenceFieldSuccess = React.memo(
|
|
|
139
135
|
return <ErrorView error={"The specified collection does not exist"}/>;
|
|
140
136
|
|
|
141
137
|
return (
|
|
142
|
-
<div className="w-full"
|
|
143
|
-
onMouseEnter={hoverTrue}
|
|
144
|
-
onMouseMove={hoverTrue}
|
|
145
|
-
onMouseLeave={hoverFalse}>
|
|
138
|
+
<div className="w-full group">
|
|
146
139
|
|
|
147
140
|
{internalValue && !multiselect && buildSingleReferenceField()}
|
|
148
141
|
|
|
@@ -51,7 +51,7 @@ export function TableStorageUpload(props: {
|
|
|
51
51
|
entity,
|
|
52
52
|
path,
|
|
53
53
|
previewSize,
|
|
54
|
-
updateValue
|
|
54
|
+
updateValue,
|
|
55
55
|
} = props;
|
|
56
56
|
|
|
57
57
|
const storageSource = useStorageSource();
|
|
@@ -137,7 +137,7 @@ function StorageUpload({
|
|
|
137
137
|
storage,
|
|
138
138
|
onFilesAdded,
|
|
139
139
|
onFileUploadComplete,
|
|
140
|
-
storagePathBuilder
|
|
140
|
+
storagePathBuilder,
|
|
141
141
|
}: StorageUploadProps) {
|
|
142
142
|
|
|
143
143
|
const [onHover, setOnHover] = useState(false);
|
|
@@ -293,7 +293,7 @@ export function TableStorageItemPreview({
|
|
|
293
293
|
|
|
294
294
|
return (
|
|
295
295
|
<div
|
|
296
|
-
className={"relative
|
|
296
|
+
className={"relative p-2 max-w-full"}
|
|
297
297
|
>
|
|
298
298
|
|
|
299
299
|
{value &&
|
|
@@ -9,21 +9,23 @@ export const editEntityAction: EntityAction = {
|
|
|
9
9
|
onClick({
|
|
10
10
|
entity,
|
|
11
11
|
collection,
|
|
12
|
+
fullPath,
|
|
12
13
|
context,
|
|
13
14
|
highlightEntity,
|
|
14
|
-
unhighlightEntity
|
|
15
|
+
unhighlightEntity,
|
|
15
16
|
}): Promise<void> {
|
|
16
17
|
highlightEntity?.(entity);
|
|
17
18
|
context.analyticsController?.onAnalyticsEvent?.("entity_click", {
|
|
18
19
|
path: entity.path,
|
|
19
20
|
entityId: entity.id
|
|
20
21
|
});
|
|
22
|
+
const path = collection?.collectionGroup ? entity.path : (fullPath ?? entity.path);
|
|
21
23
|
context.sideEntityController.open({
|
|
22
24
|
entityId: entity.id,
|
|
23
|
-
path
|
|
25
|
+
path,
|
|
24
26
|
collection,
|
|
25
27
|
updateUrl: true,
|
|
26
|
-
onClose: () => unhighlightEntity?.(entity)
|
|
28
|
+
onClose: () => unhighlightEntity?.(entity),
|
|
27
29
|
});
|
|
28
30
|
return Promise.resolve(undefined);
|
|
29
31
|
}
|
|
@@ -37,7 +39,7 @@ export const copyEntityAction: EntityAction = {
|
|
|
37
39
|
collection,
|
|
38
40
|
context,
|
|
39
41
|
highlightEntity,
|
|
40
|
-
unhighlightEntity
|
|
42
|
+
unhighlightEntity,
|
|
41
43
|
}): Promise<void> {
|
|
42
44
|
highlightEntity?.(entity);
|
|
43
45
|
context.analyticsController?.onAnalyticsEvent?.("copy_entity_click", {
|
|
@@ -50,11 +52,12 @@ export const copyEntityAction: EntityAction = {
|
|
|
50
52
|
copy: true,
|
|
51
53
|
collection,
|
|
52
54
|
updateUrl: true,
|
|
53
|
-
onClose: () => unhighlightEntity?.(entity)
|
|
55
|
+
onClose: () => unhighlightEntity?.(entity),
|
|
54
56
|
});
|
|
55
57
|
return Promise.resolve(undefined);
|
|
56
58
|
}
|
|
57
59
|
}
|
|
60
|
+
|
|
58
61
|
export const archiveEntityAction: EntityAction = {
|
|
59
62
|
icon: <ArchiveIcon/>,
|
|
60
63
|
name: "Archive",
|
|
@@ -69,6 +72,7 @@ export const archiveEntityAction: EntityAction = {
|
|
|
69
72
|
return Promise.resolve(undefined);
|
|
70
73
|
}
|
|
71
74
|
}
|
|
75
|
+
|
|
72
76
|
export const openWebsiteAction: EntityAction = {
|
|
73
77
|
icon: <OpenInNewIcon/>,
|
|
74
78
|
name: "See in website",
|
|
@@ -12,8 +12,7 @@ import {
|
|
|
12
12
|
PartialEntityCollection,
|
|
13
13
|
PropertyOrBuilder,
|
|
14
14
|
ResolvedProperty,
|
|
15
|
-
SaveEntityProps
|
|
16
|
-
SelectionController
|
|
15
|
+
SaveEntityProps
|
|
17
16
|
} from "../../types";
|
|
18
17
|
import {
|
|
19
18
|
EntityCollectionRowActions,
|
|
@@ -25,7 +24,6 @@ import {
|
|
|
25
24
|
canCreateEntity,
|
|
26
25
|
canDeleteEntity,
|
|
27
26
|
canEditEntity,
|
|
28
|
-
fullPathToCollectionSegments,
|
|
29
27
|
getPropertyInPath,
|
|
30
28
|
mergeDeep,
|
|
31
29
|
resolveCollection,
|
|
@@ -74,6 +72,7 @@ import {
|
|
|
74
72
|
} from "../EntityCollectionTable/internal/default_entity_actions";
|
|
75
73
|
import { DeleteEntityDialog } from "../DeleteEntityDialog";
|
|
76
74
|
import { useAnalyticsController } from "../../hooks/useAnalyticsController";
|
|
75
|
+
import { useSelectionController } from "./useSelectionController";
|
|
77
76
|
|
|
78
77
|
const COLLECTION_GROUP_PARENT_ID = "collectionGroupParent";
|
|
79
78
|
|
|
@@ -121,7 +120,7 @@ export const EntityCollectionView = React.memo(
|
|
|
121
120
|
}: EntityCollectionViewProps<M>
|
|
122
121
|
) {
|
|
123
122
|
|
|
124
|
-
const dataSource = useDataSource();
|
|
123
|
+
const dataSource = useDataSource(collectionProp);
|
|
125
124
|
const navigation = useNavigationController();
|
|
126
125
|
const sideEntityController = useSideEntityController();
|
|
127
126
|
const authController = useAuthController();
|
|
@@ -129,6 +128,7 @@ export const EntityCollectionView = React.memo(
|
|
|
129
128
|
const analyticsController = useAnalyticsController();
|
|
130
129
|
const customizationController = useCustomizationController();
|
|
131
130
|
|
|
131
|
+
|
|
132
132
|
const containerRef = React.useRef<HTMLDivElement>(null);
|
|
133
133
|
|
|
134
134
|
const collection = useMemo(() => {
|
|
@@ -141,7 +141,7 @@ export const EntityCollectionView = React.memo(
|
|
|
141
141
|
collectionRef.current = collection;
|
|
142
142
|
}, [collection]);
|
|
143
143
|
|
|
144
|
-
const canCreateEntities = canCreateEntity(collection, authController,
|
|
144
|
+
const canCreateEntities = canCreateEntity(collection, authController, fullPath, null);
|
|
145
145
|
const [selectedNavigationEntity, setSelectedNavigationEntity] = useState<Entity<M> | undefined>(undefined);
|
|
146
146
|
const [deleteEntityClicked, setDeleteEntityClicked] = React.useState<Entity<M> | Entity<M>[] | undefined>(undefined);
|
|
147
147
|
|
|
@@ -160,7 +160,7 @@ export const EntityCollectionView = React.memo(
|
|
|
160
160
|
|
|
161
161
|
const checkInlineEditing = useCallback((entity?: Entity<any>): boolean => {
|
|
162
162
|
const collection = collectionRef.current;
|
|
163
|
-
if (!canEditEntity(collection, authController,
|
|
163
|
+
if (!canEditEntity(collection, authController, fullPath, entity ?? null)) {
|
|
164
164
|
return false;
|
|
165
165
|
}
|
|
166
166
|
return collection.inlineEditing === undefined || collection.inlineEditing;
|
|
@@ -199,6 +199,7 @@ export const EntityCollectionView = React.memo(
|
|
|
199
199
|
}, [tableController.setPopupCell]);
|
|
200
200
|
|
|
201
201
|
const onEntityClick = useCallback((clickedEntity: Entity<M>) => {
|
|
202
|
+
console.log("Entity clicked", clickedEntity)
|
|
202
203
|
const collection = collectionRef.current;
|
|
203
204
|
setSelectedNavigationEntity(clickedEntity);
|
|
204
205
|
analyticsController.onAnalyticsEvent?.("edit_entity_clicked", {
|
|
@@ -210,9 +211,9 @@ export const EntityCollectionView = React.memo(
|
|
|
210
211
|
path: clickedEntity.path,
|
|
211
212
|
collection,
|
|
212
213
|
updateUrl: true,
|
|
213
|
-
onClose: unselectNavigatedEntity
|
|
214
|
+
onClose: unselectNavigatedEntity,
|
|
214
215
|
});
|
|
215
|
-
}, [unselectNavigatedEntity]);
|
|
216
|
+
}, [unselectNavigatedEntity, sideEntityController]);
|
|
216
217
|
|
|
217
218
|
const onNewClick = useCallback(() => {
|
|
218
219
|
|
|
@@ -224,9 +225,9 @@ export const EntityCollectionView = React.memo(
|
|
|
224
225
|
path: fullPath,
|
|
225
226
|
collection,
|
|
226
227
|
updateUrl: true,
|
|
227
|
-
onClose: unselectNavigatedEntity
|
|
228
|
+
onClose: unselectNavigatedEntity,
|
|
228
229
|
});
|
|
229
|
-
}, [fullPath]);
|
|
230
|
+
}, [fullPath, sideEntityController]);
|
|
230
231
|
|
|
231
232
|
const onMultipleDeleteClick = () => {
|
|
232
233
|
analyticsController.onAnalyticsEvent?.("multiple_delete_dialog_open", {
|
|
@@ -288,7 +289,7 @@ export const EntityCollectionView = React.memo(
|
|
|
288
289
|
onCollectionModifiedForUser(fullPath, { defaultSize: size })
|
|
289
290
|
}, [onCollectionModifiedForUser, fullPath, userConfigPersistence]);
|
|
290
291
|
|
|
291
|
-
const createEnabled = canCreateEntity(collection, authController,
|
|
292
|
+
const createEnabled = canCreateEntity(collection, authController, fullPath, null);
|
|
292
293
|
|
|
293
294
|
const uniqueFieldValidator: UniqueFieldValidator = useCallback(
|
|
294
295
|
({
|
|
@@ -387,7 +388,7 @@ export const EntityCollectionView = React.memo(
|
|
|
387
388
|
entityId: entity.id,
|
|
388
389
|
selectedSubPath: subcollection.id ?? subcollection.path,
|
|
389
390
|
collection,
|
|
390
|
-
updateUrl: true
|
|
391
|
+
updateUrl: true,
|
|
391
392
|
});
|
|
392
393
|
}}>
|
|
393
394
|
{subcollection.name}
|
|
@@ -425,7 +426,7 @@ export const EntityCollectionView = React.memo(
|
|
|
425
426
|
...subcollectionColumns,
|
|
426
427
|
...collectionGroupParentCollections
|
|
427
428
|
];
|
|
428
|
-
}, [collection, fullPath]);
|
|
429
|
+
}, [collection, fullPath, sideEntityController]);
|
|
429
430
|
|
|
430
431
|
const updateLastDeleteTimestamp = useCallback(() => {
|
|
431
432
|
setLastDeleteTimestamp(Date.now());
|
|
@@ -433,11 +434,14 @@ export const EntityCollectionView = React.memo(
|
|
|
433
434
|
|
|
434
435
|
const largeLayout = useLargeLayout();
|
|
435
436
|
|
|
436
|
-
const getActionsForEntity = ({
|
|
437
|
+
const getActionsForEntity = ({
|
|
438
|
+
entity,
|
|
439
|
+
customEntityActions
|
|
440
|
+
}: {
|
|
437
441
|
entity?: Entity<M>,
|
|
438
442
|
customEntityActions?: EntityAction[]
|
|
439
443
|
}): EntityAction[] => {
|
|
440
|
-
const deleteEnabled = entity ? canDeleteEntity(collection, authController,
|
|
444
|
+
const deleteEnabled = entity ? canDeleteEntity(collection, authController, fullPath, entity) : true;
|
|
441
445
|
const actions: EntityAction[] = [editEntityAction];
|
|
442
446
|
if (createEnabled)
|
|
443
447
|
actions.push(copyEntityAction);
|
|
@@ -448,13 +452,13 @@ export const EntityCollectionView = React.memo(
|
|
|
448
452
|
return actions;
|
|
449
453
|
};
|
|
450
454
|
|
|
451
|
-
const getIdColumnWidth =
|
|
455
|
+
const getIdColumnWidth = () => {
|
|
452
456
|
const entityActions = getActionsForEntity({});
|
|
453
457
|
const collapsedActions = entityActions.filter(a => a.collapsed !== false);
|
|
454
458
|
const uncollapsedActions = entityActions.filter(a => a.collapsed === false);
|
|
455
459
|
const actionsWidth = uncollapsedActions.length * (largeLayout ? 40 : 30);
|
|
456
460
|
return (largeLayout ? (80 + actionsWidth) : (70 + actionsWidth)) + (collapsedActions.length > 0 ? (largeLayout ? 40 : 30) : 0);
|
|
457
|
-
}
|
|
461
|
+
};
|
|
458
462
|
|
|
459
463
|
const tableRowActionsBuilder = ({
|
|
460
464
|
entity,
|
|
@@ -470,7 +474,10 @@ export const EntityCollectionView = React.memo(
|
|
|
470
474
|
|
|
471
475
|
const isSelected = isEntitySelected(entity);
|
|
472
476
|
|
|
473
|
-
const actions = getActionsForEntity({
|
|
477
|
+
const actions = getActionsForEntity({
|
|
478
|
+
entity,
|
|
479
|
+
customEntityActions: collection.entityActions
|
|
480
|
+
});
|
|
474
481
|
|
|
475
482
|
return (
|
|
476
483
|
<EntityCollectionRowActions
|
|
@@ -577,7 +584,7 @@ export const EntityCollectionView = React.memo(
|
|
|
577
584
|
});
|
|
578
585
|
|
|
579
586
|
return (
|
|
580
|
-
<div className={cn("overflow-hidden h-full w-full", className)}
|
|
587
|
+
<div className={cn("overflow-hidden h-full w-full rounded-md", className)}
|
|
581
588
|
ref={containerRef}>
|
|
582
589
|
<EntityCollectionTable
|
|
583
590
|
key={`collection_table_${fullPath}`}
|
|
@@ -681,34 +688,6 @@ export const EntityCollectionView = React.memo(
|
|
|
681
688
|
equal(a.forceFilter, b.forceFilter);
|
|
682
689
|
}) as React.FunctionComponent<EntityCollectionViewProps<any>>
|
|
683
690
|
|
|
684
|
-
export function useSelectionController<M extends Record<string, any> = any>(
|
|
685
|
-
onSelectionChange?: (entity: Entity<M>, selected: boolean) => void
|
|
686
|
-
): SelectionController<M> {
|
|
687
|
-
|
|
688
|
-
const [selectedEntities, setSelectedEntities] = useState<Entity<M>[]>([]);
|
|
689
|
-
|
|
690
|
-
const toggleEntitySelection = useCallback((entity: Entity<M>) => {
|
|
691
|
-
let newValue;
|
|
692
|
-
if (selectedEntities.map(e => e.id).includes(entity.id)) {
|
|
693
|
-
onSelectionChange?.(entity, false);
|
|
694
|
-
newValue = selectedEntities.filter((item: Entity<M>) => item.id !== entity.id);
|
|
695
|
-
} else {
|
|
696
|
-
onSelectionChange?.(entity, true);
|
|
697
|
-
newValue = [...selectedEntities, entity];
|
|
698
|
-
}
|
|
699
|
-
setSelectedEntities(newValue);
|
|
700
|
-
}, [selectedEntities]);
|
|
701
|
-
|
|
702
|
-
const isEntitySelected = useCallback((entity: Entity<M>) => selectedEntities.map(e => e.id).includes(entity.id), [selectedEntities]);
|
|
703
|
-
|
|
704
|
-
return {
|
|
705
|
-
selectedEntities,
|
|
706
|
-
setSelectedEntities,
|
|
707
|
-
isEntitySelected,
|
|
708
|
-
toggleEntitySelection
|
|
709
|
-
};
|
|
710
|
-
}
|
|
711
|
-
|
|
712
691
|
function EntitiesCount({
|
|
713
692
|
fullPath,
|
|
714
693
|
collection,
|
|
@@ -723,7 +702,7 @@ function EntitiesCount({
|
|
|
723
702
|
onCountChange?: (count: number) => void,
|
|
724
703
|
}) {
|
|
725
704
|
|
|
726
|
-
const dataSource = useDataSource();
|
|
705
|
+
const dataSource = useDataSource(collection);
|
|
727
706
|
const navigation = useNavigationController();
|
|
728
707
|
const [count, setCount] = useState<number | undefined>(undefined);
|
|
729
708
|
const [error, setError] = useState<Error | undefined>(undefined);
|
|
@@ -799,7 +778,7 @@ function EntityIdHeaderWidget({
|
|
|
799
778
|
entityId: searchString,
|
|
800
779
|
path,
|
|
801
780
|
collection,
|
|
802
|
-
updateUrl: true
|
|
781
|
+
updateUrl: true,
|
|
803
782
|
});
|
|
804
783
|
}}
|
|
805
784
|
className={"text-gray-900 dark:text-white w-96 max-w-full"}>
|
|
@@ -44,7 +44,7 @@ export function EntityCollectionViewActions<M extends Record<string, any>>({
|
|
|
44
44
|
|
|
45
45
|
const selectedEntities = selectionController.selectedEntities;
|
|
46
46
|
|
|
47
|
-
const addButton = canCreateEntity(collection, authController,
|
|
47
|
+
const addButton = canCreateEntity(collection, authController, path, null) &&
|
|
48
48
|
onNewClick && (largeLayout
|
|
49
49
|
? <Button
|
|
50
50
|
id={`add_entity_${path}`}
|
|
@@ -57,14 +57,13 @@ export function EntityCollectionViewActions<M extends Record<string, any>>({
|
|
|
57
57
|
: <Button
|
|
58
58
|
id={`add_entity_${path}`}
|
|
59
59
|
onClick={onNewClick}
|
|
60
|
-
size="medium"
|
|
61
60
|
variant="filled"
|
|
62
61
|
color="primary"
|
|
63
62
|
>
|
|
64
63
|
<AddIcon/>
|
|
65
64
|
</Button>);
|
|
66
65
|
|
|
67
|
-
const multipleDeleteEnabled = canDeleteEntity(collection, authController,
|
|
66
|
+
const multipleDeleteEnabled = canDeleteEntity(collection, authController, path, null);
|
|
68
67
|
|
|
69
68
|
let multipleDeleteButton: React.ReactNode | undefined;
|
|
70
69
|
if (selectionEnabled) {
|
|
@@ -112,11 +111,11 @@ export function EntityCollectionViewActions<M extends Record<string, any>>({
|
|
|
112
111
|
|
|
113
112
|
if (plugins) {
|
|
114
113
|
plugins.forEach((plugin, i) => {
|
|
115
|
-
if (plugin.
|
|
116
|
-
actions.push(...toArray(plugin.
|
|
114
|
+
if (plugin.collectionView?.CollectionActions) {
|
|
115
|
+
actions.push(...toArray(plugin.collectionView?.CollectionActions)
|
|
117
116
|
.map((Action, j) => (
|
|
118
117
|
<ErrorBoundary key={`plugin_actions_${i}_${j}`}>
|
|
119
|
-
<Action {...actionProps} {...plugin.
|
|
118
|
+
<Action {...actionProps} {...plugin.collectionView?.collectionActionsProps}/>
|
|
120
119
|
</ErrorBoundary>
|
|
121
120
|
)));
|
|
122
121
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { useCallback, useState } from "react";
|
|
2
|
+
import { Entity, SelectionController } from "../../types";
|
|
3
|
+
|
|
4
|
+
export function useSelectionController<M extends Record<string, any> = any>(
|
|
5
|
+
onSelectionChange?: (entity: Entity<M>, selected: boolean) => void
|
|
6
|
+
): SelectionController<M> {
|
|
7
|
+
|
|
8
|
+
const [selectedEntities, setSelectedEntities] = useState<Entity<M>[]>([]);
|
|
9
|
+
|
|
10
|
+
const toggleEntitySelection = useCallback((entity: Entity<M>) => {
|
|
11
|
+
let newValue;
|
|
12
|
+
if (selectedEntities.map(e => e.id).includes(entity.id)) {
|
|
13
|
+
onSelectionChange?.(entity, false);
|
|
14
|
+
newValue = selectedEntities.filter((item: Entity<M>) => item.id !== entity.id);
|
|
15
|
+
} else {
|
|
16
|
+
onSelectionChange?.(entity, true);
|
|
17
|
+
newValue = [...selectedEntities, entity];
|
|
18
|
+
}
|
|
19
|
+
setSelectedEntities(newValue);
|
|
20
|
+
}, [selectedEntities]);
|
|
21
|
+
|
|
22
|
+
const isEntitySelected = useCallback((entity: Entity<M>) => selectedEntities.map(e => e.id).includes(entity.id), [selectedEntities]);
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
selectedEntities,
|
|
26
|
+
setSelectedEntities,
|
|
27
|
+
isEntitySelected,
|
|
28
|
+
toggleEntitySelection
|
|
29
|
+
};
|
|
30
|
+
}
|