@firecms/core 3.0.0-alpha.21 → 3.0.0-alpha.25
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/TextareaAutosize.d.ts +2 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/core/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +8 -1
- package/dist/core/components/EntityCollectionTable/useEntityCollectionTableController.d.ts +1 -1
- package/dist/core/components/VirtualTable/VirtualTableHeader.d.ts +3 -0
- package/dist/core/components/VirtualTable/VirtualTableHeaderRow.d.ts +1 -1
- package/dist/core/components/VirtualTable/VirtualTableProps.d.ts +14 -0
- package/dist/core/components/VirtualTable/types.d.ts +2 -0
- package/dist/core/form_field_configs.d.ts +1 -1
- package/dist/core/util/make_properties_editable.d.ts +2 -1
- package/dist/core/util/property_utils.d.ts +2 -1
- package/dist/index.es.js +7886 -7752
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +105 -105
- package/dist/index.umd.js.map +1 -1
- package/dist/types/collections.d.ts +1 -0
- package/dist/types/plugins.d.ts +22 -0
- package/package.json +137 -136
- package/src/components/BooleanSwitch.tsx +1 -1
- package/src/components/BooleanSwitchWithLabel.tsx +2 -2
- package/src/components/CircularProgress.tsx +1 -1
- package/src/components/TextField.tsx +5 -6
- package/src/components/TextareaAutosize.tsx +8 -4
- package/src/components/index.tsx +2 -0
- package/src/core/components/EntityCollectionTable/EntityCollectionTable.tsx +18 -7
- package/src/core/components/EntityCollectionTable/EntityCollectionTableProps.tsx +13 -1
- package/src/core/components/EntityCollectionTable/internal/PropertyTableCell.tsx +4 -2
- package/src/core/components/EntityCollectionTable/useEntityCollectionTableController.tsx +1 -1
- package/src/core/components/EntityCollectionView/EntityCollectionView.tsx +110 -4
- package/src/core/components/VirtualTable/VirtualTable.tsx +19 -7
- package/src/core/components/VirtualTable/VirtualTableHeader.tsx +32 -32
- package/src/core/components/VirtualTable/VirtualTableHeaderRow.tsx +7 -2
- package/src/core/components/VirtualTable/VirtualTableProps.tsx +14 -0
- package/src/core/components/VirtualTable/VirtualTableRow.tsx +1 -1
- package/src/core/components/VirtualTable/types.tsx +2 -0
- package/src/core/util/make_properties_editable.ts +18 -1
- package/src/core/util/property_utils.tsx +6 -1
- package/src/form/components/LabelWithIcon.tsx +2 -3
- package/src/form/field_bindings/TextFieldBinding.tsx +1 -2
- package/src/types/collections.ts +2 -0
- package/src/types/plugins.tsx +24 -1
|
@@ -395,6 +395,7 @@ export type TableController<M extends Record<string, any> = any> = {
|
|
|
395
395
|
checkFilterCombination?: (filterValues: FilterValues<any>, sortBy?: [string, "asc" | "desc"]) => boolean;
|
|
396
396
|
popupCell?: SelectedCellProps<M>;
|
|
397
397
|
setPopupCell?: (popupCell?: SelectedCellProps<M>) => void;
|
|
398
|
+
onAddColumn?: (column: string) => void;
|
|
398
399
|
};
|
|
399
400
|
export type SelectedCellProps<M extends Record<string, any>> = {
|
|
400
401
|
propertyKey: Extract<keyof M, string>;
|
package/dist/types/plugins.d.ts
CHANGED
|
@@ -84,6 +84,28 @@ export type FireCMSPlugin<PROPS = any, FORM_PROPS = any> = {
|
|
|
84
84
|
children: React.ReactNode;
|
|
85
85
|
};
|
|
86
86
|
};
|
|
87
|
+
collectionView?: {
|
|
88
|
+
/**
|
|
89
|
+
* Use this method to inject widgets to the entity collections header
|
|
90
|
+
* @param props
|
|
91
|
+
*/
|
|
92
|
+
HeaderAction?: React.ComponentType<{
|
|
93
|
+
property: ResolvedProperty;
|
|
94
|
+
propertyKey: string;
|
|
95
|
+
fullPath: string;
|
|
96
|
+
parentPathSegments: string[];
|
|
97
|
+
onHover: boolean;
|
|
98
|
+
}>;
|
|
99
|
+
/**
|
|
100
|
+
* If you add this callback to your plugin, an add button will be added to the collection table.
|
|
101
|
+
* TODO: Only the first plugin that defines this callback will be used, at the moment.
|
|
102
|
+
*/
|
|
103
|
+
AddColumnComponent?: React.ComponentType<{
|
|
104
|
+
fullPath: string;
|
|
105
|
+
parentPathSegments: string[];
|
|
106
|
+
collection: EntityCollection;
|
|
107
|
+
}>;
|
|
108
|
+
};
|
|
87
109
|
};
|
|
88
110
|
/**
|
|
89
111
|
* Props passed to the {@link FireCMSPlugin.homePage.CollectionActions} method.
|
package/package.json
CHANGED
|
@@ -1,139 +1,140 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
"name": "@firecms/core",
|
|
3
|
+
"version": "3.0.0-alpha.25",
|
|
4
|
+
"description": "Awesome Firebase/Firestore-based headless open-source CMS",
|
|
5
|
+
"funding": {
|
|
6
|
+
"url": "https://github.com/sponsors/firecmsco"
|
|
7
|
+
},
|
|
8
|
+
"author": "FireCMS",
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"repository": "git@github.com:FireCMSco/firecms.git",
|
|
11
|
+
"main": "./dist/index.umd.js",
|
|
12
|
+
"module": "./dist/index.es.js",
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"source": "src/index.ts",
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": ">=14"
|
|
17
|
+
},
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"import": "./dist/index.es.js",
|
|
21
|
+
"require": "./dist/index.umd.js",
|
|
22
|
+
"types": "./dist/index.d.ts"
|
|
7
23
|
},
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
},
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
"
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
"
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
"
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
"react-router-dom": "^6.17.0",
|
|
125
|
-
"ts-jest": "^29.1.1",
|
|
126
|
-
"ts-node": "^10.9.1",
|
|
127
|
-
"tsd": "^0.28.1",
|
|
128
|
-
"typescript": "^5.2.2",
|
|
129
|
-
"vite": "^4.5.0"
|
|
130
|
-
},
|
|
131
|
-
"files": [
|
|
132
|
-
"dist",
|
|
133
|
-
"src"
|
|
134
|
-
],
|
|
135
|
-
"gitHead": "4a18047fa8fd4ddaa157ec2d415fcab89cf34d65",
|
|
136
|
-
"publishConfig": {
|
|
137
|
-
"access": "public"
|
|
138
|
-
}
|
|
24
|
+
"./package.json": "./package.json"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"firebase",
|
|
28
|
+
"cms",
|
|
29
|
+
"admin",
|
|
30
|
+
"admin panel",
|
|
31
|
+
"firebase panel",
|
|
32
|
+
"firestore",
|
|
33
|
+
"headless",
|
|
34
|
+
"headless cms",
|
|
35
|
+
"content manager"
|
|
36
|
+
],
|
|
37
|
+
"scripts": {
|
|
38
|
+
"watch": "vite build --watch",
|
|
39
|
+
"build": "vite build && tsc --emitDeclarationOnly",
|
|
40
|
+
"prepublishOnly": "run-s build",
|
|
41
|
+
"createTag": "PACKAGE_VERSION=$(cat package.json | grep version | head -1 | awk -F: '{ print $2 }' | sed 's/[\",]//g' | tr -d '[[:space:]]') && git tag v$PACKAGE_VERSION && git push --tags",
|
|
42
|
+
"test:lint": "eslint \"src/**\" --quiet",
|
|
43
|
+
"test": "jest",
|
|
44
|
+
"clean": "rm -rf dist && find ./src -name '*.js' -type f | xargs rm -f",
|
|
45
|
+
"generateIcons": "ts-node --esm src/icons/generateIcons.ts"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@date-io/date-fns": "^2.17.0",
|
|
49
|
+
"@fontsource/ibm-plex-mono": "^5.0.8",
|
|
50
|
+
"@fontsource/roboto": "^5.0.8",
|
|
51
|
+
"@hello-pangea/dnd": "^16.3.0",
|
|
52
|
+
"@material-design-icons/font": "^0.14.13",
|
|
53
|
+
"@radix-ui/react-checkbox": "^1.0.4",
|
|
54
|
+
"@radix-ui/react-collapsible": "^1.0.3",
|
|
55
|
+
"@radix-ui/react-dialog": "^1.0.5",
|
|
56
|
+
"@radix-ui/react-dropdown-menu": "^2.0.6",
|
|
57
|
+
"@radix-ui/react-popover": "^1.0.7",
|
|
58
|
+
"@radix-ui/react-portal": "^1.0.4",
|
|
59
|
+
"@radix-ui/react-scroll-area": "^1.0.5",
|
|
60
|
+
"@radix-ui/react-select": "^1.2.2",
|
|
61
|
+
"@radix-ui/react-switch": "^1.0.3",
|
|
62
|
+
"@radix-ui/react-tabs": "^1.0.4",
|
|
63
|
+
"@radix-ui/react-tooltip": "^1.0.7",
|
|
64
|
+
"cmdk": "^0.2.0",
|
|
65
|
+
"date-fns": "^2.30.0",
|
|
66
|
+
"formik": "^2.4.5",
|
|
67
|
+
"history": "^5.3.0",
|
|
68
|
+
"js-search": "^2.0.1",
|
|
69
|
+
"markdown-it": "^13.0.2",
|
|
70
|
+
"notistack": "^3.0.1",
|
|
71
|
+
"object-hash": "^3.0.0",
|
|
72
|
+
"react-datepicker": "^4.21.0",
|
|
73
|
+
"react-dropzone": "^14.2.3",
|
|
74
|
+
"react-fast-compare": "^3.2.2",
|
|
75
|
+
"react-image-file-resizer": "^0.4.8",
|
|
76
|
+
"react-markdown-editor-lite": "^1.3.4",
|
|
77
|
+
"react-transition-group": "^4.4.5",
|
|
78
|
+
"react-use-measure": "^2.1.1",
|
|
79
|
+
"react-window": "^1.8.9",
|
|
80
|
+
"tailwind-merge": "^1.14.0",
|
|
81
|
+
"typeface-rubik": "^1.1.13",
|
|
82
|
+
"yup": "^0.32.11"
|
|
83
|
+
},
|
|
84
|
+
"peerDependencies": {
|
|
85
|
+
"algoliasearch": "^4.13.0",
|
|
86
|
+
"firebase": "^10.4.0",
|
|
87
|
+
"react": "^18.2.0",
|
|
88
|
+
"react-dom": "^18.2.0",
|
|
89
|
+
"react-router": "^6.2.0",
|
|
90
|
+
"react-router-dom": "^6.2.0"
|
|
91
|
+
},
|
|
92
|
+
"eslintConfig": {
|
|
93
|
+
"extends": [
|
|
94
|
+
"react-app",
|
|
95
|
+
"react-app/jest"
|
|
96
|
+
]
|
|
97
|
+
},
|
|
98
|
+
"devDependencies": {
|
|
99
|
+
"@jest/globals": "^29.7.0",
|
|
100
|
+
"@testing-library/jest-dom": "^5.17.0",
|
|
101
|
+
"@testing-library/react": "^14.0.0",
|
|
102
|
+
"@testing-library/user-event": "^14.5.1",
|
|
103
|
+
"@types/jest": "^29.5.6",
|
|
104
|
+
"@types/node": "^18.18.7",
|
|
105
|
+
"@types/object-hash": "^3.0.5",
|
|
106
|
+
"@types/react": "^18.2.33",
|
|
107
|
+
"@types/react-dom": "^18.2.14",
|
|
108
|
+
"@types/react-measure": "^2.0.10",
|
|
109
|
+
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
|
110
|
+
"@typescript-eslint/parser": "^5.62.0",
|
|
111
|
+
"@vitejs/plugin-react": "^4.1.0",
|
|
112
|
+
"algoliasearch": "^4.20.0",
|
|
113
|
+
"cross-env": "^7.0.3",
|
|
114
|
+
"eslint": "^8.52.0",
|
|
115
|
+
"eslint-config-standard": "^17.1.0",
|
|
116
|
+
"eslint-plugin-import": "^2.29.0",
|
|
117
|
+
"eslint-plugin-n": "^15.7.0",
|
|
118
|
+
"eslint-plugin-promise": "^6.1.1",
|
|
119
|
+
"eslint-plugin-react": "^7.33.2",
|
|
120
|
+
"eslint-plugin-react-hooks": "^4.6.0",
|
|
121
|
+
"firebase": "^10.5.2",
|
|
122
|
+
"jest": "^29.7.0",
|
|
123
|
+
"npm-run-all": "^4.1.5",
|
|
124
|
+
"react-router": "^6.17.0",
|
|
125
|
+
"react-router-dom": "^6.17.0",
|
|
126
|
+
"ts-jest": "^29.1.1",
|
|
127
|
+
"ts-node": "^10.9.1",
|
|
128
|
+
"tsd": "^0.28.1",
|
|
129
|
+
"typescript": "^5.2.2",
|
|
130
|
+
"vite": "^4.5.0"
|
|
131
|
+
},
|
|
132
|
+
"files": [
|
|
133
|
+
"dist",
|
|
134
|
+
"src"
|
|
135
|
+
],
|
|
136
|
+
"gitHead": "8bce80c65696930df7a8003b0b5d0310f595d46d",
|
|
137
|
+
"publishConfig": {
|
|
138
|
+
"access": "public"
|
|
139
|
+
}
|
|
139
140
|
}
|
|
@@ -54,12 +54,12 @@ export const BooleanSwitchWithLabel = function BooleanSwitchWithLabel({
|
|
|
54
54
|
onBlur={onBlur}
|
|
55
55
|
tabIndex={-1}
|
|
56
56
|
className={cn(
|
|
57
|
-
|
|
57
|
+
!invisible && fieldBackgroundMixin,
|
|
58
58
|
!invisible && (disabled ? fieldBackgroundDisabledMixin : fieldBackgroundHoverMixin),
|
|
59
59
|
disabled ? "cursor-default" : "cursor-pointer",
|
|
60
60
|
"rounded-md relative max-w-full justify-between w-full box-border relative inline-flex items-center",
|
|
61
61
|
!invisible && focus && !disabled ? focusedClasses : "",
|
|
62
|
-
error ? "text-red-500 dark:text-red-600" : (focus ? "text-primary" : (!disabled ? "text-text-primary dark:text-text-primary-dark" : "text-text-secondary dark:text-text-secondary-dark")),
|
|
62
|
+
error ? "text-red-500 dark:text-red-600" : (focus && !disabled ? "text-primary" : (!disabled ? "text-text-primary dark:text-text-primary-dark" : "text-text-secondary dark:text-text-secondary-dark")),
|
|
63
63
|
size === "small" ? "min-h-[40px]" : "min-h-[64px]",
|
|
64
64
|
size === "small" ? "pl-2" : "pl-4",
|
|
65
65
|
size === "small" ? "pr-4" : "pr-6",
|
|
@@ -89,8 +89,7 @@ export function TextField<T extends string | number>({
|
|
|
89
89
|
? <TextareaAutosize
|
|
90
90
|
{...inputProps as any}
|
|
91
91
|
ref={inputRef}
|
|
92
|
-
|
|
93
|
-
placeholder={placeholder}
|
|
92
|
+
placeholder={focused || hasValue || !label ? placeholder : undefined}
|
|
94
93
|
autoFocus={autoFocus}
|
|
95
94
|
rows={rows}
|
|
96
95
|
// onFocus={() => setFocused(true)}
|
|
@@ -119,10 +118,10 @@ export function TextField<T extends string | number>({
|
|
|
119
118
|
label ? (size === "medium" ? "pt-[28px] pb-2" : "pt-4 pb-2") : "py-2",
|
|
120
119
|
focused ? "text-text-primary dark:text-text-primary-dark" : "",
|
|
121
120
|
endAdornment ? "pr-10" : "pr-3",
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
disabled && "border border-transparent outline-none opacity-50 dark:opacity-50 text-gray-800 dark:text-gray-200",
|
|
122
|
+
inputClassName
|
|
124
123
|
)}
|
|
125
|
-
placeholder={placeholder}
|
|
124
|
+
placeholder={focused || hasValue || !label ? placeholder : undefined}
|
|
126
125
|
autoFocus={autoFocus}
|
|
127
126
|
onFocus={() => setFocused(true)}
|
|
128
127
|
onBlur={() => setFocused(false)}
|
|
@@ -150,7 +149,7 @@ export function TextField<T extends string | number>({
|
|
|
150
149
|
className={cn(
|
|
151
150
|
"pointer-events-none absolute",
|
|
152
151
|
size === "medium" ? "top-1" : "-top-1",
|
|
153
|
-
!error ? (focused ? "text-primary" : "text-text-secondary dark:text-text-secondary-dark") : "text-red-500 dark:text-red-600",
|
|
152
|
+
!error ? (focused ? "text-primary dark:text-primary" : "text-text-secondary dark:text-text-secondary-dark") : "text-red-500 dark:text-red-600",
|
|
154
153
|
disabled ? "opacity-50" : "")}
|
|
155
154
|
shrink={hasValue || focused}
|
|
156
155
|
>
|
|
@@ -2,6 +2,7 @@ import * as React from "react";
|
|
|
2
2
|
import { useLayoutEffect } from "react";
|
|
3
3
|
import * as ReactDOM from "react-dom";
|
|
4
4
|
import { debounce } from "../core/util/debounce";
|
|
5
|
+
import { cn } from "./util/cn";
|
|
5
6
|
|
|
6
7
|
type State = {
|
|
7
8
|
outerHeightStyle: number;
|
|
@@ -102,6 +103,7 @@ export const TextareaAutosize = React.forwardRef(function TextareaAutosize(
|
|
|
102
103
|
getStyleValue(computedStyle.paddingBottom) + getStyleValue(computedStyle.paddingTop);
|
|
103
104
|
const border =
|
|
104
105
|
getStyleValue(computedStyle.borderBottomWidth) + getStyleValue(computedStyle.borderTopWidth);
|
|
106
|
+
const minHeight = getStyleValue(computedStyle.minHeight);
|
|
105
107
|
|
|
106
108
|
// The height of the inner content
|
|
107
109
|
const innerHeight = sizeReferenceElement.scrollHeight;
|
|
@@ -119,10 +121,11 @@ export const TextareaAutosize = React.forwardRef(function TextareaAutosize(
|
|
|
119
121
|
if (maxRows) {
|
|
120
122
|
outerHeight = Math.min(Number(maxRows) * singleRowHeight, outerHeight);
|
|
121
123
|
}
|
|
122
|
-
outerHeight = Math.max(outerHeight, singleRowHeight);
|
|
124
|
+
outerHeight = Math.max(outerHeight, singleRowHeight, minHeight);
|
|
123
125
|
|
|
124
126
|
// Take the box sizing into account for applying this value as a style.
|
|
125
|
-
const outerHeightStyle = outerHeight + (boxSizing === "border-box" ? padding + border : 0);
|
|
127
|
+
const outerHeightStyle = outerHeight + (!props.ignoreBoxSizing && boxSizing === "border-box" ? padding + border : 0);
|
|
128
|
+
|
|
126
129
|
const overflow = Math.abs(outerHeight - innerHeight) <= 1;
|
|
127
130
|
|
|
128
131
|
return {
|
|
@@ -274,7 +277,7 @@ export const TextareaAutosize = React.forwardRef(function TextareaAutosize(
|
|
|
274
277
|
/>
|
|
275
278
|
<textarea
|
|
276
279
|
aria-hidden
|
|
277
|
-
className={props.shadowClassName}
|
|
280
|
+
className={cn(props.className, props.shadowClassName)}
|
|
278
281
|
readOnly
|
|
279
282
|
ref={shadowRef}
|
|
280
283
|
tabIndex={-1}
|
|
@@ -327,8 +330,9 @@ export type TextareaAutosizeProps = Omit<React.InputHTMLAttributes<HTMLTextAreaE
|
|
|
327
330
|
onResize?: (state: State) => void;
|
|
328
331
|
|
|
329
332
|
autoFocus?: boolean;
|
|
330
|
-
}
|
|
331
333
|
|
|
334
|
+
ignoreBoxSizing?: boolean;
|
|
335
|
+
}
|
|
332
336
|
|
|
333
337
|
function useForkRef<Instance>(
|
|
334
338
|
...refs: Array<React.Ref<Instance> | undefined>
|
package/src/components/index.tsx
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
AdditionalFieldDelegate,
|
|
6
6
|
CollectionSize,
|
|
7
7
|
Entity,
|
|
8
|
+
EntityCollection,
|
|
8
9
|
FilterValues,
|
|
9
10
|
FireCMSContext,
|
|
10
11
|
ResolvedProperty,
|
|
@@ -106,7 +107,10 @@ export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>
|
|
|
106
107
|
},
|
|
107
108
|
filterable = true,
|
|
108
109
|
sortable = true,
|
|
109
|
-
endAdornment
|
|
110
|
+
endAdornment,
|
|
111
|
+
AddColumnComponent,
|
|
112
|
+
AdditionalHeaderWidget,
|
|
113
|
+
additionalIDHeaderWidget
|
|
110
114
|
}: EntityCollectionTableProps<M>) {
|
|
111
115
|
|
|
112
116
|
const largeLayout = useLargeLayout();
|
|
@@ -268,7 +272,7 @@ export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>
|
|
|
268
272
|
|
|
269
273
|
}, [additionalFieldsMap, size, selectedEntityIds]);
|
|
270
274
|
|
|
271
|
-
const
|
|
275
|
+
const collectionColumns: VirtualTableColumn[] = useMemo(() => {
|
|
272
276
|
const columnsResult: VirtualTableColumn[] = Object.entries<ResolvedProperty>(properties)
|
|
273
277
|
.flatMap(([key, property]) => getColumnKeysForProperty(property, key))
|
|
274
278
|
.map(({
|
|
@@ -291,7 +295,10 @@ export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>
|
|
|
291
295
|
custom: {
|
|
292
296
|
resolvedProperty: property,
|
|
293
297
|
disabled
|
|
294
|
-
}
|
|
298
|
+
},
|
|
299
|
+
AdditionalHeaderWidget: ({ onHover }) => AdditionalHeaderWidget
|
|
300
|
+
? <AdditionalHeaderWidget property={property} propertyKey={key} onHover={onHover}/>
|
|
301
|
+
: undefined
|
|
295
302
|
};
|
|
296
303
|
});
|
|
297
304
|
|
|
@@ -315,16 +322,18 @@ export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>
|
|
|
315
322
|
title: "ID",
|
|
316
323
|
resizable: false,
|
|
317
324
|
frozen: largeLayout,
|
|
318
|
-
headerAlign: "center"
|
|
325
|
+
headerAlign: "center",
|
|
326
|
+
align: "center",
|
|
327
|
+
AdditionalHeaderWidget: () => additionalIDHeaderWidget
|
|
319
328
|
}), [largeLayout])
|
|
320
329
|
|
|
321
330
|
const columns: VirtualTableColumn[] = useMemo(() => [
|
|
322
331
|
idColumn,
|
|
323
332
|
...displayedColumnIds
|
|
324
333
|
.map((p) => {
|
|
325
|
-
return
|
|
334
|
+
return collectionColumns.find(c => c.key === p.key);
|
|
326
335
|
}).filter(Boolean) as VirtualTableColumn[]
|
|
327
|
-
], [
|
|
336
|
+
], [collectionColumns, displayedColumnIds, idColumn]);
|
|
328
337
|
|
|
329
338
|
const cellRenderer = useCallback((props: CellRendererParams<any>) => {
|
|
330
339
|
const column = props.column;
|
|
@@ -366,7 +375,7 @@ export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>
|
|
|
366
375
|
onValueChange,
|
|
367
376
|
size,
|
|
368
377
|
selectedCell,
|
|
369
|
-
selectedEntityIds
|
|
378
|
+
selectedEntityIds
|
|
370
379
|
}}
|
|
371
380
|
>
|
|
372
381
|
|
|
@@ -408,6 +417,7 @@ export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>
|
|
|
408
417
|
}, [selectedEntityIds])}
|
|
409
418
|
className="flex-grow"
|
|
410
419
|
endAdornment={endAdornment}
|
|
420
|
+
AddColumnComponent={AddColumnComponent}
|
|
411
421
|
/>
|
|
412
422
|
|
|
413
423
|
</div>
|
|
@@ -495,3 +505,4 @@ function filterableProperty(property: ResolvedProperty, partOfArray = false): bo
|
|
|
495
505
|
}
|
|
496
506
|
return ["string", "number", "boolean", "date", "reference", "array"].includes(property.dataType);
|
|
497
507
|
}
|
|
508
|
+
|
|
@@ -5,7 +5,9 @@ import {
|
|
|
5
5
|
Entity,
|
|
6
6
|
FilterValues,
|
|
7
7
|
ResolvedProperties,
|
|
8
|
-
|
|
8
|
+
ResolvedProperty,
|
|
9
|
+
SelectionController,
|
|
10
|
+
TableController,
|
|
9
11
|
User
|
|
10
12
|
} from "../../../types";
|
|
11
13
|
import { OnCellValueChange, UniqueFieldValidator } from "./types";
|
|
@@ -117,6 +119,16 @@ export type EntityCollectionTableProps<M extends Record<string, any>,
|
|
|
117
119
|
|
|
118
120
|
endAdornment?: React.ReactNode;
|
|
119
121
|
|
|
122
|
+
AdditionalHeaderWidget?: (props: {
|
|
123
|
+
property: ResolvedProperty,
|
|
124
|
+
propertyKey: string,
|
|
125
|
+
onHover: boolean,
|
|
126
|
+
}) => React.ReactNode;
|
|
127
|
+
|
|
128
|
+
AddColumnComponent?: React.ComponentType;
|
|
129
|
+
|
|
130
|
+
additionalIDHeaderWidget?: React.ReactNode;
|
|
131
|
+
|
|
120
132
|
}
|
|
121
133
|
|
|
122
134
|
export type GetPropertyForProps<M extends Record<string, any>> = {
|
|
@@ -128,11 +128,14 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
|
|
|
128
128
|
);
|
|
129
129
|
|
|
130
130
|
const saveValues = (value: any) => {
|
|
131
|
+
if (equal(value, internalValueRef.current))
|
|
132
|
+
return;
|
|
131
133
|
setSaved(false);
|
|
132
134
|
validation
|
|
133
135
|
.validate(value)
|
|
134
136
|
.then(() => {
|
|
135
137
|
setError(undefined);
|
|
138
|
+
internalValueRef.current = value;
|
|
136
139
|
if (onValueChange) {
|
|
137
140
|
onValueChange({
|
|
138
141
|
value,
|
|
@@ -167,7 +170,6 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
|
|
|
167
170
|
} else {
|
|
168
171
|
updatedValue = newValue;
|
|
169
172
|
}
|
|
170
|
-
internalValueRef.current = updatedValue;
|
|
171
173
|
setInternalValue(updatedValue);
|
|
172
174
|
saveValues(updatedValue);
|
|
173
175
|
};
|
|
@@ -234,7 +236,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
|
|
|
234
236
|
propertyKey={propertyKey}
|
|
235
237
|
property={property}
|
|
236
238
|
entity={entity}
|
|
237
|
-
value={
|
|
239
|
+
value={internalValue}
|
|
238
240
|
size={getPreviewSizeFrom(size)}
|
|
239
241
|
/>
|
|
240
242
|
</EntityTableCell>;
|
|
@@ -33,7 +33,7 @@ export function useEntityCollectionTableController<M extends Record<string, any>
|
|
|
33
33
|
collection,
|
|
34
34
|
entitiesDisplayedFirst,
|
|
35
35
|
lastDeleteTimestamp,
|
|
36
|
-
forceFilter: forceFilterFromProps
|
|
36
|
+
forceFilter: forceFilterFromProps,
|
|
37
37
|
}: EntityCollectionTableControllerProps<M>)
|
|
38
38
|
: TableController<M> {
|
|
39
39
|
|