@linzjs/step-ag-grid 28.4.0 → 28.4.2
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/index.css +5 -0
- package/dist/src/components/GridCell.d.ts +4 -3
- package/dist/step-ag-grid.cjs +27 -35
- package/dist/step-ag-grid.cjs.map +1 -1
- package/dist/step-ag-grid.esm.js +27 -36
- package/dist/step-ag-grid.esm.js.map +1 -1
- package/package.json +8 -6
- package/src/components/GridCell.test.tsx +27 -25
- package/src/components/GridCell.tsx +36 -33
- package/src/components/GridIcon.tsx +1 -0
- package/src/styles/Grid.scss +5 -0
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@linzjs/step-ag-grid",
|
|
3
3
|
"repository": "github:linz/step-ag-grid.git",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"version": "28.4.
|
|
5
|
+
"version": "28.4.2",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"aggrid",
|
|
8
8
|
"ag-grid",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"access": "public"
|
|
25
25
|
},
|
|
26
26
|
"engines": {
|
|
27
|
-
"node": ">=
|
|
27
|
+
"node": ">=22"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
30
30
|
"@linzjs/lui": ">=21",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"clean": "rimraf dist && mkdirp ./dist",
|
|
48
48
|
"bundle": "rollup -c",
|
|
49
49
|
"css": "sass ./src/styles/index.scss:dist/index.css --no-source-map",
|
|
50
|
-
"test": "vitest run",
|
|
50
|
+
"test": "cross-env NODE_OPTIONS='--no-experimental-global-navigator' vitest run",
|
|
51
51
|
"test:watch": "vitest --watch",
|
|
52
52
|
"lint": "eslint ./src --ext .js,.ts,.tsx --cache --ignore-path .gitignore",
|
|
53
53
|
"lint:fix": "eslint ./src --ext .js,.ts,.tsx --fix --cache --ignore-path .gitignore",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
},
|
|
82
82
|
"devDependencies": {
|
|
83
83
|
"@chromatic-com/storybook": "^4.0.1",
|
|
84
|
-
"@linzjs/lui": "^23.
|
|
84
|
+
"@linzjs/lui": "^23.11.1",
|
|
85
85
|
"@linzjs/style": "^5.4.0",
|
|
86
86
|
"@rollup/plugin-commonjs": "^28.0.6",
|
|
87
87
|
"@rollup/plugin-json": "^6.1.0",
|
|
@@ -95,6 +95,7 @@
|
|
|
95
95
|
"@testing-library/react": "^16.3.0",
|
|
96
96
|
"@testing-library/user-event": "^14.6.1",
|
|
97
97
|
"@types/debounce-promise": "^3.1.9",
|
|
98
|
+
"@types/jsdom": "^21.1.7",
|
|
98
99
|
"@types/lodash-es": "^4.17.12",
|
|
99
100
|
"@types/node": "^22.17.0",
|
|
100
101
|
"@types/react": "^18.3.23",
|
|
@@ -105,7 +106,9 @@
|
|
|
105
106
|
"ag-grid-community": "^34.1.0",
|
|
106
107
|
"ag-grid-react": "^34.1.0",
|
|
107
108
|
"babel-preset-react-app": "^10.1.0",
|
|
109
|
+
"canvas": "^3.2.0",
|
|
108
110
|
"chromatic": "^13.1.3",
|
|
111
|
+
"cross-env": "^10.0.0",
|
|
109
112
|
"css-loader": "^7.1.2",
|
|
110
113
|
"eslint-plugin-react": "^7.37.5",
|
|
111
114
|
"eslint-plugin-storybook": "^9.1.0",
|
|
@@ -135,8 +138,7 @@
|
|
|
135
138
|
"vite": "^6.3.5",
|
|
136
139
|
"vite-plugin-html": "^3.2.2",
|
|
137
140
|
"vite-tsconfig-paths": "^5.1.4",
|
|
138
|
-
"vitest": "^3.2.4"
|
|
139
|
-
"vitest-canvas-mock": "^0.3.3"
|
|
141
|
+
"vitest": "^3.2.4"
|
|
140
142
|
},
|
|
141
143
|
"babel": {
|
|
142
144
|
"presets": [
|
|
@@ -1,35 +1,37 @@
|
|
|
1
|
-
import { ValueGetterParams } from 'ag-grid-community';
|
|
2
1
|
import { describe, expect, test } from 'vitest';
|
|
3
2
|
|
|
4
|
-
import {
|
|
5
|
-
import { generateFilterGetter } from './GridCell';
|
|
3
|
+
import { defaultValueFormatter, generateFilterGetter } from './GridCell';
|
|
6
4
|
|
|
7
5
|
describe('GridCell', () => {
|
|
8
|
-
test('
|
|
9
|
-
|
|
10
|
-
expect(
|
|
11
|
-
expect(
|
|
12
|
-
expect(
|
|
6
|
+
test('defaultValueFormatter', () => {
|
|
7
|
+
expect(defaultValueFormatter({ value: null } as any)).toBe('–');
|
|
8
|
+
expect(defaultValueFormatter({ value: undefined } as any)).toBe('–');
|
|
9
|
+
expect(defaultValueFormatter({ value: 'a' } as any)).toBe('a');
|
|
10
|
+
expect(defaultValueFormatter({ value: 1 } as any)).toBe('1');
|
|
11
|
+
expect(defaultValueFormatter({ value: false } as any)).toBe('false');
|
|
12
|
+
expect(defaultValueFormatter({ value: { x: 1 } } as any)).toBe('{"x":1}');
|
|
13
13
|
});
|
|
14
14
|
|
|
15
15
|
test('generateFilterGetter', () => {
|
|
16
|
-
expect(generateFilterGetter(
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
{ formatted: 'f2', value: {}, expected: 'f2' },
|
|
21
|
-
{ formatted: '', value: 'v3', expected: 'v3' },
|
|
22
|
-
];
|
|
23
|
-
|
|
24
|
-
tests.forEach((test) => {
|
|
25
|
-
const field = 'xxx';
|
|
26
|
-
const valueFormatter = test.formatted == null ? undefined : () => test.formatted;
|
|
27
|
-
const filterGetter = generateFilterGetter(field, undefined, valueFormatter);
|
|
28
|
-
expect(typeof filterGetter).toBe('function');
|
|
29
|
-
if (typeof filterGetter !== 'function') return;
|
|
30
|
-
expect(filterGetter({ getValue: () => test.value } as unknown as ValueGetterParams<GridBaseRow>)).toBe(
|
|
31
|
-
test.expected,
|
|
32
|
-
);
|
|
16
|
+
expect(generateFilterGetter(undefined)).toBeUndefined();
|
|
17
|
+
expect(generateFilterGetter('x')).toBeUndefined();
|
|
18
|
+
const fn = generateFilterGetter((props) => {
|
|
19
|
+
return String(props.value);
|
|
33
20
|
});
|
|
21
|
+
expect(fn).toBeTypeOf('function');
|
|
22
|
+
if (typeof fn !== 'function') {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
expect(
|
|
26
|
+
fn({
|
|
27
|
+
value: 'x',
|
|
28
|
+
colDef: { colId: 'col1' },
|
|
29
|
+
node: undefined!,
|
|
30
|
+
data: undefined!,
|
|
31
|
+
column: undefined!,
|
|
32
|
+
api: undefined!,
|
|
33
|
+
context: undefined,
|
|
34
|
+
}),
|
|
35
|
+
).toBe('x');
|
|
34
36
|
});
|
|
35
37
|
});
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
ColDef,
|
|
3
|
+
EditableCallback,
|
|
4
|
+
GetQuickFilterTextParams,
|
|
5
|
+
ICellEditorParams,
|
|
6
|
+
ICellRendererParams,
|
|
7
|
+
} from 'ag-grid-community';
|
|
2
8
|
import {
|
|
3
9
|
SuppressKeyboardEventParams,
|
|
4
10
|
ValueFormatterFunc,
|
|
5
11
|
ValueFormatterParams,
|
|
6
12
|
ValueGetterFunc,
|
|
7
|
-
ValueGetterParams,
|
|
8
13
|
} from 'ag-grid-community';
|
|
9
14
|
import { forwardRef, ReactElement, useContext } from 'react';
|
|
10
15
|
|
|
@@ -32,8 +37,12 @@ export const GridCellRenderer = (props: ICellRendererParams) => {
|
|
|
32
37
|
let warningText = props.data !== undefined && warningFn ? warningFn(props) : undefined;
|
|
33
38
|
const infoFn = rendererParams?.info;
|
|
34
39
|
let infoText = props.data !== undefined && infoFn ? infoFn(props) : undefined;
|
|
35
|
-
if (Array.isArray(warningText))
|
|
36
|
-
|
|
40
|
+
if (Array.isArray(warningText)) {
|
|
41
|
+
warningText = warningText.join('\n');
|
|
42
|
+
}
|
|
43
|
+
if (Array.isArray(infoText)) {
|
|
44
|
+
infoText = infoText.join('\n');
|
|
45
|
+
}
|
|
37
46
|
|
|
38
47
|
return checkUpdating(colDef.field ?? colDef.colId ?? '', props.data.id) ? (
|
|
39
48
|
<GridLoadableCell />
|
|
@@ -47,7 +56,7 @@ export const GridCellRenderer = (props: ICellRendererParams) => {
|
|
|
47
56
|
{colDef.cellRendererParams?.originalCellRenderer ? (
|
|
48
57
|
<colDef.cellRendererParams.originalCellRenderer {...props} />
|
|
49
58
|
) : (
|
|
50
|
-
<span title={props.valueFormatted ?? undefined}>{props.valueFormatted}</span>
|
|
59
|
+
<span title={props.valueFormatted ?? undefined}>{props.valueFormatted || '–'}</span>
|
|
51
60
|
)}
|
|
52
61
|
</div>
|
|
53
62
|
{fnOrVar(colDef.editable, props) && rendererParams?.rightHoverElement && (
|
|
@@ -91,25 +100,24 @@ export const suppressCellKeyboardEvents = (e: SuppressKeyboardEventParams) => {
|
|
|
91
100
|
};
|
|
92
101
|
|
|
93
102
|
export const generateFilterGetter = <TData extends GridBaseRow, ValueType>(
|
|
94
|
-
field: string | undefined,
|
|
95
|
-
filterValueGetter: string | ValueGetterFunc<TData, ValueType> | undefined,
|
|
96
103
|
valueFormatter: string | ValueFormatterFunc<TData, ValueType> | undefined,
|
|
97
|
-
): string |
|
|
98
|
-
if (filterValueGetter) return filterValueGetter;
|
|
104
|
+
): string | ((params: GetQuickFilterTextParams<TData, ValueType>) => string) | undefined => {
|
|
99
105
|
// aggrid will default to valueGetter
|
|
100
|
-
if (typeof valueFormatter !== 'function'
|
|
106
|
+
if (typeof valueFormatter !== 'function') {
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
101
109
|
|
|
102
|
-
return (params:
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
110
|
+
return (params: GetQuickFilterTextParams<TData, ValueType>) => valueFormatter(params);
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const stringableValueFormatterTypes = ['number', 'boolean', 'string'];
|
|
114
|
+
export const defaultValueFormatter = ({ value }: ValueFormatterParams) => {
|
|
115
|
+
if (value == null) {
|
|
116
|
+
return '–';
|
|
117
|
+
}
|
|
118
|
+
return stringableValueFormatterTypes.includes(typeof value) //
|
|
119
|
+
? String(value)
|
|
120
|
+
: JSON.stringify(value);
|
|
113
121
|
};
|
|
114
122
|
|
|
115
123
|
/*
|
|
@@ -128,17 +136,18 @@ export const GridCell = <TData extends GridBaseRow, TValue = any, Props extends
|
|
|
128
136
|
// Generate a default filter value getter which uses the formatted value plus
|
|
129
137
|
// the editable value if it's a string and different from the formatted value.
|
|
130
138
|
// This is so that e.g. bearings can be searched for by DMS or raw number.
|
|
131
|
-
const valueFormatter = props.valueFormatter;
|
|
139
|
+
const valueFormatter = props.valueFormatter ?? defaultValueFormatter;
|
|
132
140
|
// FIXME
|
|
133
|
-
const filterValueGetter =
|
|
141
|
+
const filterValueGetter = props.filterValueGetter ?? generateFilterGetter(valueFormatter as any);
|
|
134
142
|
const exportable = props.exportable;
|
|
135
143
|
// Can't leave this here ag-grid will complain
|
|
136
144
|
delete props.exportable;
|
|
137
145
|
|
|
138
146
|
return {
|
|
139
|
-
|
|
147
|
+
// Will be overridden if specified later
|
|
148
|
+
colId: props.field,
|
|
140
149
|
headerTooltip: props.headerName,
|
|
141
|
-
sortable:
|
|
150
|
+
sortable: true,
|
|
142
151
|
resizable: true,
|
|
143
152
|
editable: props.editable ?? false,
|
|
144
153
|
...(custom?.editor && {
|
|
@@ -155,15 +164,9 @@ export const GridCell = <TData extends GridBaseRow, TValue = any, Props extends
|
|
|
155
164
|
},
|
|
156
165
|
}),
|
|
157
166
|
// If there's a valueFormatter and no filterValueGetter then create a filterValueGetter
|
|
158
|
-
|
|
159
|
-
filterValueGetter: filterValueGetter as any,
|
|
167
|
+
getQuickFilterText: filterValueGetter as any,
|
|
160
168
|
// Default value formatter, otherwise react freaks out on objects
|
|
161
|
-
valueFormatter
|
|
162
|
-
if (params.value == null) return '–';
|
|
163
|
-
const types = ['number', 'boolean', 'string'];
|
|
164
|
-
if (types.includes(typeof params.value)) return `${params.value}`;
|
|
165
|
-
else return JSON.stringify(params.value);
|
|
166
|
-
},
|
|
169
|
+
valueFormatter,
|
|
167
170
|
...props,
|
|
168
171
|
cellRenderer: typeof props.cellRenderer === 'string' ? props.cellRenderer : GridCellRenderer,
|
|
169
172
|
cellRendererParams: {
|