@firecms/core 3.0.0-alpha.27 → 3.0.0-alpha.29
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/Popover.d.ts +3 -1
- package/dist/core/FireCMS.d.ts +2 -2
- package/dist/core/builders.d.ts +5 -5
- package/dist/core/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +4 -2
- package/dist/core/components/EntityCollectionTable/filters/ReferenceFilterField.d.ts +3 -3
- package/dist/core/components/EntityCollectionTable/internal/EntityCollectionRowActions.d.ts +15 -11
- package/dist/core/components/EntityCollectionTable/internal/default_entity_actions.d.ts +5 -0
- package/dist/core/components/EntityCollectionTable/types.d.ts +1 -37
- package/dist/core/components/FieldConfigBadge.d.ts +3 -3
- package/dist/core/components/VirtualTable/VirtualTableHeader.d.ts +2 -2
- package/dist/core/components/VirtualTable/VirtualTableProps.d.ts +1 -1
- package/dist/core/contexts/DialogsProvider.d.ts +4 -0
- package/dist/core/form_field_configs.d.ts +3 -3
- package/dist/core/index.d.ts +1 -1
- package/dist/core/internal/useBuildNavigationContext.d.ts +3 -3
- package/dist/core/util/property_utils.d.ts +5 -5
- package/dist/core/util/references.d.ts +2 -2
- package/dist/core/util/resolutions.d.ts +6 -6
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/useBuildDataSource.d.ts +23 -0
- package/dist/hooks/useDialogsController.d.ts +11 -0
- package/dist/index.es.js +8996 -8583
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +67 -67
- package/dist/index.umd.js.map +1 -1
- package/dist/styles.d.ts +1 -1
- package/dist/types/collections.d.ts +36 -13
- package/dist/types/datasource.d.ts +120 -11
- package/dist/types/dialogs_controller.d.ts +30 -0
- package/dist/types/entity_actions.d.ts +33 -0
- package/dist/types/fields.d.ts +1 -1
- package/dist/types/firecms.d.ts +8 -8
- package/dist/types/firecms_context.d.ts +10 -3
- package/dist/types/index.d.ts +2 -1
- package/dist/types/navigation.d.ts +3 -3
- package/dist/types/plugins.d.ts +11 -10
- package/dist/types/properties.d.ts +1 -1
- package/dist/types/{field_config.d.ts → property_config.d.ts} +3 -4
- package/package.json +3 -3
- package/src/components/Popover.tsx +10 -3
- package/src/components/Sheet.tsx +1 -0
- package/src/components/TextareaAutosize.tsx +2 -1
- package/src/core/FireCMS.tsx +9 -6
- package/src/core/builders.ts +11 -11
- package/src/core/components/ArrayContainer.tsx +1 -1
- package/src/core/components/EntityCollectionTable/EntityCollectionTable.tsx +20 -13
- package/src/core/components/EntityCollectionTable/EntityCollectionTableProps.tsx +5 -2
- package/src/core/components/EntityCollectionTable/filters/ReferenceFilterField.tsx +11 -6
- package/src/core/components/EntityCollectionTable/internal/EntityCollectionRowActions.tsx +96 -79
- package/src/core/components/EntityCollectionTable/internal/PropertyTableCell.tsx +2 -2
- package/src/core/components/EntityCollectionTable/internal/default_entity_actions.tsx +107 -0
- package/src/core/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +6 -2
- package/src/core/components/EntityCollectionTable/types.tsx +1 -56
- package/src/core/components/EntityCollectionView/EntityCollectionView.tsx +67 -43
- package/src/core/components/FieldConfigBadge.tsx +4 -4
- package/src/core/components/ReferenceSelectionInner.tsx +2 -2
- package/src/core/components/VirtualTable/VirtualTable.tsx +4 -6
- package/src/core/components/VirtualTable/VirtualTableHeader.tsx +21 -18
- package/src/core/components/VirtualTable/VirtualTableProps.tsx +1 -1
- package/src/core/contexts/DialogsProvider.tsx +50 -0
- package/src/core/form_field_configs.tsx +5 -5
- package/src/core/index.tsx +1 -1
- package/src/core/internal/useBuildNavigationContext.tsx +13 -13
- package/src/core/internal/useBuildSideEntityController.tsx +9 -1
- package/src/core/util/property_utils.tsx +5 -5
- package/src/core/util/references.ts +2 -2
- package/src/core/util/resolutions.ts +16 -11
- package/src/form/EntityForm.tsx +64 -7
- package/src/form/PropertyFieldBinding.tsx +4 -4
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +1 -1
- package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +4 -6
- package/src/hooks/index.tsx +1 -0
- package/src/hooks/useBuildDataSource.ts +351 -0
- package/src/hooks/useDialogsController.tsx +14 -0
- package/src/hooks/useFireCMSContext.tsx +5 -11
- package/src/preview/property_previews/StringPropertyPreview.tsx +4 -2
- package/src/styles.ts +1 -1
- package/src/types/collections.ts +36 -17
- package/src/types/datasource.ts +174 -10
- package/src/types/dialogs_controller.tsx +31 -0
- package/src/types/entity_actions.tsx +36 -0
- package/src/types/fields.tsx +1 -1
- package/src/types/firecms.tsx +8 -8
- package/src/types/firecms_context.tsx +11 -3
- package/src/types/index.ts +2 -1
- package/src/types/navigation.ts +3 -3
- package/src/types/plugins.tsx +11 -10
- package/src/types/properties.ts +1 -1
- package/src/types/{field_config.tsx → property_config.tsx} +3 -4
- /package/dist/core/contexts/{SnackbarContext.d.ts → SnackbarProvider.d.ts} +0 -0
- /package/src/core/contexts/{SnackbarContext.tsx → SnackbarProvider.tsx} +0 -0
|
@@ -55,6 +55,7 @@ export const TextareaAutosize = React.forwardRef(function TextareaAutosize(
|
|
|
55
55
|
onFocus,
|
|
56
56
|
onBlur,
|
|
57
57
|
sizeRef,
|
|
58
|
+
ignoreBoxSizing,
|
|
58
59
|
...other
|
|
59
60
|
} = props;
|
|
60
61
|
|
|
@@ -124,7 +125,7 @@ export const TextareaAutosize = React.forwardRef(function TextareaAutosize(
|
|
|
124
125
|
outerHeight = Math.max(outerHeight, singleRowHeight, minHeight);
|
|
125
126
|
|
|
126
127
|
// Take the box sizing into account for applying this value as a style.
|
|
127
|
-
const outerHeightStyle = outerHeight + (!
|
|
128
|
+
const outerHeightStyle = outerHeight + (!ignoreBoxSizing && boxSizing === "border-box" ? padding + border : 0);
|
|
128
129
|
|
|
129
130
|
const overflow = Math.abs(outerHeight - innerHeight) <= 1;
|
|
130
131
|
|
package/src/core/FireCMS.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useMemo } from "react";
|
|
2
2
|
|
|
3
|
-
import { FireCMSContext, FireCMSPlugin, FireCMSProps, User } from "../types";
|
|
3
|
+
import { EntityCollection, FireCMSContext, FireCMSPlugin, FireCMSProps, User } from "../types";
|
|
4
4
|
import { BreadcrumbsProvider } from "./contexts/BreacrumbsContext";
|
|
5
5
|
import { ModeControllerContext } from "./contexts/ModeController";
|
|
6
6
|
import { useBuildSideEntityController } from "./internal/useBuildSideEntityController";
|
|
@@ -17,6 +17,7 @@ import { AuthControllerContext } from "./contexts/AuthControllerContext";
|
|
|
17
17
|
import { SideDialogsControllerContext } from "./contexts/SideDialogsControllerContext";
|
|
18
18
|
import { useLocaleConfig } from "./internal/useLocaleConfig";
|
|
19
19
|
import { CenteredView } from "../components";
|
|
20
|
+
import { DialogsProvider } from "./contexts/DialogsProvider";
|
|
20
21
|
|
|
21
22
|
const DEFAULT_BASE_PATH = "/";
|
|
22
23
|
const DEFAULT_COLLECTION_PATH = "/c";
|
|
@@ -34,7 +35,7 @@ const DEFAULT_COLLECTION_PATH = "/c";
|
|
|
34
35
|
* @constructor
|
|
35
36
|
* @category Core
|
|
36
37
|
*/
|
|
37
|
-
export function FireCMS<UserType extends User>(props: FireCMSProps<UserType>) {
|
|
38
|
+
export function FireCMS<UserType extends User, EC extends EntityCollection>(props: FireCMSProps<UserType, EC>) {
|
|
38
39
|
|
|
39
40
|
const modeController = useModeController();
|
|
40
41
|
const {
|
|
@@ -124,10 +125,12 @@ export function FireCMS<UserType extends User>(props: FireCMSProps<UserType>) {
|
|
|
124
125
|
<NavigationContextInstance.Provider
|
|
125
126
|
value={navigation}>
|
|
126
127
|
<BreadcrumbsProvider>
|
|
127
|
-
<
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
128
|
+
<DialogsProvider>
|
|
129
|
+
<FireCMSInternal
|
|
130
|
+
loading={loading}>
|
|
131
|
+
{children}
|
|
132
|
+
</FireCMSInternal>
|
|
133
|
+
</DialogsProvider>
|
|
131
134
|
</BreadcrumbsProvider>
|
|
132
135
|
</NavigationContextInstance.Provider>
|
|
133
136
|
</SideEntityControllerContext.Provider>
|
package/src/core/builders.ts
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
EntityCollection,
|
|
9
9
|
EnumValueConfig,
|
|
10
10
|
EnumValues,
|
|
11
|
-
|
|
11
|
+
PropertyConfig,
|
|
12
12
|
GeopointProperty,
|
|
13
13
|
MapProperty,
|
|
14
14
|
NumberProperty,
|
|
@@ -27,10 +27,10 @@ import {
|
|
|
27
27
|
* @category Builder
|
|
28
28
|
*/
|
|
29
29
|
export function buildCollection<M extends Record<string, any> = any,
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
UserType extends User = User>(
|
|
32
|
-
collection: EntityCollection<M,
|
|
33
|
-
): EntityCollection<M,
|
|
32
|
+
collection: EntityCollection<M, UserType>
|
|
33
|
+
): EntityCollection<M, UserType> {
|
|
34
34
|
return collection;
|
|
35
35
|
}
|
|
36
36
|
|
|
@@ -121,20 +121,20 @@ export function buildEntityCallbacks<M extends Record<string, any> = any>(
|
|
|
121
121
|
* @param additionalFieldDelegate
|
|
122
122
|
* @category Builder
|
|
123
123
|
*/
|
|
124
|
-
export function buildAdditionalFieldDelegate<M extends Record<string, any>,
|
|
125
|
-
additionalFieldDelegate: AdditionalFieldDelegate<M,
|
|
126
|
-
): AdditionalFieldDelegate<M,
|
|
124
|
+
export function buildAdditionalFieldDelegate<M extends Record<string, any>, UserType extends User = User>(
|
|
125
|
+
additionalFieldDelegate: AdditionalFieldDelegate<M, UserType>
|
|
126
|
+
): AdditionalFieldDelegate<M, UserType> {
|
|
127
127
|
return additionalFieldDelegate;
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
/**
|
|
131
131
|
* Identity function we use to defeat the type system of Typescript and build
|
|
132
132
|
* additional field delegates views with all its properties
|
|
133
|
-
* @param
|
|
133
|
+
* @param propertyConfig
|
|
134
134
|
* @category Builder
|
|
135
135
|
*/
|
|
136
136
|
export function buildFieldConfig<T extends CMSType = CMSType>(
|
|
137
|
-
|
|
138
|
-
):
|
|
139
|
-
return
|
|
137
|
+
propertyConfig: PropertyConfig<T>
|
|
138
|
+
): PropertyConfig<T> {
|
|
139
|
+
return propertyConfig;
|
|
140
140
|
}
|
|
@@ -175,7 +175,7 @@ export function ArrayContainer<T>({
|
|
|
175
175
|
|
|
176
176
|
{droppableProvided.placeholder}
|
|
177
177
|
|
|
178
|
-
{includeAddButton && <div className="
|
|
178
|
+
{includeAddButton && <div className="py-4 justify-center text-left">
|
|
179
179
|
<Button
|
|
180
180
|
variant={size === "small" ? "text" : "outlined"}
|
|
181
181
|
size={size === "small" ? "small" : "medium"}
|
|
@@ -63,7 +63,7 @@ export const useEntityCollectionTableController = () => useContext<EntityCollect
|
|
|
63
63
|
* @category Components
|
|
64
64
|
*/
|
|
65
65
|
export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>(
|
|
66
|
-
function EntityCollectionTable<M extends Record<string, any>,
|
|
66
|
+
function EntityCollectionTable<M extends Record<string, any>, UserType extends User>
|
|
67
67
|
({
|
|
68
68
|
forceFilter,
|
|
69
69
|
actionsStart,
|
|
@@ -110,7 +110,9 @@ export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>
|
|
|
110
110
|
endAdornment,
|
|
111
111
|
AddColumnComponent,
|
|
112
112
|
AdditionalHeaderWidget,
|
|
113
|
-
additionalIDHeaderWidget
|
|
113
|
+
additionalIDHeaderWidget,
|
|
114
|
+
emptyComponent,
|
|
115
|
+
getIdColumnWidth
|
|
114
116
|
}: EntityCollectionTableProps<M>) {
|
|
115
117
|
|
|
116
118
|
const largeLayout = useLargeLayout();
|
|
@@ -154,12 +156,12 @@ export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>
|
|
|
154
156
|
|
|
155
157
|
const onTextSearch = useCallback((newSearchString?: string) => setSearchString?.(newSearchString), []);
|
|
156
158
|
|
|
157
|
-
const additionalFieldsMap: Record<string, AdditionalFieldDelegate<M,
|
|
159
|
+
const additionalFieldsMap: Record<string, AdditionalFieldDelegate<M, UserType>> = useMemo(() => {
|
|
158
160
|
return (additionalFields
|
|
159
161
|
? additionalFields
|
|
160
|
-
.map((aC) => ({ [aC.id]: aC as AdditionalFieldDelegate<M,
|
|
162
|
+
.map((aC) => ({ [aC.id]: aC as AdditionalFieldDelegate<M, any> }))
|
|
161
163
|
.reduce((a, b) => ({ ...a, ...b }), {})
|
|
162
|
-
: {}) as Record<string, AdditionalFieldDelegate<M,
|
|
164
|
+
: {}) as Record<string, AdditionalFieldDelegate<M, UserType>>;
|
|
163
165
|
}, [additionalFields]);
|
|
164
166
|
|
|
165
167
|
// on ESC key press
|
|
@@ -198,7 +200,11 @@ export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>
|
|
|
198
200
|
|
|
199
201
|
let disabled = column.custom?.disabled;
|
|
200
202
|
const propertyValue = entity.values ? getValueInPath(entity.values, propertyKey) : undefined;
|
|
201
|
-
const property = getPropertyFor?.({
|
|
203
|
+
const property = getPropertyFor?.({
|
|
204
|
+
propertyKey,
|
|
205
|
+
propertyValue,
|
|
206
|
+
entity
|
|
207
|
+
}) ?? column.custom.resolvedProperty;
|
|
202
208
|
if (!property?.disabled) {
|
|
203
209
|
disabled = false;
|
|
204
210
|
}
|
|
@@ -238,7 +244,7 @@ export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>
|
|
|
238
244
|
|
|
239
245
|
const entity: Entity<M> = rowData;
|
|
240
246
|
|
|
241
|
-
const additionalField = additionalFieldsMap[column.key as
|
|
247
|
+
const additionalField = additionalFieldsMap[column.key as string];
|
|
242
248
|
const value = additionalField.dependencies
|
|
243
249
|
? Object.entries(entity.values)
|
|
244
250
|
.filter(([key, value]) => additionalField.dependencies!.includes(key as Extract<keyof M, string>))
|
|
@@ -318,14 +324,14 @@ export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>
|
|
|
318
324
|
|
|
319
325
|
const idColumn: VirtualTableColumn = useMemo(() => ({
|
|
320
326
|
key: "id_ewcfedcswdf3",
|
|
321
|
-
width: largeLayout ? 160 : 130,
|
|
327
|
+
width: getIdColumnWidth?.() ?? (largeLayout ? 160 : 130),
|
|
322
328
|
title: "ID",
|
|
323
329
|
resizable: false,
|
|
324
330
|
frozen: largeLayout,
|
|
325
331
|
headerAlign: "center",
|
|
326
332
|
align: "center",
|
|
327
333
|
AdditionalHeaderWidget: () => additionalIDHeaderWidget
|
|
328
|
-
}), [largeLayout])
|
|
334
|
+
}), [getIdColumnWidth, largeLayout])
|
|
329
335
|
|
|
330
336
|
const columns: VirtualTableColumn[] = useMemo(() => [
|
|
331
337
|
idColumn,
|
|
@@ -410,6 +416,7 @@ export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>
|
|
|
410
416
|
sortBy={sortBy}
|
|
411
417
|
onSortByUpdate={setSortBy as ((sortBy?: [string, "asc" | "desc"]) => void)}
|
|
412
418
|
hoverRow={hoverRow}
|
|
419
|
+
emptyComponent={emptyComponent}
|
|
413
420
|
checkFilterCombination={checkFilterCombination}
|
|
414
421
|
createFilterField={filterable ? createFilterField : undefined}
|
|
415
422
|
rowClassName={useCallback((entity: Entity<M>) => {
|
|
@@ -433,8 +440,8 @@ function createFilterField({
|
|
|
433
440
|
filterValue,
|
|
434
441
|
setFilterValue,
|
|
435
442
|
column,
|
|
436
|
-
|
|
437
|
-
|
|
443
|
+
hidden,
|
|
444
|
+
setHidden
|
|
438
445
|
}: FilterFormFieldProps<{
|
|
439
446
|
resolvedProperty: ResolvedProperty,
|
|
440
447
|
disabled: boolean,
|
|
@@ -459,8 +466,8 @@ function createFilterField({
|
|
|
459
466
|
path={baseProperty.path}
|
|
460
467
|
title={resolvedProperty?.name}
|
|
461
468
|
previewProperties={baseProperty?.previewProperties}
|
|
462
|
-
|
|
463
|
-
|
|
469
|
+
hidden={hidden}
|
|
470
|
+
setHidden={setHidden}/>;
|
|
464
471
|
} else if (baseProperty.dataType === "number" || baseProperty.dataType === "string") {
|
|
465
472
|
const name = baseProperty.name;
|
|
466
473
|
const enumValues = baseProperty.enumValues ? enumToObjectEntries(baseProperty.enumValues) : undefined;
|
|
@@ -21,7 +21,7 @@ export type OnColumnResizeParams = { width: number, key: string };
|
|
|
21
21
|
* @category Collection components
|
|
22
22
|
*/
|
|
23
23
|
export type EntityCollectionTableProps<M extends Record<string, any>,
|
|
24
|
-
|
|
24
|
+
|
|
25
25
|
UserType extends User = User> = {
|
|
26
26
|
|
|
27
27
|
/**
|
|
@@ -105,7 +105,7 @@ export type EntityCollectionTableProps<M extends Record<string, any>,
|
|
|
105
105
|
|
|
106
106
|
inlineEditing?: boolean | ((entity: Entity<M>) => boolean);
|
|
107
107
|
|
|
108
|
-
additionalFields?: AdditionalFieldDelegate<M,
|
|
108
|
+
additionalFields?: AdditionalFieldDelegate<M, UserType>[];
|
|
109
109
|
|
|
110
110
|
defaultSize?: CollectionSize;
|
|
111
111
|
|
|
@@ -129,6 +129,9 @@ export type EntityCollectionTableProps<M extends Record<string, any>,
|
|
|
129
129
|
|
|
130
130
|
additionalIDHeaderWidget?: React.ReactNode;
|
|
131
131
|
|
|
132
|
+
emptyComponent?: React.ReactNode;
|
|
133
|
+
|
|
134
|
+
getIdColumnWidth?: () => number;
|
|
132
135
|
}
|
|
133
136
|
|
|
134
137
|
export type GetPropertyForProps<M extends Record<string, any>> = {
|
|
@@ -15,8 +15,8 @@ interface ReferenceFilterFieldProps {
|
|
|
15
15
|
path?: string;
|
|
16
16
|
title?: string;
|
|
17
17
|
previewProperties?: string[];
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
hidden: boolean;
|
|
19
|
+
setHidden: (hidden: boolean) => void;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
const operationLabels = {
|
|
@@ -42,7 +42,7 @@ export function ReferenceFilterField({
|
|
|
42
42
|
path,
|
|
43
43
|
title,
|
|
44
44
|
previewProperties,
|
|
45
|
-
|
|
45
|
+
setHidden
|
|
46
46
|
}: ReferenceFilterFieldProps) {
|
|
47
47
|
|
|
48
48
|
const possibleOperations: (keyof typeof operationLabels) [] = isArray
|
|
@@ -118,13 +118,13 @@ export function ReferenceFilterField({
|
|
|
118
118
|
onMultipleEntitiesSelected,
|
|
119
119
|
selectedEntityIds,
|
|
120
120
|
onClose: () => {
|
|
121
|
-
|
|
121
|
+
setHidden(false);
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
124
|
);
|
|
125
125
|
|
|
126
126
|
const doOpenDialog = () => {
|
|
127
|
-
|
|
127
|
+
setHidden(true);
|
|
128
128
|
referenceDialogController.open();
|
|
129
129
|
};
|
|
130
130
|
|
|
@@ -148,6 +148,10 @@ export function ReferenceFilterField({
|
|
|
148
148
|
);
|
|
149
149
|
};
|
|
150
150
|
|
|
151
|
+
console.log("ReferenceFilterField", {
|
|
152
|
+
internalValue
|
|
153
|
+
|
|
154
|
+
})
|
|
151
155
|
return (
|
|
152
156
|
|
|
153
157
|
<div className="flex w-[440px] flex-row">
|
|
@@ -175,7 +179,8 @@ export function ReferenceFilterField({
|
|
|
175
179
|
</div>}
|
|
176
180
|
{(!internalValue || (Array.isArray(internalValue) && internalValue.length === 0)) &&
|
|
177
181
|
<Button onClick={doOpenDialog}
|
|
178
|
-
|
|
182
|
+
variant={"outlined"}
|
|
183
|
+
className="h-full w-full">
|
|
179
184
|
{multiple ? "Select references" : "Select reference"}
|
|
180
185
|
</Button>
|
|
181
186
|
}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import React, { MouseEvent, useCallback } from "react";
|
|
2
|
+
import equal from "react-fast-compare"
|
|
2
3
|
|
|
3
|
-
import { CollectionSize, Entity } from "../../../../types";
|
|
4
|
-
import { Checkbox, IconButton, Tooltip, Typography } from "../../../../components";
|
|
5
|
-
import { useLargeLayout } from "../../../../hooks
|
|
6
|
-
import {
|
|
7
|
-
import { Menu, MenuItem } from "../../../../components/Menu";
|
|
4
|
+
import { CollectionSize, Entity, EntityAction, EntityCollection, SelectionController } from "../../../../types";
|
|
5
|
+
import { Checkbox, cn, IconButton, Menu, MenuItem, Tooltip, Typography } from "../../../../components";
|
|
6
|
+
import { useFireCMSContext, useLargeLayout } from "../../../../hooks";
|
|
7
|
+
import { MoreVertIcon } from "../../../../icons";
|
|
8
8
|
import { Skeleton } from "../../../../components/Skeleton";
|
|
9
|
-
import { cn } from "../../../../components/util/cn";
|
|
10
9
|
|
|
11
10
|
/**
|
|
12
11
|
*
|
|
@@ -25,62 +24,57 @@ import { cn } from "../../../../components/util/cn";
|
|
|
25
24
|
*
|
|
26
25
|
* @category Collection components
|
|
27
26
|
*/
|
|
28
|
-
export
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
27
|
+
export const EntityCollectionRowActions = React.memo(function EntityCollectionRowActions({
|
|
28
|
+
entity,
|
|
29
|
+
collection,
|
|
30
|
+
fullPath,
|
|
31
|
+
width,
|
|
32
|
+
frozen,
|
|
33
|
+
isSelected,
|
|
34
|
+
selectionEnabled,
|
|
35
|
+
size,
|
|
36
|
+
highlightEntity,
|
|
37
|
+
onCollectionChange,
|
|
38
|
+
unhighlightEntity,
|
|
39
|
+
actions = [],
|
|
40
|
+
hideId,
|
|
41
|
+
selectionController
|
|
42
|
+
}:
|
|
43
|
+
{
|
|
44
|
+
entity: Entity<any>,
|
|
45
|
+
collection?: EntityCollection<any>,
|
|
46
|
+
fullPath?: string,
|
|
47
|
+
width: number,
|
|
48
|
+
frozen?: boolean,
|
|
49
|
+
size: CollectionSize,
|
|
50
|
+
isSelected: boolean,
|
|
51
|
+
selectionEnabled?: boolean,
|
|
52
|
+
actions?: EntityAction[],
|
|
53
|
+
hideId?: boolean,
|
|
54
|
+
onCollectionChange?: () => void,
|
|
55
|
+
selectionController?: SelectionController;
|
|
56
|
+
highlightEntity?: (entity: Entity<any>) => void;
|
|
57
|
+
unhighlightEntity?: (entity: Entity<any>) => void;
|
|
58
|
+
}) {
|
|
54
59
|
|
|
55
60
|
const largeLayout = useLargeLayout();
|
|
56
61
|
|
|
57
|
-
const
|
|
58
|
-
const copyEnabled = Boolean(onCopyClicked);
|
|
59
|
-
const deleteEnabled = Boolean(onDeleteClicked);
|
|
62
|
+
const context = useFireCMSContext();
|
|
60
63
|
|
|
61
64
|
const onCheckedChange = useCallback((checked: boolean) => {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}, [entity, toggleEntitySelection]);
|
|
65
|
-
|
|
66
|
-
const onDeleteClick = useCallback((event: MouseEvent) => {
|
|
67
|
-
event.stopPropagation();
|
|
68
|
-
if (onDeleteClicked)
|
|
69
|
-
onDeleteClicked(entity);
|
|
70
|
-
}, [entity, onDeleteClicked]);
|
|
71
|
-
|
|
72
|
-
const onCopyClick = useCallback((event: MouseEvent) => {
|
|
73
|
-
event.stopPropagation();
|
|
74
|
-
if (onCopyClicked)
|
|
75
|
-
onCopyClicked(entity);
|
|
76
|
-
}, [entity, onCopyClicked]);
|
|
65
|
+
selectionController?.toggleEntitySelection(entity);
|
|
66
|
+
}, [entity, selectionController?.toggleEntitySelection]);
|
|
77
67
|
|
|
78
68
|
const onClick = useCallback((event: MouseEvent) => {
|
|
79
69
|
event.stopPropagation();
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
70
|
+
selectionController?.toggleEntitySelection(entity);
|
|
71
|
+
}, [entity, selectionController?.toggleEntitySelection]);
|
|
72
|
+
|
|
73
|
+
const hasActions = actions.length > 0;
|
|
74
|
+
const hasCollapsedActions = actions.some(a => a.collapsed || a.collapsed === undefined);
|
|
83
75
|
|
|
76
|
+
const collapsedActions = actions.filter(a => a.collapsed || a.collapsed === undefined);
|
|
77
|
+
const uncollapsedActions = actions.filter(a => a.collapsed === false);
|
|
84
78
|
return (
|
|
85
79
|
<div
|
|
86
80
|
onClick={onClick}
|
|
@@ -95,20 +89,58 @@ export function EntityCollectionRowActions<M extends Record<string, any>>({
|
|
|
95
89
|
contain: "strict"
|
|
96
90
|
}}>
|
|
97
91
|
|
|
98
|
-
{(
|
|
92
|
+
{(hasActions || selectionEnabled) &&
|
|
99
93
|
<div className="w-34 flex justify-center">
|
|
100
|
-
|
|
101
|
-
|
|
94
|
+
|
|
95
|
+
{uncollapsedActions.map((action, index) => (
|
|
96
|
+
<Tooltip key={index} title={action.name}>
|
|
102
97
|
<IconButton
|
|
103
98
|
onClick={(event: MouseEvent) => {
|
|
104
99
|
event.stopPropagation();
|
|
105
|
-
|
|
106
|
-
|
|
100
|
+
action.onClick({
|
|
101
|
+
entity,
|
|
102
|
+
fullPath,
|
|
103
|
+
collection,
|
|
104
|
+
context,
|
|
105
|
+
selectionController,
|
|
106
|
+
highlightEntity,
|
|
107
|
+
unhighlightEntity,
|
|
108
|
+
onCollectionChange
|
|
109
|
+
});
|
|
107
110
|
}}
|
|
108
111
|
size={largeLayout ? "medium" : "small"}>
|
|
109
|
-
|
|
112
|
+
{action.icon}
|
|
110
113
|
</IconButton>
|
|
111
114
|
</Tooltip>
|
|
115
|
+
))}
|
|
116
|
+
|
|
117
|
+
{hasCollapsedActions &&
|
|
118
|
+
<Menu
|
|
119
|
+
trigger={<IconButton
|
|
120
|
+
size={largeLayout ? "medium" : "small"}>
|
|
121
|
+
<MoreVertIcon/>
|
|
122
|
+
</IconButton>}>
|
|
123
|
+
{collapsedActions.map((action, index) => (
|
|
124
|
+
<MenuItem
|
|
125
|
+
key={index}
|
|
126
|
+
onClick={(e) => {
|
|
127
|
+
e.stopPropagation();
|
|
128
|
+
action.onClick({
|
|
129
|
+
entity,
|
|
130
|
+
fullPath,
|
|
131
|
+
collection,
|
|
132
|
+
context,
|
|
133
|
+
selectionController,
|
|
134
|
+
highlightEntity,
|
|
135
|
+
unhighlightEntity,
|
|
136
|
+
onCollectionChange
|
|
137
|
+
});
|
|
138
|
+
}}>
|
|
139
|
+
{action.icon}
|
|
140
|
+
{action.name}
|
|
141
|
+
</MenuItem>
|
|
142
|
+
))}
|
|
143
|
+
</Menu>
|
|
112
144
|
}
|
|
113
145
|
|
|
114
146
|
{selectionEnabled &&
|
|
@@ -120,24 +152,6 @@ export function EntityCollectionRowActions<M extends Record<string, any>>({
|
|
|
120
152
|
/>
|
|
121
153
|
</Tooltip>}
|
|
122
154
|
|
|
123
|
-
{(copyEnabled || deleteEnabled) &&
|
|
124
|
-
<Menu
|
|
125
|
-
trigger={<IconButton
|
|
126
|
-
size={largeLayout ? "medium" : "small"}>
|
|
127
|
-
<MoreVertIcon/>
|
|
128
|
-
</IconButton>}>
|
|
129
|
-
{deleteEnabled && <MenuItem onClick={onDeleteClick}>
|
|
130
|
-
<DeleteIcon/>
|
|
131
|
-
Delete
|
|
132
|
-
</MenuItem>}
|
|
133
|
-
|
|
134
|
-
{copyEnabled && <MenuItem onClick={onCopyClick}>
|
|
135
|
-
<FileCopyIcon/>
|
|
136
|
-
Copy
|
|
137
|
-
</MenuItem>}
|
|
138
|
-
</Menu>
|
|
139
|
-
}
|
|
140
|
-
|
|
141
155
|
</div>}
|
|
142
156
|
|
|
143
157
|
{!hideId && size !== "xs" && (
|
|
@@ -145,7 +159,10 @@ export function EntityCollectionRowActions<M extends Record<string, any>>({
|
|
|
145
159
|
|
|
146
160
|
{entity
|
|
147
161
|
? <Typography
|
|
148
|
-
|
|
162
|
+
onClick={(event) => {
|
|
163
|
+
event.stopPropagation();
|
|
164
|
+
}}
|
|
165
|
+
className={"font-mono select-all"}
|
|
149
166
|
variant={"caption"}
|
|
150
167
|
color={"secondary"}> {entity.id} </Typography>
|
|
151
168
|
: <Skeleton/>
|
|
@@ -156,4 +173,4 @@ export function EntityCollectionRowActions<M extends Record<string, any>>({
|
|
|
156
173
|
</div>
|
|
157
174
|
);
|
|
158
175
|
|
|
159
|
-
}
|
|
176
|
+
}, equal);
|
|
@@ -375,7 +375,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
|
|
|
375
375
|
hideOverflow = false;
|
|
376
376
|
}
|
|
377
377
|
} else if (arrayProperty.of.dataType === "reference") {
|
|
378
|
-
if (typeof arrayProperty.of.
|
|
378
|
+
if (typeof arrayProperty.of.path === "string") {
|
|
379
379
|
innerComponent =
|
|
380
380
|
<TableReferenceField
|
|
381
381
|
name={propertyKey as string}
|
|
@@ -384,7 +384,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
|
|
|
384
384
|
updateValue={updateValue}
|
|
385
385
|
size={size}
|
|
386
386
|
multiselect={true}
|
|
387
|
-
path={arrayProperty.of.
|
|
387
|
+
path={arrayProperty.of.path}
|
|
388
388
|
previewProperties={arrayProperty.of.previewProperties}
|
|
389
389
|
title={arrayProperty.of.name}
|
|
390
390
|
forceFilter={arrayProperty.of.forceFilter}
|