mig-schema-table 1.0.12 → 2.0.1
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/component/SchemaTable/Th/index.d.ts +5 -2
- package/dist/component/SchemaTable/Th/index.js +7 -3
- package/dist/component/SchemaTable/constants.d.ts +1 -0
- package/dist/component/SchemaTable/constants.js +1 -0
- package/dist/component/SchemaTable/index.d.ts +3 -1
- package/dist/component/SchemaTable/index.js +55 -17
- package/dist/index.css +13 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -34,7 +34,7 @@ const userSchema ={
|
|
|
34
34
|
```
|
|
35
35
|
```typescript jsx
|
|
36
36
|
import React from 'react';
|
|
37
|
-
import {
|
|
37
|
+
import { SchemaTable, IColumnConfig } from "mig-schema-table";
|
|
38
38
|
import "mig-schema-table/dist/index.css";
|
|
39
39
|
|
|
40
40
|
const config:{[keyName: string]: IColumnConfig} ={
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { oas31 } from "openapi3-ts";
|
|
2
|
-
import { CSSProperties, Dispatch, SetStateAction } from "react";
|
|
2
|
+
import React, { CSSProperties, Dispatch, SetStateAction } from "react";
|
|
3
3
|
import { IColumnConfig } from "../../../types/type";
|
|
4
4
|
interface IThProps {
|
|
5
5
|
columnFilters?: {
|
|
@@ -16,6 +16,9 @@ interface IThProps {
|
|
|
16
16
|
setSortColumn: Dispatch<SetStateAction<string>>;
|
|
17
17
|
sortAsc?: boolean;
|
|
18
18
|
style: CSSProperties;
|
|
19
|
+
onSelectAllIndexesHandler?: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
|
20
|
+
isAllChecked?: boolean;
|
|
21
|
+
numberOfSelectedRows?: number;
|
|
19
22
|
}
|
|
20
|
-
declare const _default: ({ columnFilters, config, isSortable, name, schema, setColumnFilters, setSortAsc, setSortColumn, sortAsc, style, }: IThProps) => import("react/jsx-runtime").JSX.Element;
|
|
23
|
+
declare const _default: ({ columnFilters, config, isSortable, name, schema, setColumnFilters, setSortAsc, setSortColumn, sortAsc, style, onSelectAllIndexesHandler, isAllChecked, numberOfSelectedRows, }: IThProps) => import("react/jsx-runtime").JSX.Element;
|
|
21
24
|
export default _default;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import { uncamel } from "../../../inc/string";
|
|
4
|
-
|
|
4
|
+
import { SELECT_ALL_COLUMN_NAME } from "../constants";
|
|
5
|
+
const Th = ({ columnFilters, config, isSortable, name, schema, setColumnFilters, setSortAsc, setSortColumn, sortAsc, style, onSelectAllIndexesHandler, isAllChecked, numberOfSelectedRows, }) => {
|
|
5
6
|
const thDivProps = {
|
|
6
7
|
style,
|
|
7
8
|
className: `schema-table__th ${isSortable ? "schema-table__th--sortable" : "schema-table__th--unsortable"}`,
|
|
8
9
|
};
|
|
9
|
-
const onFilterButtonClick = React.useCallback((
|
|
10
|
+
const onFilterButtonClick = React.useCallback(() => {
|
|
10
11
|
if (!setColumnFilters) {
|
|
11
12
|
return;
|
|
12
13
|
}
|
|
@@ -23,6 +24,9 @@ const Th = ({ columnFilters, config, isSortable, name, schema, setColumnFilters,
|
|
|
23
24
|
}
|
|
24
25
|
setSortAsc((sortAsc) => !sortAsc);
|
|
25
26
|
}, [config === null || config === void 0 ? void 0 : config.defaultSortDesc, name, setSortAsc, setSortColumn, sortAsc]);
|
|
27
|
+
if (name === SELECT_ALL_COLUMN_NAME) {
|
|
28
|
+
return (_jsx("div", Object.assign({}, thDivProps, { children: _jsx("div", Object.assign({ style: { marginTop: 12 }, title: `${numberOfSelectedRows || 0} selected` }, { children: _jsx("input", { type: "checkbox", checked: isAllChecked, onChange: onSelectAllIndexesHandler }) })) })));
|
|
29
|
+
}
|
|
26
30
|
if (!schema) {
|
|
27
31
|
return _jsx("div", Object.assign({}, thDivProps));
|
|
28
32
|
}
|
|
@@ -39,6 +43,6 @@ const Th = ({ columnFilters, config, isSortable, name, schema, setColumnFilters,
|
|
|
39
43
|
thDivProps.className += ` text-${(config === null || config === void 0 ? void 0 : config.align) || "end"}`;
|
|
40
44
|
}
|
|
41
45
|
}
|
|
42
|
-
return (_jsxs("div", Object.assign({}, thDivProps, { children: [isSortable ? (_jsxs("button", Object.assign({ className: "px-0", disabled: (config === null || config === void 0 ? void 0 : config.sortable) === false, onClick: onSortButtonClick }, { children: [(config === null || config === void 0 ? void 0 : config.title)
|
|
46
|
+
return (_jsxs("div", Object.assign({}, thDivProps, { children: [isSortable ? (_jsxs("button", Object.assign({ className: "px-0", disabled: (config === null || config === void 0 ? void 0 : config.sortable) === false, onClick: onSortButtonClick }, { children: [(config === null || config === void 0 ? void 0 : config.title) === undefined ? uncamel(name) : config === null || config === void 0 ? void 0 : config.title, sortAsc === undefined ? null : sortAsc ? "▲" : "▼"] }))) : (_jsx("div", Object.assign({ style: { lineHeight: "44px" } }, { children: (config === null || config === void 0 ? void 0 : config.title) === undefined ? uncamel(name) : config === null || config === void 0 ? void 0 : config.title }))), (config === null || config === void 0 ? void 0 : config.isFilterable) ? (_jsx("button", Object.assign({ onClick: onFilterButtonClick }, { children: _jsx("svg", Object.assign({ viewBox: "0 0 36 36", xmlns: "http://www.w3.org/2000/svg", height: 16, width: 16, style: { display: "block" } }, { children: _jsx("polygon", { fill: "#231F20", points: "14,30 22,25 22,17 35.999,0 17.988,0 0,0 14,17 " }) })) }))) : null] })));
|
|
43
47
|
};
|
|
44
48
|
export default React.memo(Th);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const SELECT_ALL_COLUMN_NAME = "SELECT_ALL_COLUMN_NAME";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const SELECT_ALL_COLUMN_NAME = "SELECT_ALL_COLUMN_NAME";
|
|
@@ -22,5 +22,7 @@ export interface ISchemaTableComponentProps<T> {
|
|
|
22
22
|
customElement?: React.ReactNode;
|
|
23
23
|
tableTitle?: string;
|
|
24
24
|
searchPlaceholder?: string;
|
|
25
|
+
onCheckedIndexesChange?: (rowIndex: number[]) => void;
|
|
26
|
+
checkedIndexes?: number[];
|
|
25
27
|
}
|
|
26
|
-
export default function
|
|
28
|
+
export default function SchemaTable<T>(props: ISchemaTableComponentProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -4,8 +4,9 @@ import { VariableSizeList, VariableSizeGrid } from "react-window";
|
|
|
4
4
|
import { localeFormat } from "../../inc/date";
|
|
5
5
|
import { uncamel } from "../../inc/string";
|
|
6
6
|
import Th from "./Th";
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
import { SELECT_ALL_COLUMN_NAME } from "./constants";
|
|
8
|
+
export default function SchemaTable(props) {
|
|
9
|
+
const { config, data, defaultSortColumn, defaultSortAsc = false, Heading = VariableSizeList, isSearchable, isSortable, onRowClick, getRowClassName, getRowSelected, rowHeight = 36, schema, style, customElement, tableTitle, searchPlaceholder, onCheckedIndexesChange, checkedIndexes, } = props;
|
|
9
10
|
const [sortColumn, setSortColumn] = React.useState(defaultSortColumn);
|
|
10
11
|
const [sortAsc, setSortAsc] = React.useState(defaultSortAsc);
|
|
11
12
|
const [searchQuery, setSearchQuery] = React.useState("");
|
|
@@ -13,6 +14,9 @@ export default function SchemaTableComponent(props) {
|
|
|
13
14
|
const { properties = {} } = schema;
|
|
14
15
|
const columnNames = React.useMemo(() => {
|
|
15
16
|
const columns = Object.keys(properties);
|
|
17
|
+
if (onCheckedIndexesChange) {
|
|
18
|
+
columns.unshift(SELECT_ALL_COLUMN_NAME);
|
|
19
|
+
}
|
|
16
20
|
if (!config) {
|
|
17
21
|
return columns;
|
|
18
22
|
}
|
|
@@ -33,6 +37,10 @@ export default function SchemaTableComponent(props) {
|
|
|
33
37
|
if (orderB === undefined) {
|
|
34
38
|
orderB = Object.keys(properties).findIndex((propName) => propName === columnB);
|
|
35
39
|
}
|
|
40
|
+
if (columnB === SELECT_ALL_COLUMN_NAME ||
|
|
41
|
+
columnA === SELECT_ALL_COLUMN_NAME) {
|
|
42
|
+
return 0;
|
|
43
|
+
}
|
|
36
44
|
if (orderA === -1) {
|
|
37
45
|
return 1;
|
|
38
46
|
}
|
|
@@ -41,7 +49,7 @@ export default function SchemaTableComponent(props) {
|
|
|
41
49
|
}
|
|
42
50
|
return orderA - orderB;
|
|
43
51
|
});
|
|
44
|
-
}, [config, properties]);
|
|
52
|
+
}, [config, onCheckedIndexesChange, properties]);
|
|
45
53
|
const renderData = React.useMemo(() => data
|
|
46
54
|
? data.map((object, rowIndex) => columnNames.reduce((prev, propName) => {
|
|
47
55
|
const schema = properties[propName];
|
|
@@ -50,6 +58,10 @@ export default function SchemaTableComponent(props) {
|
|
|
50
58
|
prev[propName] = propConfig.renderData(object, rowIndex);
|
|
51
59
|
return prev;
|
|
52
60
|
}
|
|
61
|
+
if (propName === SELECT_ALL_COLUMN_NAME) {
|
|
62
|
+
prev[propName] = "asd";
|
|
63
|
+
return prev;
|
|
64
|
+
}
|
|
53
65
|
if (!schema) {
|
|
54
66
|
prev[propName] = "?";
|
|
55
67
|
return prev;
|
|
@@ -81,7 +93,7 @@ export default function SchemaTableComponent(props) {
|
|
|
81
93
|
return prev;
|
|
82
94
|
}
|
|
83
95
|
if (schema.enum) {
|
|
84
|
-
prev[propName] = rawValue ? uncamel(rawValue) :
|
|
96
|
+
prev[propName] = rawValue ? uncamel(rawValue) : "";
|
|
85
97
|
return prev;
|
|
86
98
|
}
|
|
87
99
|
// fallthrough
|
|
@@ -108,23 +120,14 @@ export default function SchemaTableComponent(props) {
|
|
|
108
120
|
const dynamicColumnWidth = Math.floor((gridWidth - 16 - fixedWidthColumnsWidth) / dynamicWidthColumnCount);
|
|
109
121
|
const columnWidths = columnNames.map((propName) => {
|
|
110
122
|
const propConfig = config ? config[propName] : undefined;
|
|
123
|
+
if (propName === SELECT_ALL_COLUMN_NAME) {
|
|
124
|
+
return 50;
|
|
125
|
+
}
|
|
111
126
|
return (propConfig === null || propConfig === void 0 ? void 0 : propConfig.width) || dynamicColumnWidth;
|
|
112
127
|
});
|
|
113
128
|
return { columnWidths, dynamicWidthColumnCount, fixedWidthColumnsWidth };
|
|
114
129
|
}, [columnNames, config, gridWidth]);
|
|
115
130
|
const getColumnWidth = React.useCallback((columnIndex) => columnWidths[columnIndex], [columnWidths]);
|
|
116
|
-
const SchemaTableTh = React.useCallback(({ style, index }) => {
|
|
117
|
-
const propName = columnNames[index];
|
|
118
|
-
return (_jsx(Th, { columnFilters: columnFilters, config: config ? config[propName] : undefined, isSortable: !!isSortable, name: propName, schema: properties[propName], setColumnFilters: setColumnFilters, setSortColumn: setSortColumn, setSortAsc: setSortAsc, sortAsc: sortColumn === propName ? sortAsc : undefined, style: style }));
|
|
119
|
-
}, [
|
|
120
|
-
columnFilters,
|
|
121
|
-
columnNames,
|
|
122
|
-
config,
|
|
123
|
-
isSortable,
|
|
124
|
-
properties,
|
|
125
|
-
sortAsc,
|
|
126
|
-
sortColumn,
|
|
127
|
-
]);
|
|
128
131
|
const filteredRenderData = React.useMemo(() => {
|
|
129
132
|
let result = renderData;
|
|
130
133
|
if (!result) {
|
|
@@ -188,6 +191,30 @@ export default function SchemaTableComponent(props) {
|
|
|
188
191
|
return (x < y ? 1 : -1) * (sortAsc ? -1 : 1);
|
|
189
192
|
});
|
|
190
193
|
}, [config, data, filteredRenderData, properties, sortAsc, sortColumn]);
|
|
194
|
+
const onSelectAllIndexesHandler = React.useCallback(() => {
|
|
195
|
+
if (!onCheckedIndexesChange || !filteredRenderData) {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
onCheckedIndexesChange(filteredRenderData.map((el) => el._index));
|
|
199
|
+
}, [onCheckedIndexesChange, filteredRenderData]);
|
|
200
|
+
const isAllRowsChecked = React.useMemo(() => {
|
|
201
|
+
return (checkedIndexes === null || checkedIndexes === void 0 ? void 0 : checkedIndexes.length) === (filteredRenderData === null || filteredRenderData === void 0 ? void 0 : filteredRenderData.length);
|
|
202
|
+
}, [checkedIndexes, filteredRenderData]);
|
|
203
|
+
const SchemaTableTh = React.useCallback(({ style, index }) => {
|
|
204
|
+
const propName = columnNames[index];
|
|
205
|
+
return (_jsx(Th, { columnFilters: columnFilters, config: config ? config[propName] : undefined, isSortable: !!isSortable, name: propName, schema: properties[propName], setColumnFilters: setColumnFilters, setSortColumn: setSortColumn, setSortAsc: setSortAsc, sortAsc: sortColumn === propName ? sortAsc : undefined, style: style, onSelectAllIndexesHandler: onSelectAllIndexesHandler, isAllChecked: isAllRowsChecked, numberOfSelectedRows: checkedIndexes === null || checkedIndexes === void 0 ? void 0 : checkedIndexes.length }));
|
|
206
|
+
}, [
|
|
207
|
+
columnNames,
|
|
208
|
+
columnFilters,
|
|
209
|
+
config,
|
|
210
|
+
isSortable,
|
|
211
|
+
properties,
|
|
212
|
+
sortColumn,
|
|
213
|
+
sortAsc,
|
|
214
|
+
onSelectAllIndexesHandler,
|
|
215
|
+
isAllRowsChecked,
|
|
216
|
+
checkedIndexes === null || checkedIndexes === void 0 ? void 0 : checkedIndexes.length,
|
|
217
|
+
]);
|
|
191
218
|
const onTdClick = React.useCallback((e) => {
|
|
192
219
|
if (!sortedRenderData || !onRowClick) {
|
|
193
220
|
return;
|
|
@@ -222,6 +249,15 @@ export default function SchemaTableComponent(props) {
|
|
|
222
249
|
if (propConfig === null || propConfig === void 0 ? void 0 : propConfig.renderCell) {
|
|
223
250
|
return (_jsx("div", Object.assign({}, tdDivProps, { children: propConfig.renderCell(data[row._index], rowIndex) })));
|
|
224
251
|
}
|
|
252
|
+
if (propName === SELECT_ALL_COLUMN_NAME) {
|
|
253
|
+
const onChecked = () => {
|
|
254
|
+
if (!onCheckedIndexesChange) {
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
onCheckedIndexesChange([rowIndex]);
|
|
258
|
+
};
|
|
259
|
+
return (_jsx("div", Object.assign({}, tdDivProps, { children: _jsx("div", Object.assign({ style: { marginLeft: 8 } }, { children: _jsx("input", { type: "checkbox", onChange: onChecked, checked: checkedIndexes === null || checkedIndexes === void 0 ? void 0 : checkedIndexes.includes(rowIndex) }) })) })));
|
|
260
|
+
}
|
|
225
261
|
if (!schema) {
|
|
226
262
|
return null;
|
|
227
263
|
}
|
|
@@ -251,6 +287,8 @@ export default function SchemaTableComponent(props) {
|
|
|
251
287
|
getRowSelected,
|
|
252
288
|
data,
|
|
253
289
|
getRowClassName,
|
|
290
|
+
checkedIndexes,
|
|
291
|
+
onCheckedIndexesChange,
|
|
254
292
|
]);
|
|
255
293
|
const onSearchChange = React.useCallback((e) => {
|
|
256
294
|
setSearchQuery(e.currentTarget.value);
|
|
@@ -260,5 +298,5 @@ export default function SchemaTableComponent(props) {
|
|
|
260
298
|
const totalWidth = React.useMemo(() => columnWidths.reduce((a, b) => {
|
|
261
299
|
return a + b;
|
|
262
300
|
}, 0), [columnWidths]);
|
|
263
|
-
return (_jsxs("div", Object.assign({ className: `schema-table${onRowClick ? " schema-table--clickable-rows" : ""}`, style: Object.assign(Object.assign({}, style), { width: dynamicWidthColumnCount ? gridWidth : fixedWidthColumnsWidth }) }, { children: [_jsx("div", Object.assign({ className: "tableTitle" }, { children: tableTitle })), _jsxs("div", Object.assign({ className: "
|
|
301
|
+
return (_jsxs("div", Object.assign({ className: `schema-table${onRowClick ? " schema-table--clickable-rows" : ""}`, style: Object.assign(Object.assign({}, style), { width: dynamicWidthColumnCount ? gridWidth : fixedWidthColumnsWidth }) }, { children: [_jsx("div", Object.assign({ className: "tableTitle" }, { children: tableTitle })), _jsxs("div", Object.assign({ className: "action-container" }, { children: [_jsx("div", Object.assign({ style: { flex: 1 } }, { children: isSearchable ? (_jsx("input", { id: "input-filter", type: "text", placeholder: searchPlaceholder || "Search...", value: searchQuery, onChange: onSearchChange, autoFocus: true })) : null })), customElement] })), _jsx(Heading, Object.assign({ height: 50, itemCount: columnCount, itemSize: getColumnWidth, layout: "horizontal", width: width, sortAsc: sortAsc, setSortAsc: setSortAsc, setSortColumn: setSortColumn, sortColumn: sortColumn, sortedRenderData: sortedRenderData, className: "schema-table__th-row" }, { children: SchemaTableTh }), `thead_${width}_${sortColumn}_${sortAsc}_${searchQuery}`), _jsx(VariableSizeGrid, Object.assign({ className: "schema-table__tbody", height: props.height - (isSearchable ? 50 : 0), width: totalWidth, columnWidth: getColumnWidth, rowHeight: getRowHeight, columnCount: columnCount, rowCount: sortedRenderData ? sortedRenderData.length : 0 }, { children: Td }), `tbody_${width}_${sortColumn}_${sortAsc}_${searchQuery}_${columnCount}`)] })));
|
|
264
302
|
}
|
package/dist/index.css
CHANGED
|
@@ -54,3 +54,16 @@
|
|
|
54
54
|
.schema-table button {
|
|
55
55
|
border: 1px solid transparent;
|
|
56
56
|
}
|
|
57
|
+
.schema-table .action-container {
|
|
58
|
+
display: flex;
|
|
59
|
+
flex-direction: row;
|
|
60
|
+
}
|
|
61
|
+
.schema-table .action-container #input-filter {
|
|
62
|
+
width: 30%;
|
|
63
|
+
border-radius: 8px;
|
|
64
|
+
padding: 4px 10px;
|
|
65
|
+
}
|
|
66
|
+
.schema-table .action-container img {
|
|
67
|
+
margin-right: 1.5rem;
|
|
68
|
+
margin-top: 5px;
|
|
69
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import SchemaTable from "./component/SchemaTable";
|
|
2
2
|
import { IColumnConfig, IRenderData } from "./types/type";
|
|
3
3
|
export type { IColumnConfig, IRenderData };
|
|
4
|
-
export {
|
|
4
|
+
export { SchemaTable };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
export {
|
|
1
|
+
import SchemaTable from "./component/SchemaTable";
|
|
2
|
+
export { SchemaTable };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mig-schema-table",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist/"
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"lodash": "^4.17.21",
|
|
21
21
|
"openapi-typescript": "^6.2.4",
|
|
22
22
|
"openapi3-ts": "^4.1.2",
|
|
23
|
+
"prettier": "^2.8.8",
|
|
23
24
|
"react": "^18.2.0",
|
|
24
25
|
"react-dom": "^18.2.0",
|
|
25
26
|
"react-scripts": "5.0.1",
|