@firecms/core 3.0.0-alpha.72 → 3.0.0-alpha.74
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/internal/DeleteEntityDialog.d.ts → DeleteEntityDialog.d.ts} +1 -1
- package/dist/components/EntityCollectionTable/{internal/EntityCollectionRowActions.d.ts → EntityCollectionRowActions.d.ts} +3 -3
- package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +1 -1
- package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +3 -3
- package/dist/components/EntityCollectionTable/{internal/PropertyTableCell.d.ts → PropertyTableCell.d.ts} +2 -2
- package/dist/components/EntityCollectionTable/SimpleEntityCollectionTable.d.ts +95 -0
- package/dist/components/EntityCollectionTable/column_utils.d.ts +16 -0
- package/dist/components/EntityCollectionTable/index.d.ts +4 -0
- package/dist/components/EntityCollectionTable/internal/CollectionTableToolbar.d.ts +1 -1
- package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +1 -1
- package/dist/components/EntityCollectionTable/types.d.ts +2 -2
- package/dist/components/EntityCollectionTable/useDataSourceEntityCollectionTableController.d.ts +3 -3
- package/dist/components/EntityCollectionView/EntityCollectionViewActions.d.ts +2 -2
- package/dist/components/VirtualTable/VirtualTableCell.d.ts +1 -1
- package/dist/components/VirtualTable/VirtualTableProps.d.ts +2 -3
- package/dist/components/VirtualTable/types.d.ts +1 -1
- package/dist/form/components/FieldHelperText.d.ts +1 -1
- package/dist/index.es.js +5004 -4214
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +587 -4
- package/dist/index.umd.js.map +1 -1
- package/dist/types/collections.d.ts +2 -2
- package/dist/types/plugins.d.ts +2 -0
- package/package.json +3 -3
- package/src/components/{EntityCollectionTable/internal/DeleteEntityDialog.tsx → DeleteEntityDialog.tsx} +4 -4
- package/src/components/EntityCollectionTable/{internal/EntityCollectionRowActions.tsx → EntityCollectionRowActions.tsx} +4 -4
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +13 -48
- package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +3 -3
- package/src/components/EntityCollectionTable/{internal/PropertyTableCell.tsx → PropertyTableCell.tsx} +19 -18
- package/src/components/EntityCollectionTable/SimpleEntityCollectionTable.tsx +369 -0
- package/src/components/EntityCollectionTable/column_utils.tsx +74 -0
- package/src/components/EntityCollectionTable/index.tsx +4 -0
- package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +3 -3
- package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +1 -2
- package/src/components/EntityCollectionTable/internal/default_entity_actions.tsx +1 -1
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +18 -18
- package/src/components/EntityCollectionTable/types.tsx +2 -2
- package/src/components/EntityCollectionTable/useDataSourceEntityCollectionTableController.tsx +3 -3
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +4 -4
- package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +2 -2
- package/src/components/ReferenceSelectionInner.tsx +1 -1
- package/src/components/VirtualTable/VirtualTableCell.tsx +9 -13
- package/src/components/VirtualTable/VirtualTableProps.tsx +3 -4
- package/src/components/VirtualTable/VirtualTableRow.tsx +0 -1
- package/src/components/VirtualTable/types.tsx +1 -1
- package/src/core/EntitySidePanel.tsx +0 -1
- package/src/core/FireCMS.tsx +2 -2
- package/src/form/EntityForm.tsx +7 -8
- package/src/form/PropertyFieldBinding.tsx +3 -1
- package/src/form/components/FieldHelperText.tsx +2 -2
- package/src/form/field_bindings/DateTimeFieldBinding.tsx +2 -1
- package/src/form/field_bindings/MapFieldBinding.tsx +3 -9
- package/src/form/field_bindings/MarkdownFieldBinding.tsx +585 -585
- package/src/form/validation.ts +5 -1
- package/src/internal/EntityView.tsx +6 -6
- package/src/internal/useBuildDataSource.ts +0 -2
- package/src/internal/useBuildSideEntityController.tsx +27 -15
- package/src/preview/components/BooleanPreview.tsx +1 -1
- package/src/preview/property_previews/MapPropertyPreview.tsx +3 -1
- package/src/preview/property_previews/StringPropertyPreview.tsx +1 -2
- package/src/types/collections.ts +2 -2
- package/src/types/plugins.tsx +4 -2
- package/src/util/enums.ts +1 -2
- package/dist/util/chip_utils.d.ts +0 -3
- package/src/util/chip_utils.ts +0 -13
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { getTableCellAlignment, getTablePropertyColumnWidth } from "./internal/common";
|
|
3
|
+
import { FilterValues, ResolvedProperties, ResolvedProperty } from "../../types";
|
|
4
|
+
import { VirtualTableColumn } from "../VirtualTable";
|
|
5
|
+
import { getIconForProperty, getResolvedPropertyInPath } from "../../util";
|
|
6
|
+
import { getColumnKeysForProperty } from "../EntityCollectionView/useColumnsIds";
|
|
7
|
+
|
|
8
|
+
export function buildIdColumn(largeLayout?: boolean): VirtualTableColumn {
|
|
9
|
+
return {
|
|
10
|
+
key: "id_ewcfedcswdf3",
|
|
11
|
+
width: (largeLayout ? 160 : 130),
|
|
12
|
+
title: "ID",
|
|
13
|
+
resizable: false,
|
|
14
|
+
frozen: largeLayout ?? false,
|
|
15
|
+
headerAlign: "center",
|
|
16
|
+
align: "center",
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface PropertiesToColumnsParams<M extends Record<string, any>> {
|
|
21
|
+
properties: ResolvedProperties<M>;
|
|
22
|
+
sortable?: boolean;
|
|
23
|
+
forceFilter?: FilterValues<keyof M extends string ? keyof M : never>;
|
|
24
|
+
disabledFilter?: boolean;
|
|
25
|
+
AdditionalHeaderWidget?: (props: {
|
|
26
|
+
property: ResolvedProperty,
|
|
27
|
+
propertyKey: string,
|
|
28
|
+
onHover: boolean,
|
|
29
|
+
}) => React.ReactNode;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function propertiesToColumns<M extends Record<string, any>>({ properties, sortable, forceFilter, disabledFilter, AdditionalHeaderWidget }: PropertiesToColumnsParams<M>): VirtualTableColumn[] {
|
|
33
|
+
return Object.entries<ResolvedProperty>(properties)
|
|
34
|
+
.flatMap(([key, property]) => getColumnKeysForProperty(property, key))
|
|
35
|
+
.map(({
|
|
36
|
+
key,
|
|
37
|
+
disabled
|
|
38
|
+
}) => {
|
|
39
|
+
const property = getResolvedPropertyInPath(properties, key);
|
|
40
|
+
if (!property)
|
|
41
|
+
throw Error("Internal error: no property found in path " + key);
|
|
42
|
+
const filterable = filterableProperty(property);
|
|
43
|
+
return {
|
|
44
|
+
key: key as string,
|
|
45
|
+
align: getTableCellAlignment(property),
|
|
46
|
+
icon: (hoverOrOpen) => getIconForProperty(property, "small"),
|
|
47
|
+
title: property.name ?? key as string,
|
|
48
|
+
sortable: sortable && (forceFilter ? Object.keys(forceFilter).includes(key) : true),
|
|
49
|
+
filter: !disabledFilter && filterable,
|
|
50
|
+
width: getTablePropertyColumnWidth(property),
|
|
51
|
+
resizable: true,
|
|
52
|
+
custom: {
|
|
53
|
+
resolvedProperty: property,
|
|
54
|
+
disabled
|
|
55
|
+
},
|
|
56
|
+
AdditionalHeaderWidget: AdditionalHeaderWidget
|
|
57
|
+
? ({ onHover }) => <AdditionalHeaderWidget property={property} propertyKey={key} onHover={onHover}/>
|
|
58
|
+
: undefined
|
|
59
|
+
} satisfies VirtualTableColumn;
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function filterableProperty(property: ResolvedProperty, partOfArray = false): boolean {
|
|
64
|
+
if (partOfArray) {
|
|
65
|
+
return ["string", "number", "date", "reference"].includes(property.dataType);
|
|
66
|
+
}
|
|
67
|
+
if (property.dataType === "array") {
|
|
68
|
+
if (property.of)
|
|
69
|
+
return filterableProperty(property.of, true);
|
|
70
|
+
else
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
return ["string", "number", "boolean", "date", "reference", "array"].includes(property.dataType);
|
|
74
|
+
}
|
|
@@ -13,4 +13,8 @@ export type {
|
|
|
13
13
|
OnCellValueChangeParams
|
|
14
14
|
} from "./types";
|
|
15
15
|
|
|
16
|
+
export * from "./PropertyTableCell";
|
|
17
|
+
export * from "./SimpleEntityCollectionTable";
|
|
18
|
+
export * from "./EntityCollectionRowActions";
|
|
16
19
|
export * from "./useDataSourceEntityCollectionTableController";
|
|
20
|
+
export * from "./column_utils";
|
|
@@ -17,7 +17,7 @@ interface CollectionTableToolbarProps {
|
|
|
17
17
|
size: CollectionSize;
|
|
18
18
|
filterIsSet: boolean;
|
|
19
19
|
loading: boolean;
|
|
20
|
-
forceFilter
|
|
20
|
+
forceFilter?: boolean;
|
|
21
21
|
actionsStart?: React.ReactNode;
|
|
22
22
|
actions?: React.ReactNode;
|
|
23
23
|
title?: React.ReactNode,
|
|
@@ -71,9 +71,9 @@ export function CollectionTableToolbar(props: CollectionTableToolbarProps) {
|
|
|
71
71
|
|
|
72
72
|
return (
|
|
73
73
|
<div
|
|
74
|
-
className={cn(defaultBorderMixin, "no-scrollbar min-h-[56px] overflow-x-auto px-4 bg-gray-50 dark:bg-gray-900 border-b flex flex-row justify-between items-center w-full")}>
|
|
74
|
+
className={cn(defaultBorderMixin, "no-scrollbar min-h-[56px] overflow-x-auto px-2 md:px-4 bg-gray-50 dark:bg-gray-900 border-b flex flex-row justify-between items-center w-full")}>
|
|
75
75
|
|
|
76
|
-
<div className="flex items-center gap-2">
|
|
76
|
+
<div className="flex items-center gap-2 md:mr-4 mr-2">
|
|
77
77
|
|
|
78
78
|
{props.title && <div className={"hidden lg:block"}>
|
|
79
79
|
{props.title}
|
|
@@ -4,8 +4,7 @@ import useMeasure from "react-use-measure";
|
|
|
4
4
|
|
|
5
5
|
import { VirtualTableSize } from "../../VirtualTable";
|
|
6
6
|
import { getRowHeight } from "../../VirtualTable/common";
|
|
7
|
-
import { cn, RemoveCircleIcon, Tooltip } from "@firecms/ui";
|
|
8
|
-
import { useOutsideAlerter } from "@firecms/ui";
|
|
7
|
+
import { useOutsideAlerter, cn, RemoveCircleIcon, Tooltip } from "@firecms/ui";
|
|
9
8
|
import { ErrorBoundary } from "../../../components";
|
|
10
9
|
|
|
11
10
|
interface EntityTableCellProps {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { EntityAction } from "../../../types";
|
|
2
|
-
import { DeleteEntityDialog } from "./DeleteEntityDialog";
|
|
3
2
|
import { ArchiveIcon, DeleteIcon, FileCopyIcon, KeyboardTabIcon, OpenInNewIcon } from "@firecms/ui";
|
|
3
|
+
import { DeleteEntityDialog } from "../../DeleteEntityDialog";
|
|
4
4
|
|
|
5
5
|
export const editEntityAction: EntityAction = {
|
|
6
6
|
icon: <KeyboardTabIcon/>,
|
|
@@ -40,7 +40,7 @@ interface PopupFormFieldProps<M extends Record<string, any>> {
|
|
|
40
40
|
* Callback when the value of a cell has been edited
|
|
41
41
|
* @param params
|
|
42
42
|
*/
|
|
43
|
-
onCellValueChange?: (params: OnCellValueChangeParams<any, M>) => Promise<void
|
|
43
|
+
onCellValueChange?: (params: OnCellValueChangeParams<any, M>) => Promise<void> | void;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
export function PopupFormField<M extends Record<string, any>>(props: PopupFormFieldProps<M>) {
|
|
@@ -63,7 +63,7 @@ export function PopupFormFieldInternal<M extends Record<string, any>>({
|
|
|
63
63
|
container
|
|
64
64
|
}: PopupFormFieldProps<M>) {
|
|
65
65
|
|
|
66
|
-
const dataSource = useDataSource();
|
|
66
|
+
// const dataSource = useDataSource();
|
|
67
67
|
const fireCMSContext = useFireCMSContext();
|
|
68
68
|
|
|
69
69
|
const [savingError, setSavingError] = React.useState<any>();
|
|
@@ -74,22 +74,22 @@ export function PopupFormFieldInternal<M extends Record<string, any>>({
|
|
|
74
74
|
|
|
75
75
|
const entityId = entityProp?.id;
|
|
76
76
|
const [entity, setEntity] = useState<Entity<M> | undefined>(entityProp);
|
|
77
|
-
useEffect(() => {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}, [dataSource, entityId, inputCollection, path, open]);
|
|
77
|
+
// useEffect(() => {
|
|
78
|
+
// if (entityId && inputCollection) {
|
|
79
|
+
// return dataSource.listenEntity?.({
|
|
80
|
+
// path,
|
|
81
|
+
// entityId,
|
|
82
|
+
// collection: inputCollection,
|
|
83
|
+
// onUpdate: (e) => {
|
|
84
|
+
// setEntity(e);
|
|
85
|
+
// setInternalValue(e?.values);
|
|
86
|
+
// }
|
|
87
|
+
// });
|
|
88
|
+
// } else {
|
|
89
|
+
// return () => {
|
|
90
|
+
// };
|
|
91
|
+
// }
|
|
92
|
+
// }, [dataSource, entityId, inputCollection, path, open]);
|
|
93
93
|
|
|
94
94
|
const [internalValue, setInternalValue] = useState<EntityValues<M> | undefined>(entity?.values);
|
|
95
95
|
|
|
@@ -31,7 +31,7 @@ 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, M extends Record<string, any
|
|
34
|
+
export interface OnCellValueChangeParams<T = any, M extends Record<string, any> = any> {
|
|
35
35
|
value: T,
|
|
36
36
|
propertyKey: string,
|
|
37
37
|
entity: Entity<M>,
|
|
@@ -55,4 +55,4 @@ export type UniqueFieldValidator = (props: {
|
|
|
55
55
|
* Callback when a cell has changed in a table
|
|
56
56
|
* @group Collection components
|
|
57
57
|
*/
|
|
58
|
-
export type OnCellValueChange<T, M extends Record<string, any>> = (params: OnCellValueChangeParams<T, M>) => Promise<void
|
|
58
|
+
export type OnCellValueChange<T, M extends Record<string, any>> = (params: OnCellValueChangeParams<T, M>) => Promise<void> | void;
|
package/src/components/EntityCollectionTable/useDataSourceEntityCollectionTableController.tsx
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
FilterValues,
|
|
9
9
|
FireCMSContext,
|
|
10
10
|
SelectedCellProps,
|
|
11
|
-
|
|
11
|
+
EntityTableController,
|
|
12
12
|
User
|
|
13
13
|
} from "../../types";
|
|
14
14
|
import { useDebouncedData } from "./useDebouncedData";
|
|
@@ -38,7 +38,7 @@ export type DataSourceEntityCollectionTableControllerProps<M extends Record<stri
|
|
|
38
38
|
* Use this hook to build a controller for the {@link EntityCollectionTable}.
|
|
39
39
|
* This controller is bound to data in a path in your specified datasource.
|
|
40
40
|
*
|
|
41
|
-
* Note that you can build your own hook returning a {@link
|
|
41
|
+
* Note that you can build your own hook returning a {@link EntityTableController}
|
|
42
42
|
* if you would like to display different data.
|
|
43
43
|
*
|
|
44
44
|
* @param fullPath
|
|
@@ -55,7 +55,7 @@ export function useDataSourceEntityCollectionTableController<M extends Record<st
|
|
|
55
55
|
lastDeleteTimestamp,
|
|
56
56
|
forceFilter: forceFilterFromProps,
|
|
57
57
|
}: DataSourceEntityCollectionTableControllerProps<M>)
|
|
58
|
-
:
|
|
58
|
+
: EntityTableController<M> {
|
|
59
59
|
|
|
60
60
|
const {
|
|
61
61
|
initialFilter,
|
|
@@ -22,8 +22,7 @@ import {
|
|
|
22
22
|
UniqueFieldValidator
|
|
23
23
|
} from "../EntityCollectionTable";
|
|
24
24
|
|
|
25
|
-
import { EntityCollectionRowActions } from "../EntityCollectionTable/
|
|
26
|
-
import { DeleteEntityDialog } from "../EntityCollectionTable/internal/DeleteEntityDialog";
|
|
25
|
+
import { EntityCollectionRowActions } from "../EntityCollectionTable/EntityCollectionRowActions";
|
|
27
26
|
|
|
28
27
|
import {
|
|
29
28
|
canCreateEntity,
|
|
@@ -72,6 +71,7 @@ import {
|
|
|
72
71
|
deleteEntityAction,
|
|
73
72
|
editEntityAction
|
|
74
73
|
} from "../EntityCollectionTable/internal/default_entity_actions";
|
|
74
|
+
import { DeleteEntityDialog } from "../DeleteEntityDialog";
|
|
75
75
|
|
|
76
76
|
const COLLECTION_GROUP_PARENT_ID = "collectionGroupParent";
|
|
77
77
|
|
|
@@ -570,7 +570,7 @@ export const EntityCollectionView = React.memo(
|
|
|
570
570
|
setTextSearchLoading(true);
|
|
571
571
|
Promise.all(context.plugins?.map(p => {
|
|
572
572
|
if (p.collectionView?.onTextSearchClick)
|
|
573
|
-
return p.collectionView.onTextSearchClick({ context, path: resolvedFullPath, collection });
|
|
573
|
+
return p.collectionView.onTextSearchClick({ context, path: resolvedFullPath, collection, parentCollectionIds });
|
|
574
574
|
return Promise.resolve(true);
|
|
575
575
|
}) as Promise<boolean>[])
|
|
576
576
|
.then((res) => {
|
|
@@ -583,7 +583,7 @@ export const EntityCollectionView = React.memo(
|
|
|
583
583
|
context.plugins?.forEach(p => {
|
|
584
584
|
if (!textSearchEnabled)
|
|
585
585
|
if (p.collectionView?.showTextSearchBar) {
|
|
586
|
-
textSearchEnabled = p.collectionView.showTextSearchBar({ context, path: resolvedFullPath, collection });
|
|
586
|
+
textSearchEnabled = p.collectionView.showTextSearchBar({ context, path: resolvedFullPath, collection, parentCollectionIds });
|
|
587
587
|
}
|
|
588
588
|
})
|
|
589
589
|
}
|
|
@@ -2,7 +2,7 @@ import React from "react";
|
|
|
2
2
|
|
|
3
3
|
import { canCreateEntity, canDeleteEntity, fullPathToCollectionSegments } from "../../util";
|
|
4
4
|
import { useAuthController, useFireCMSContext, useLargeLayout } from "../../hooks";
|
|
5
|
-
import { CollectionActionsProps, EntityCollection, SelectionController,
|
|
5
|
+
import { CollectionActionsProps, EntityCollection, SelectionController, EntityTableController } from "../../types";
|
|
6
6
|
import { AddIcon, Button, DeleteIcon, IconButton, Tooltip } from "@firecms/ui";
|
|
7
7
|
import { toArray } from "../../util/arrays";
|
|
8
8
|
import { ErrorBoundary } from "../ErrorBoundary";
|
|
@@ -16,7 +16,7 @@ export type EntityCollectionViewActionsProps<M extends Record<string, any>> = {
|
|
|
16
16
|
onNewClick: () => void;
|
|
17
17
|
onMultipleDeleteClick: () => void;
|
|
18
18
|
selectionController: SelectionController<M>;
|
|
19
|
-
tableController:
|
|
19
|
+
tableController: EntityTableController<M>;
|
|
20
20
|
collectionEntitiesCount: number;
|
|
21
21
|
}
|
|
22
22
|
|
|
@@ -2,7 +2,7 @@ import React, { MouseEventHandler, useCallback, useEffect, useMemo, useState } f
|
|
|
2
2
|
import { CollectionSize, Entity, EntityCollection, FilterValues } from "../types";
|
|
3
3
|
|
|
4
4
|
import { EntityCollectionTable } from "./EntityCollectionTable";
|
|
5
|
-
import { EntityCollectionRowActions } from "./EntityCollectionTable/
|
|
5
|
+
import { EntityCollectionRowActions } from "./EntityCollectionTable/EntityCollectionRowActions";
|
|
6
6
|
import {
|
|
7
7
|
useAuthController,
|
|
8
8
|
useDataSource,
|
|
@@ -12,23 +12,19 @@ type VirtualTableCellProps<T extends any> = {
|
|
|
12
12
|
cellData: any;
|
|
13
13
|
rowIndex: any;
|
|
14
14
|
columnIndex: number;
|
|
15
|
-
cellRenderer:
|
|
15
|
+
cellRenderer: React.ComponentType<CellRendererParams<T>>;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
export const VirtualTableCell = React.memo<VirtualTableCellProps<any>>(
|
|
19
19
|
function VirtualTableCell<T extends any>(props: VirtualTableCellProps<T>) {
|
|
20
|
-
return props.rowData && props.cellRenderer
|
|
21
|
-
{
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
columnIndex: props.columnIndex,
|
|
29
|
-
width: props.column.width
|
|
30
|
-
} as CellRendererParams<T>
|
|
31
|
-
);
|
|
20
|
+
return props.rowData && <props.cellRenderer
|
|
21
|
+
rowData={props.rowData}
|
|
22
|
+
rowIndex={props.rowIndex}
|
|
23
|
+
isScrolling={false}
|
|
24
|
+
column={props.column}
|
|
25
|
+
columns={props.columns}
|
|
26
|
+
columnIndex={props.columnIndex}
|
|
27
|
+
width={props.column.width}/>
|
|
32
28
|
},
|
|
33
29
|
(a, b) => {
|
|
34
30
|
return equal(a, b);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { WhereFilterOp } from "../../types";
|
|
2
|
+
import { ResolvedProperty, WhereFilterOp } from "../../types";
|
|
3
3
|
import { FilterFormFieldProps } from "./VirtualTableHeader";
|
|
4
4
|
|
|
5
5
|
export type OnRowClickParams<T extends Record<string, any>> = {
|
|
@@ -29,7 +29,7 @@ export interface VirtualTableProps<T extends Record<string, any>> {
|
|
|
29
29
|
* Custom cell renderer
|
|
30
30
|
* The renderer receives props `{ cellData, columns, column, columnIndex, rowData, rowIndex, container, isScrolling }`
|
|
31
31
|
*/
|
|
32
|
-
cellRenderer:
|
|
32
|
+
cellRenderer: React.ComponentType<CellRendererParams<T>>;
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
35
|
* If enabled, content is loaded in batch
|
|
@@ -144,8 +144,7 @@ export interface VirtualTableProps<T extends Record<string, any>> {
|
|
|
144
144
|
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
-
export type CellRendererParams<T extends any> = {
|
|
148
|
-
cellData?: any;
|
|
147
|
+
export type CellRendererParams<T extends any = any> = {
|
|
149
148
|
column: VirtualTableColumn;
|
|
150
149
|
columns: VirtualTableColumn[];
|
|
151
150
|
columnIndex: number;
|
|
@@ -26,7 +26,7 @@ export type VirtualTableContextProps<T extends any> = {
|
|
|
26
26
|
data?: T[];
|
|
27
27
|
size?: VirtualTableSize,
|
|
28
28
|
columns: VirtualTableColumn[];
|
|
29
|
-
cellRenderer:
|
|
29
|
+
cellRenderer: React.ComponentType<CellRendererParams<T>>;
|
|
30
30
|
currentSort: "asc" | "desc" | undefined;
|
|
31
31
|
filter?: VirtualTableFilterValues<any>;
|
|
32
32
|
onRowClick?: (props: OnRowClickParams<any>) => void;
|
package/src/core/FireCMS.tsx
CHANGED
|
@@ -95,7 +95,7 @@ export function FireCMS<UserType extends User, EC extends EntityCollection>(prop
|
|
|
95
95
|
|
|
96
96
|
if (navigationController.navigationLoadingError) {
|
|
97
97
|
return (
|
|
98
|
-
<CenteredView maxWidth={"md"}
|
|
98
|
+
<CenteredView maxWidth={"md"}>
|
|
99
99
|
<ErrorView
|
|
100
100
|
title={"Error loading navigation"}
|
|
101
101
|
error={navigationController.navigationLoadingError}/>
|
|
@@ -105,7 +105,7 @@ export function FireCMS<UserType extends User, EC extends EntityCollection>(prop
|
|
|
105
105
|
|
|
106
106
|
if (authController.authError) {
|
|
107
107
|
return (
|
|
108
|
-
<CenteredView maxWidth={"md"}
|
|
108
|
+
<CenteredView maxWidth={"md"}>
|
|
109
109
|
<ErrorView
|
|
110
110
|
title={"Error loading auth"}
|
|
111
111
|
error={authController.authError}/>
|
package/src/form/EntityForm.tsx
CHANGED
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
import { useAuthController, useDataSource, useFireCMSContext, useSideEntityController } from "../hooks";
|
|
29
29
|
import { ErrorFocus } from "./components/ErrorFocus";
|
|
30
30
|
import { CustomIdField } from "./components/CustomIdField";
|
|
31
|
-
import { Button, cn, DialogActions, IconButton, Typography } from "@firecms/ui";
|
|
31
|
+
import { Alert, Button, cn, DialogActions, IconButton, Typography } from "@firecms/ui";
|
|
32
32
|
import { ErrorBoundary } from "../components";
|
|
33
33
|
import {
|
|
34
34
|
copyEntityAction,
|
|
@@ -400,25 +400,24 @@ function EntityFormInternal<M extends Record<string, any>>({
|
|
|
400
400
|
)).filter(Boolean));
|
|
401
401
|
}
|
|
402
402
|
|
|
403
|
-
return <div
|
|
404
|
-
className="h-full overflow-auto"
|
|
405
|
-
>
|
|
403
|
+
return <div className="h-full overflow-auto">
|
|
406
404
|
|
|
407
405
|
{pluginActions.length > 0 && <div
|
|
408
406
|
className={cn("w-full flex justify-end items-center sticky top-0 right-0 left-0 z-10 bg-opacity-60 bg-slate-200 dark:bg-opacity-60 dark:bg-slate-800 backdrop-blur-md")}>
|
|
409
407
|
{pluginActions}
|
|
410
408
|
</div>}
|
|
411
409
|
|
|
412
|
-
<div
|
|
413
|
-
className="pl-4 pr-4 pt-12 pb-16 md:pl-8"
|
|
414
|
-
>
|
|
410
|
+
<div className="pl-4 pr-4 pt-12 pb-16 md:pl-8">
|
|
415
411
|
<div
|
|
416
|
-
className={`w-full py-2 flex items-
|
|
412
|
+
className={`w-full py-2 flex flex-col items-start mt-${4 + (pluginActions ? 8 : 0)} lg:mt-${8 + (pluginActions ? 8 : 0)} mb-8`}>
|
|
417
413
|
|
|
418
414
|
<Typography
|
|
419
415
|
className={"mt-4 flex-grow " + inputCollection.hideIdFromForm ? "mb-2" : "mb-0"}
|
|
420
416
|
variant={"h4"}>{inputCollection.singularName ?? inputCollection.name}
|
|
421
417
|
</Typography>
|
|
418
|
+
<Alert color={"base"} className={"w-full"} size={"small"}>
|
|
419
|
+
<code className={"text-xs select-all"}>{path}/{entityId}</code>
|
|
420
|
+
</Alert>
|
|
422
421
|
</div>
|
|
423
422
|
|
|
424
423
|
{!hideId &&
|
|
@@ -197,12 +197,14 @@ function FieldInternal<T extends CMSType, CustomProps, M extends Record<string,
|
|
|
197
197
|
const error = getIn(fieldProps.form.errors, propertyKey);
|
|
198
198
|
const touched = getIn(fieldProps.form.touched, propertyKey);
|
|
199
199
|
|
|
200
|
+
console.log("error", propertyKey, error);
|
|
201
|
+
|
|
200
202
|
const showError: boolean = error &&
|
|
201
203
|
(fieldProps.form.submitCount > 0 || property.validation?.unique) &&
|
|
202
204
|
(!Array.isArray(error) || !!error.filter((e: any) => !!e).length);
|
|
203
205
|
|
|
204
206
|
const WrappedComponent: ComponentType<FieldProps<T, any, M>> | null = useWrappedComponent(context.path, context.collection, propertyKey, property, Component, plugins);
|
|
205
|
-
const UsedComponent: ComponentType<FieldProps<T>> = Component;
|
|
207
|
+
const UsedComponent: ComponentType<FieldProps<T>> = WrappedComponent ?? Component;
|
|
206
208
|
|
|
207
209
|
const isSubmitting = fieldProps.form.isSubmitting;
|
|
208
210
|
|
|
@@ -12,7 +12,7 @@ export function FieldHelperText({
|
|
|
12
12
|
includeDescription = true,
|
|
13
13
|
disabled
|
|
14
14
|
}: {
|
|
15
|
-
error
|
|
15
|
+
error?: string,
|
|
16
16
|
showError: boolean,
|
|
17
17
|
property: ResolvedProperty,
|
|
18
18
|
includeDescription?: boolean,
|
|
@@ -27,7 +27,7 @@ export function FieldHelperText({
|
|
|
27
27
|
|
|
28
28
|
if (showError && error) {
|
|
29
29
|
return <Typography variant={"caption"}
|
|
30
|
-
className={"ml-3.5 text-red-500"}>
|
|
30
|
+
className={"ml-3.5 text-red-500 dark:text-red-500"}>
|
|
31
31
|
{error}
|
|
32
32
|
</Typography>
|
|
33
33
|
}
|
|
@@ -48,10 +48,11 @@ export function DateTimeFieldBinding({
|
|
|
48
48
|
mode={property.mode}
|
|
49
49
|
clearable={property.clearable}
|
|
50
50
|
locale={locale}
|
|
51
|
+
error={showError}
|
|
51
52
|
label={<LabelWithIcon
|
|
52
53
|
icon={getIconForProperty(property, "small")}
|
|
53
54
|
required={property.validation?.required}
|
|
54
|
-
className={"text-text-secondary dark:text-text-secondary-dark"}
|
|
55
|
+
className={showError ? "text-red-500 dark:text-red-500" : "text-text-secondary dark:text-text-secondary-dark"}
|
|
55
56
|
title={property.name}/>}
|
|
56
57
|
/>
|
|
57
58
|
|
|
@@ -51,12 +51,6 @@ export function MapFieldBinding<T extends Record<string, any>>({
|
|
|
51
51
|
mapProperties = property.properties;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
// useClearRestoreValue({
|
|
55
|
-
// property,
|
|
56
|
-
// value,
|
|
57
|
-
// setValue
|
|
58
|
-
// });
|
|
59
|
-
|
|
60
54
|
const mapFormView = <>
|
|
61
55
|
<div className="py-1 flex flex-col space-y-2">
|
|
62
56
|
{Object.entries(mapProperties)
|
|
@@ -99,14 +93,14 @@ export function MapFieldBinding<T extends Record<string, any>>({
|
|
|
99
93
|
<>
|
|
100
94
|
|
|
101
95
|
{!tableMode && !partOfBlock && <ExpandablePanel initiallyExpanded={expanded}
|
|
102
|
-
|
|
103
|
-
|
|
96
|
+
className={"px-2 md:px-4 pb-2 md:pb-4 pt-1 md:pt-2"}
|
|
97
|
+
title={title}>{mapFormView}</ExpandablePanel>}
|
|
104
98
|
|
|
105
99
|
{(tableMode || partOfBlock) && mapFormView}
|
|
106
100
|
|
|
107
101
|
<FieldHelperText includeDescription={includeDescription}
|
|
108
102
|
showError={showError}
|
|
109
|
-
error={error}
|
|
103
|
+
error={error ? (typeof error === "string" ? error : "A property of this map has an error") : undefined}
|
|
110
104
|
disabled={disabled}
|
|
111
105
|
property={property}/>
|
|
112
106
|
|