mig-schema-table 3.0.24 → 3.0.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/SchemaTable/ColumnFilterRow/index.d.ts +3 -7
- package/dist/SchemaTable/ColumnFilterRow/index.js +15 -66
- package/dist/SchemaTable/SchemaColumnFilterPopover/FilterFormComponent/index.d.ts +11 -0
- package/dist/SchemaTable/SchemaColumnFilterPopover/FilterFormComponent/index.js +76 -0
- package/dist/SchemaTable/SchemaColumnFilterPopover/index.d.ts +19 -0
- package/dist/SchemaTable/SchemaColumnFilterPopover/index.js +53 -0
- package/dist/SchemaTable/Th/index.d.ts +11 -5
- package/dist/SchemaTable/Th/index.js +46 -12
- package/dist/SchemaTable/index.d.ts +7 -5
- package/dist/SchemaTable/index.js +86 -68
- package/dist/SchemaTable/index.test.d.ts +1 -0
- package/dist/SchemaTable/index.test.js +18 -0
- package/dist/inc/date.d.ts +0 -1
- package/dist/inc/date.js +0 -4
- package/dist/index.css +40 -0
- package/package.json +6 -3
|
@@ -1,21 +1,17 @@
|
|
|
1
|
-
import { Dispatch, SetStateAction } from "react";
|
|
2
1
|
import { IColumnConfig } from "../../types";
|
|
3
2
|
import { oas31 } from "openapi3-ts";
|
|
4
3
|
import "react-datepicker/dist/react-datepicker.css";
|
|
5
|
-
import { tColumnSearchValue } from "../index";
|
|
6
4
|
interface IColumnFilterRowProps {
|
|
7
5
|
columnNames: string[];
|
|
8
6
|
getWidth: (index: number) => number;
|
|
9
7
|
config?: {
|
|
10
8
|
[propName: string]: IColumnConfig<any>;
|
|
11
9
|
};
|
|
12
|
-
columnSearchHandler: (propName: string, value:
|
|
10
|
+
columnSearchHandler: (propName: string, value: string | number | boolean) => void;
|
|
13
11
|
value: {
|
|
14
|
-
[propName: string]:
|
|
12
|
+
[propName: string]: string | number | boolean;
|
|
15
13
|
};
|
|
16
14
|
schema: oas31.SchemaObject;
|
|
17
|
-
columnFilterDropdown?: string;
|
|
18
|
-
setColumnFilterDropdown?: Dispatch<SetStateAction<string | undefined>>;
|
|
19
15
|
}
|
|
20
|
-
export default function ColumnFilterRow({ columnNames, getWidth, config, value, columnSearchHandler, schema,
|
|
16
|
+
export default function ColumnFilterRow({ columnNames, getWidth, config, value, columnSearchHandler, schema, }: IColumnFilterRowProps): import("react/jsx-runtime").JSX.Element;
|
|
21
17
|
export {};
|
|
@@ -4,15 +4,15 @@ import { SELECT_ALL_COLUMN_NAME } from "../constants";
|
|
|
4
4
|
import DatePicker from "react-datepicker";
|
|
5
5
|
import nl from "date-fns/locale/nl";
|
|
6
6
|
import "react-datepicker/dist/react-datepicker.css";
|
|
7
|
+
import { localeFormat } from "../../inc/date";
|
|
7
8
|
import { DEFAULT_DATE_FORMAT, DEFAULT_DATE_TIME_FORMAT, } from "../../inc/constant";
|
|
8
|
-
|
|
9
|
-
export default function ColumnFilterRow({ columnNames, getWidth, config, value, columnSearchHandler, schema, columnFilterDropdown, setColumnFilterDropdown, }) {
|
|
9
|
+
export default function ColumnFilterRow({ columnNames, getWidth, config, value, columnSearchHandler, schema, }) {
|
|
10
10
|
const { properties = {} } = schema;
|
|
11
11
|
const getSelectComponent = React.useCallback((propSchema, propName, value, inputChangeHandler) => {
|
|
12
|
-
const enumItems = propSchema.type === "boolean" ? ["
|
|
12
|
+
const enumItems = propSchema.type === "boolean" ? ["true", "false"] : propSchema.enum;
|
|
13
13
|
return (_jsxs("select", Object.assign({ value: value, "data-prop-name": propName, onChange: inputChangeHandler }, { children: [_jsx("option", Object.assign({ value: "" }, { children: "All" }), "all"), enumItems.map((name) => (_jsx("option", Object.assign({ value: name }, { children: name }), `column-filter-select-${name}`)))] })));
|
|
14
14
|
}, []);
|
|
15
|
-
const field = React.useCallback((propSchema, propName, propValue) => {
|
|
15
|
+
const field = React.useCallback((propSchema, propName, propValue, propConfig) => {
|
|
16
16
|
const { type, format, minimum, maximum } = propSchema;
|
|
17
17
|
const inputChangeHandler = (event) => {
|
|
18
18
|
columnSearchHandler(propName, event.target.value);
|
|
@@ -24,69 +24,24 @@ export default function ColumnFilterRow({ columnNames, getWidth, config, value,
|
|
|
24
24
|
return getSelectComponent(propSchema, propName, strValue, inputChangeHandler);
|
|
25
25
|
}
|
|
26
26
|
if (format === "date-time" || format === "date") {
|
|
27
|
-
const dateFormat =
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
?
|
|
33
|
-
: null;
|
|
34
|
-
const endDate = (dateRangeValue === null || dateRangeValue === void 0 ? void 0 : dateRangeValue.to)
|
|
35
|
-
? new Date(dateRangeValue.to)
|
|
36
|
-
: null;
|
|
37
|
-
const startDateChangeHandler = (date) => {
|
|
38
|
-
if (endDate && date && date > endDate) {
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
columnSearchHandler(propName, Object.assign(Object.assign({}, dateRangeValue), { from: `${date || ""}`, to: `${date && endDate ? dateRangeValue.to : ""}` }));
|
|
27
|
+
const dateFormat = (propConfig === null || propConfig === void 0 ? void 0 : propConfig.dateFormat) ||
|
|
28
|
+
(format === "date"
|
|
29
|
+
? DEFAULT_DATE_FORMAT
|
|
30
|
+
: DEFAULT_DATE_TIME_FORMAT);
|
|
31
|
+
const dateChangeHandler = (date) => {
|
|
32
|
+
columnSearchHandler(propName, date ? localeFormat(date, dateFormat) : "");
|
|
42
33
|
};
|
|
43
|
-
|
|
44
|
-
if (startDate &&
|
|
45
|
-
date &&
|
|
46
|
-
getUnixTimeStamp(`${date}`) < getUnixTimeStamp(`${startDate}`)) {
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
columnSearchHandler(propName, Object.assign(Object.assign({}, dateRangeValue), { to: `${date || ""}` }));
|
|
50
|
-
};
|
|
51
|
-
return (_jsx("div", Object.assign({ "data-bs-toggle": "dropdown-menu-item" }, { children: _jsxs("div", Object.assign({ className: "d-flex p-2" }, { children: [_jsxs("div", Object.assign({ className: "d-flex flex-column m-1" }, { children: [_jsx("label", { children: "Start date-time" }), _jsx(DatePicker, { id: "filter-date", dateFormat: dateFormat, "data-prop-name": propName, locale: nl, selected: startDate, onChange: startDateChangeHandler, placeholderText: dateFormat, isClearable: true, selectsStart: true, startDate: startDate, endDate: endDate, showTimeSelect: format === "date-time", timeIntervals: 15, shouldCloseOnSelect: format === "date" })] })), _jsxs("div", Object.assign({ className: "d-flex flex-column m-1" }, { children: [_jsx("label", { children: "End date-time" }), _jsx(DatePicker, { id: "filter-date", dateFormat: dateFormat, "data-prop-name": propName, locale: nl, selectsEnd: true, selected: endDate, onChange: endDateChangeHandler, placeholderText: dateFormat, isClearable: true, startDate: startDate, endDate: endDate, showTimeSelect: format === "date-time", timeIntervals: 15, shouldCloseOnSelect: format === "date" })] }))] })) })));
|
|
34
|
+
return (_jsx(DatePicker, { id: "filter-date", dateFormat: dateFormat, "data-prop-name": propName, showTimeSelect: format === "date-time", locale: nl, selected: propValue ? new Date(propValue) : null, onChange: dateChangeHandler, value: propValue || undefined, placeholderText: dateFormat, isClearable: true }));
|
|
52
35
|
}
|
|
53
|
-
return (_jsx("
|
|
36
|
+
return (_jsx("input", { value: strValue, "data-prop-name": propName, onChange: inputChangeHandler, placeholder: `Search ${propName}` }));
|
|
54
37
|
case "integer":
|
|
55
|
-
return (_jsx("
|
|
38
|
+
return (_jsx("input", { type: "number", value: strValue, "data-prop-name": propName, onChange: inputChangeHandler, placeholder: `Search ${propName}`, min: minimum, max: maximum }));
|
|
56
39
|
case "boolean":
|
|
57
40
|
return getSelectComponent(propSchema, propName, strValue, inputChangeHandler);
|
|
58
41
|
default:
|
|
59
42
|
return _jsx(_Fragment, {});
|
|
60
43
|
}
|
|
61
44
|
}, [columnSearchHandler, getSelectComponent]);
|
|
62
|
-
const removeDropdown = React.useCallback((e) => {
|
|
63
|
-
var _a;
|
|
64
|
-
if (!columnFilterDropdown || ((_a = e.target.dataset) === null || _a === void 0 ? void 0 : _a.bsToggle) === "dropdown") {
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
let columnFilterEl = null;
|
|
68
|
-
let parentNode = e.target;
|
|
69
|
-
while (parentNode && parentNode !== window.document) {
|
|
70
|
-
if (typeof parentNode.className === "string" &&
|
|
71
|
-
parentNode.className.includes("schema-table__column-filter")) {
|
|
72
|
-
columnFilterEl = parentNode;
|
|
73
|
-
break;
|
|
74
|
-
}
|
|
75
|
-
parentNode = parentNode.parentNode;
|
|
76
|
-
}
|
|
77
|
-
if (!columnFilterEl) {
|
|
78
|
-
setColumnFilterDropdown && setColumnFilterDropdown(undefined);
|
|
79
|
-
}
|
|
80
|
-
}, [columnFilterDropdown, setColumnFilterDropdown]);
|
|
81
|
-
React.useEffect(() => {
|
|
82
|
-
if (!columnFilterDropdown) {
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
window.addEventListener("click", removeDropdown, { capture: true });
|
|
86
|
-
return () => {
|
|
87
|
-
window.removeEventListener("click", removeDropdown, { capture: true });
|
|
88
|
-
};
|
|
89
|
-
}, [columnFilterDropdown, removeDropdown]);
|
|
90
45
|
const SchemaColumnFilter = React.useCallback((index) => {
|
|
91
46
|
const propName = columnNames[index];
|
|
92
47
|
const propSchema = properties[propName];
|
|
@@ -95,14 +50,8 @@ export default function ColumnFilterRow({ columnNames, getWidth, config, value,
|
|
|
95
50
|
if (propName === SELECT_ALL_COLUMN_NAME || !(propConfig === null || propConfig === void 0 ? void 0 : propConfig.isFilterable)) {
|
|
96
51
|
return _jsx("div", { className: "schema-table__th" });
|
|
97
52
|
}
|
|
98
|
-
return (_jsx("
|
|
99
|
-
|
|
100
|
-
: ""}`, style: {
|
|
101
|
-
position: "fixed",
|
|
102
|
-
marginTop: -10,
|
|
103
|
-
minHeight: 100,
|
|
104
|
-
} }, { children: _jsx("div", Object.assign({ id: "filter-dropdown-item", style: { margin: 10 } }, { children: field(propSchema, propName, propValue) })) })));
|
|
105
|
-
}, [columnFilterDropdown, columnNames, config, field, properties, value]);
|
|
53
|
+
return (_jsx("div", Object.assign({ className: "schema-table__th" }, { children: field(propSchema, propName, propValue, propConfig) }), `filter-col-${propName}`));
|
|
54
|
+
}, [columnNames, config, field, properties, value]);
|
|
106
55
|
return (_jsx("div", Object.assign({ className: "schema-table__th-row", style: { display: "flex", flex: "row" } }, { children: columnNames.map((columnName, index) => {
|
|
107
56
|
return (_jsx("div", Object.assign({ className: "schema-table__column-filter", style: {
|
|
108
57
|
width: getWidth(index),
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { oas31 } from "openapi3-ts";
|
|
3
|
+
import { TColumnFilterValue } from "../../index";
|
|
4
|
+
interface IFilterFormComponentProps {
|
|
5
|
+
onChange: (newValue?: TColumnFilterValue) => void;
|
|
6
|
+
propSchema: oas31.SchemaObject;
|
|
7
|
+
propName: string;
|
|
8
|
+
columnFilterValue: TColumnFilterValue;
|
|
9
|
+
}
|
|
10
|
+
declare const _default: React.MemoExoticComponent<({ onChange, propSchema, propName, columnFilterValue, }: IFilterFormComponentProps) => import("react/jsx-runtime").JSX.Element>;
|
|
11
|
+
export default _default;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { uncamel } from "../../../inc/string";
|
|
4
|
+
import { DEFAULT_DATE_FORMAT, DEFAULT_DATE_TIME_FORMAT, } from "../../../inc/constant";
|
|
5
|
+
import DatePicker from "react-datepicker";
|
|
6
|
+
import nl from "date-fns/locale/nl";
|
|
7
|
+
const FilterFormComponent = ({ onChange, propSchema, propName, columnFilterValue, }) => {
|
|
8
|
+
const { type, format, minimum, maximum } = propSchema;
|
|
9
|
+
const value = columnFilterValue;
|
|
10
|
+
switch (type) {
|
|
11
|
+
case "integer":
|
|
12
|
+
return (_jsx("div", Object.assign({ className: "d-flex p-1" }, { children: _jsx("input", { type: "number", value: (value || ""), "data-prop-name": propName, onChange: (e) => {
|
|
13
|
+
onChange(e.currentTarget.value === ""
|
|
14
|
+
? undefined
|
|
15
|
+
: parseInt(e.currentTarget.value));
|
|
16
|
+
}, placeholder: `Search ${propName}`, min: minimum, max: maximum }) })));
|
|
17
|
+
case "boolean":
|
|
18
|
+
let selectValue = value ? "✓" : "✕";
|
|
19
|
+
if (value === undefined) {
|
|
20
|
+
selectValue = "";
|
|
21
|
+
}
|
|
22
|
+
return (_jsxs("select", Object.assign({ value: selectValue, "data-prop-name": propName, onChange: (e) => {
|
|
23
|
+
switch (e.currentTarget.value) {
|
|
24
|
+
case "✓":
|
|
25
|
+
onChange(true);
|
|
26
|
+
break;
|
|
27
|
+
case "✕":
|
|
28
|
+
onChange(false);
|
|
29
|
+
break;
|
|
30
|
+
default:
|
|
31
|
+
onChange(undefined);
|
|
32
|
+
}
|
|
33
|
+
} }, { children: [_jsx("option", Object.assign({ value: "" }, { children: "All" }), "all"), ["✓", "✕"].map((optionValue) => (_jsx("option", Object.assign({ value: optionValue }, { children: optionValue }), `column-filter-select-${optionValue}`)))] })));
|
|
34
|
+
// @ts-ignore
|
|
35
|
+
case "string":
|
|
36
|
+
if (propSchema.enum) {
|
|
37
|
+
return (_jsxs("select", Object.assign({ value: value, "data-prop-name": propName, onChange: (e) => {
|
|
38
|
+
onChange(e.currentTarget.value || undefined);
|
|
39
|
+
} }, { children: [_jsx("option", Object.assign({ value: "" }, { children: "All" }), "all"), propSchema.enum.map((name) => (_jsx("option", Object.assign({ value: name }, { children: uncamel(name) }), `column-filter-select-${name}`)))] })));
|
|
40
|
+
}
|
|
41
|
+
if (format === "date-time" || format === "date") {
|
|
42
|
+
const dateFormat = format === "date" ? DEFAULT_DATE_FORMAT : DEFAULT_DATE_TIME_FORMAT;
|
|
43
|
+
const dateRangeValue = (columnFilterValue || {
|
|
44
|
+
from: undefined,
|
|
45
|
+
to: undefined,
|
|
46
|
+
});
|
|
47
|
+
const startDateChangeHandler = (date) => {
|
|
48
|
+
if (!date && !dateRangeValue.to) {
|
|
49
|
+
onChange(undefined);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (dateRangeValue.to && date && date > dateRangeValue.to) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
onChange(Object.assign(Object.assign({}, columnFilterValue), { from: date || undefined }));
|
|
56
|
+
};
|
|
57
|
+
const endDateChangeHandler = (date) => {
|
|
58
|
+
if (!date && !dateRangeValue.from) {
|
|
59
|
+
onChange(undefined);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (dateRangeValue.from && date && date < dateRangeValue.from) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
onChange(Object.assign(Object.assign({}, columnFilterValue), { to: date || undefined }));
|
|
66
|
+
};
|
|
67
|
+
return (_jsx("div", Object.assign({ "data-bs-toggle": "dropdown-menu-item" }, { children: _jsxs("div", Object.assign({ className: "d-flex p-2" }, { children: [_jsxs("div", Object.assign({ className: "d-flex flex-column m-1" }, { children: [_jsx("label", { children: "Start date-time" }), _jsx(DatePicker, { dateFormat: dateFormat, "data-prop-name": propName, locale: nl, selected: dateRangeValue.from, onChange: startDateChangeHandler, placeholderText: dateFormat, isClearable: true, selectsStart: true, showTimeSelect: format === "date-time", timeIntervals: 15, shouldCloseOnSelect: format === "date" })] })), _jsxs("div", Object.assign({ className: "d-flex flex-column m-1" }, { children: [_jsx("label", { children: "End date-time" }), _jsx(DatePicker, { id: "filter-date", dateFormat: dateFormat, "data-prop-name": propName, locale: nl, selectsEnd: true, selected: dateRangeValue.to, onChange: endDateChangeHandler, placeholderText: dateFormat, isClearable: true, startDate: dateRangeValue.from, endDate: dateRangeValue.to, showTimeSelect: format === "date-time", timeIntervals: 15, shouldCloseOnSelect: format === "date" })] }))] })) })));
|
|
68
|
+
}
|
|
69
|
+
// falls through
|
|
70
|
+
default:
|
|
71
|
+
return (_jsx("div", Object.assign({ className: "p-1" }, { children: _jsx("input", { autoFocus: true, value: (value || ""), "data-prop-name": propName, onChange: (e) => {
|
|
72
|
+
onChange(e.currentTarget.value || undefined);
|
|
73
|
+
}, placeholder: `Search ${propName}` }) })));
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
export default React.memo(FilterFormComponent);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { oas31 } from "openapi3-ts";
|
|
3
|
+
import { TColumnFilterValue } from "../index";
|
|
4
|
+
export interface ISchemaColumnFilterPopoverConfig {
|
|
5
|
+
anchorPoint: {
|
|
6
|
+
x: number;
|
|
7
|
+
y: number;
|
|
8
|
+
};
|
|
9
|
+
anchorPosition?: "bottomLeft" | "bottomRight" | "topLeft" | "topRight";
|
|
10
|
+
propName: string;
|
|
11
|
+
}
|
|
12
|
+
type TSchemaColumnFilterPopoverProps = ISchemaColumnFilterPopoverConfig & {
|
|
13
|
+
onChange: (newValue?: TColumnFilterValue) => void;
|
|
14
|
+
propSchema: oas31.SchemaObject;
|
|
15
|
+
value: TColumnFilterValue;
|
|
16
|
+
onClose: () => void;
|
|
17
|
+
};
|
|
18
|
+
declare const _default: React.MemoExoticComponent<(props: TSchemaColumnFilterPopoverProps) => import("react/jsx-runtime").JSX.Element>;
|
|
19
|
+
export default _default;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import FilterFormComponent from "./FilterFormComponent";
|
|
4
|
+
const SchemaColumnFilterPopover = (props) => {
|
|
5
|
+
const { anchorPoint, onClose, onChange, propName, propSchema, value } = props;
|
|
6
|
+
const [popoverEl, setPopoverEl] = React.useState();
|
|
7
|
+
const rect = React.useMemo(() => {
|
|
8
|
+
return popoverEl === null || popoverEl === void 0 ? void 0 : popoverEl.getBoundingClientRect();
|
|
9
|
+
}, [popoverEl]);
|
|
10
|
+
const ref = React.useCallback((el) => {
|
|
11
|
+
if (el) {
|
|
12
|
+
setPopoverEl(el);
|
|
13
|
+
}
|
|
14
|
+
}, []);
|
|
15
|
+
const style = React.useMemo(() => {
|
|
16
|
+
const result = {};
|
|
17
|
+
let anchorPosition = props.anchorPosition;
|
|
18
|
+
if (!anchorPosition) {
|
|
19
|
+
const anchorPositionVertical = anchorPoint.y > window.innerHeight / 2 ? "bottom" : "top";
|
|
20
|
+
const anchorPositionHorizontal = anchorPoint.x > window.innerWidth / 2 ? "Right" : "Left";
|
|
21
|
+
anchorPosition = `${anchorPositionVertical}${anchorPositionHorizontal}`;
|
|
22
|
+
}
|
|
23
|
+
switch (anchorPosition) {
|
|
24
|
+
case "bottomLeft":
|
|
25
|
+
result.left = (anchorPoint === null || anchorPoint === void 0 ? void 0 : anchorPoint.x) || 0;
|
|
26
|
+
result.top = rect ? ((anchorPoint === null || anchorPoint === void 0 ? void 0 : anchorPoint.y) || 0) - rect.height : 0;
|
|
27
|
+
break;
|
|
28
|
+
case "topLeft":
|
|
29
|
+
result.left = (anchorPoint === null || anchorPoint === void 0 ? void 0 : anchorPoint.x) || 0;
|
|
30
|
+
result.top = (anchorPoint === null || anchorPoint === void 0 ? void 0 : anchorPoint.y) || 0;
|
|
31
|
+
break;
|
|
32
|
+
case "bottomRight":
|
|
33
|
+
result.left = rect ? ((anchorPoint === null || anchorPoint === void 0 ? void 0 : anchorPoint.x) || 0) - rect.width : 0;
|
|
34
|
+
result.top = rect ? ((anchorPoint === null || anchorPoint === void 0 ? void 0 : anchorPoint.y) || 0) - rect.height : 0;
|
|
35
|
+
break;
|
|
36
|
+
case "topRight":
|
|
37
|
+
default:
|
|
38
|
+
result.left = rect ? ((anchorPoint === null || anchorPoint === void 0 ? void 0 : anchorPoint.x) || 0) - rect.width : 0;
|
|
39
|
+
result.top = anchorPoint === null || anchorPoint === void 0 ? void 0 : anchorPoint.y;
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
result.maxHeight = window.innerHeight - result.top - 10;
|
|
43
|
+
return result;
|
|
44
|
+
}, [anchorPoint.x, anchorPoint.y, props.anchorPosition, rect]);
|
|
45
|
+
const lightboxRef = React.useRef(null);
|
|
46
|
+
const onLightboxClick = React.useCallback((e) => {
|
|
47
|
+
if (e.target === lightboxRef.current) {
|
|
48
|
+
onClose();
|
|
49
|
+
}
|
|
50
|
+
}, [onClose]);
|
|
51
|
+
return (_jsx("div", Object.assign({ className: `lightbox lightbox--transparent schema-column-filter-popover schema-column-filter-popover__${propSchema.type}${propSchema.format ? `_${propSchema.format}` : ""}`, onClick: onLightboxClick, onContextMenu: onClose, ref: lightboxRef }, { children: _jsx("div", Object.assign({ className: "popover", ref: ref, style: style }, { children: _jsx(FilterFormComponent, { onChange: onChange, propSchema: propSchema, propName: propName, columnFilterValue: value }) })) })));
|
|
52
|
+
};
|
|
53
|
+
export default React.memo(SchemaColumnFilterPopover);
|
|
@@ -1,21 +1,27 @@
|
|
|
1
1
|
import { oas31 } from "openapi3-ts";
|
|
2
2
|
import React, { CSSProperties, Dispatch, SetStateAction } from "react";
|
|
3
3
|
import { IColumnConfig } from "../../types";
|
|
4
|
+
import { ISchemaColumnFilterPopoverConfig } from "../SchemaColumnFilterPopover";
|
|
5
|
+
export declare enum EColumnFilterStatus {
|
|
6
|
+
UNAVAILABLE = "UNAVAILABLE",
|
|
7
|
+
AVAILABLE = "AVAILABLE",
|
|
8
|
+
ACTIVE = "ACTIVE"
|
|
9
|
+
}
|
|
4
10
|
interface IThProps {
|
|
5
|
-
|
|
11
|
+
columnFilterStatus: EColumnFilterStatus;
|
|
12
|
+
disableColumnFilter: (propName: string) => void;
|
|
6
13
|
isAllChecked?: boolean;
|
|
7
|
-
isColumnSearchable?: boolean;
|
|
8
14
|
isSortable: boolean;
|
|
9
|
-
name: string;
|
|
10
15
|
numberOfSelectedRows?: number;
|
|
11
16
|
onSelectAllIndexesHandler?: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
|
12
17
|
propConfig?: IColumnConfig<any>;
|
|
18
|
+
propName: string;
|
|
13
19
|
schema: oas31.SchemaObject;
|
|
14
|
-
|
|
20
|
+
setPopoverConfig?: Dispatch<SetStateAction<ISchemaColumnFilterPopoverConfig | undefined>>;
|
|
15
21
|
setSortAsc: Dispatch<SetStateAction<boolean>>;
|
|
16
22
|
setSortColumn: Dispatch<SetStateAction<string>>;
|
|
17
23
|
sortAsc?: boolean;
|
|
18
24
|
style: CSSProperties;
|
|
19
25
|
}
|
|
20
|
-
declare const _default: ({
|
|
26
|
+
declare const _default: ({ isAllChecked, columnFilterStatus, disableColumnFilter, isSortable, numberOfSelectedRows, onSelectAllIndexesHandler, propConfig, propName, schema, setPopoverConfig, setSortAsc, setSortColumn, sortAsc, style, }: IThProps) => import("react/jsx-runtime").JSX.Element;
|
|
21
27
|
export default _default;
|
|
@@ -2,30 +2,60 @@ 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
|
-
|
|
5
|
+
export var EColumnFilterStatus;
|
|
6
|
+
(function (EColumnFilterStatus) {
|
|
7
|
+
EColumnFilterStatus["UNAVAILABLE"] = "UNAVAILABLE";
|
|
8
|
+
EColumnFilterStatus["AVAILABLE"] = "AVAILABLE";
|
|
9
|
+
EColumnFilterStatus["ACTIVE"] = "ACTIVE";
|
|
10
|
+
})(EColumnFilterStatus || (EColumnFilterStatus = {}));
|
|
11
|
+
const Th = ({ isAllChecked, columnFilterStatus, disableColumnFilter, isSortable, numberOfSelectedRows, onSelectAllIndexesHandler, propConfig, propName, schema, setPopoverConfig, setSortAsc, setSortColumn, sortAsc, style, }) => {
|
|
6
12
|
const thDivProps = {
|
|
7
13
|
style,
|
|
8
|
-
className: `schema-table__th ${isSortable ? "schema-table__th--sortable" : "schema-table__th--unsortable"}`,
|
|
14
|
+
className: `schema-table__th schema-table__th--column-filter-status-${columnFilterStatus} ${isSortable ? "schema-table__th--sortable" : "schema-table__th--unsortable"}`,
|
|
9
15
|
};
|
|
10
16
|
const onSortButtonClick = React.useCallback(() => {
|
|
11
17
|
if (sortAsc === undefined) {
|
|
12
|
-
setSortColumn(
|
|
18
|
+
setSortColumn(propName);
|
|
13
19
|
setSortAsc(!(propConfig === null || propConfig === void 0 ? void 0 : propConfig.defaultSortDesc));
|
|
14
20
|
return;
|
|
15
21
|
}
|
|
16
22
|
setSortAsc((sortAsc) => !sortAsc);
|
|
17
|
-
}, [
|
|
18
|
-
|
|
19
|
-
|
|
23
|
+
}, [
|
|
24
|
+
propConfig === null || propConfig === void 0 ? void 0 : propConfig.defaultSortDesc,
|
|
25
|
+
propName,
|
|
26
|
+
setSortAsc,
|
|
27
|
+
setSortColumn,
|
|
28
|
+
sortAsc,
|
|
29
|
+
]);
|
|
30
|
+
const onFilterButtonClick = React.useCallback((e) => {
|
|
31
|
+
if (columnFilterStatus === EColumnFilterStatus.ACTIVE &&
|
|
32
|
+
disableColumnFilter) {
|
|
33
|
+
disableColumnFilter(propName);
|
|
20
34
|
return;
|
|
21
35
|
}
|
|
22
|
-
if (
|
|
23
|
-
setColumnFilterDropdown(undefined);
|
|
36
|
+
if (!setPopoverConfig) {
|
|
24
37
|
return;
|
|
25
38
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
39
|
+
const rect = e.currentTarget.getBoundingClientRect();
|
|
40
|
+
setPopoverConfig((popoverConfig) => {
|
|
41
|
+
if (popoverConfig) {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
anchorPoint: rect
|
|
46
|
+
? {
|
|
47
|
+
x: Math.round(rect.x + rect.width),
|
|
48
|
+
y: Math.round(rect.y + rect.height),
|
|
49
|
+
}
|
|
50
|
+
: {
|
|
51
|
+
x: e.clientX,
|
|
52
|
+
y: e.clientY,
|
|
53
|
+
},
|
|
54
|
+
propName,
|
|
55
|
+
};
|
|
56
|
+
});
|
|
57
|
+
}, [columnFilterStatus, disableColumnFilter, propName, setPopoverConfig]);
|
|
58
|
+
if (propName === SELECT_ALL_COLUMN_NAME) {
|
|
29
59
|
return (_jsx("div", Object.assign({}, thDivProps, { children: _jsx("div", Object.assign({ style: {
|
|
30
60
|
width: "100%",
|
|
31
61
|
textAlign: "center",
|
|
@@ -47,6 +77,10 @@ const Th = ({ columnFilterDropdown, isAllChecked, isColumnSearchable, isSortable
|
|
|
47
77
|
thDivProps.className += ` text-${propConfig.align}`;
|
|
48
78
|
}
|
|
49
79
|
}
|
|
50
|
-
return (_jsxs("div", Object.assign({}, thDivProps, { children: [isSortable ? (_jsxs("button", Object.assign({ className: "px-0", disabled: (propConfig === null || propConfig === void 0 ? void 0 : propConfig.sortable) === false, onClick: onSortButtonClick }, { children: [(propConfig === null || propConfig === void 0 ? void 0 : propConfig.title) === undefined
|
|
80
|
+
return (_jsxs("div", Object.assign({}, thDivProps, { children: [isSortable ? (_jsxs("button", Object.assign({ className: "px-0", disabled: (propConfig === null || propConfig === void 0 ? void 0 : propConfig.sortable) === false, onClick: onSortButtonClick }, { children: [(propConfig === null || propConfig === void 0 ? void 0 : propConfig.title) === undefined
|
|
81
|
+
? uncamel(propName)
|
|
82
|
+
: propConfig === null || propConfig === void 0 ? void 0 : propConfig.title, sortAsc === undefined ? null : sortAsc ? "▲" : "▼"] }))) : (_jsx("div", Object.assign({ style: { lineHeight: "44px" } }, { children: (propConfig === null || propConfig === void 0 ? void 0 : propConfig.title) === undefined
|
|
83
|
+
? uncamel(propName)
|
|
84
|
+
: propConfig === null || propConfig === void 0 ? void 0 : propConfig.title }))), columnFilterStatus !== EColumnFilterStatus.UNAVAILABLE ? (_jsx("button", Object.assign({ onClick: onFilterButtonClick, "data-bs-toggle": "dropdown" }, { children: _jsx("svg", Object.assign({ viewBox: "0 0 36 36", xmlns: "http://www.w3.org/2000/svg", height: 16, width: 16, style: { display: "block" }, fill: "currentColor" }, { children: _jsx("polygon", { points: "14,30 22,25 22,17 35.999,0 17.988,0 0,0 14,17 " }) })) }))) : null] })));
|
|
51
85
|
};
|
|
52
86
|
export default React.memo(Th);
|
|
@@ -15,7 +15,7 @@ export interface ISchemaTableProps<T> {
|
|
|
15
15
|
getRowSelected?: (rowData: T) => boolean;
|
|
16
16
|
maxHeight?: number;
|
|
17
17
|
isSearchable?: boolean;
|
|
18
|
-
|
|
18
|
+
isColumnFilterable?: boolean;
|
|
19
19
|
isSortable?: boolean;
|
|
20
20
|
onCheckedIndexesChange?: (dataIndex: number[]) => void;
|
|
21
21
|
onRowClick?: (rowData: T, dataIndex: number, event: React.MouseEvent) => void;
|
|
@@ -25,8 +25,10 @@ export interface ISchemaTableProps<T> {
|
|
|
25
25
|
style?: React.CSSProperties;
|
|
26
26
|
width: number;
|
|
27
27
|
}
|
|
28
|
-
export type
|
|
29
|
-
from
|
|
30
|
-
to
|
|
28
|
+
export type TColumnFilterValue = string | number | boolean | {
|
|
29
|
+
from?: Date;
|
|
30
|
+
to?: Date;
|
|
31
31
|
};
|
|
32
|
-
|
|
32
|
+
declare function SchemaTable<T>({ Heading, checkedIndexes, config, customElement, data, defaultSortAsc, defaultSortColumn, getRowClassName, getRowSelected, maxHeight, isSearchable, isColumnFilterable, isSortable, onCheckedIndexesChange, onRowClick, rowHeight, schema, searchPlaceholder, style, width, }: ISchemaTableProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
33
|
+
declare const _default: typeof SchemaTable;
|
|
34
|
+
export default _default;
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
|
-
import {
|
|
4
|
-
import { localeFormat
|
|
3
|
+
import { VariableSizeGrid, VariableSizeList } from "react-window";
|
|
4
|
+
import { localeFormat } from "../inc/date";
|
|
5
5
|
import { uncamel } from "../inc/string";
|
|
6
|
-
import Th from "./Th";
|
|
6
|
+
import Th, { EColumnFilterStatus } from "./Th";
|
|
7
7
|
import { SELECT_ALL_COLUMN_NAME, SELECT_ALL_COLUMN_WIDTH } from "./constants";
|
|
8
8
|
import Td from "./Td";
|
|
9
|
-
import ColumnFilterRow from "./ColumnFilterRow";
|
|
10
9
|
import { DEFAULT_DATE_FORMAT, DEFAULT_DATE_TIME_FORMAT } from "../inc/constant";
|
|
11
|
-
|
|
10
|
+
import SchemaColumnFilterPopover from "./SchemaColumnFilterPopover";
|
|
11
|
+
function SchemaTable({ Heading = VariableSizeList, checkedIndexes, config, customElement, data, defaultSortAsc = false, defaultSortColumn, getRowClassName, getRowSelected, maxHeight, isSearchable, isColumnFilterable, isSortable, onCheckedIndexesChange, onRowClick, rowHeight = 36, schema, searchPlaceholder, style, width, }) {
|
|
12
12
|
const [sortColumn, setSortColumn] = React.useState(defaultSortColumn);
|
|
13
13
|
const [sortAsc, setSortAsc] = React.useState(defaultSortAsc);
|
|
14
14
|
const [searchQuery, setSearchQuery] = React.useState("");
|
|
15
|
-
const [
|
|
16
|
-
const [
|
|
15
|
+
const [columnFilterMap, setColumnFilterMap] = React.useState({});
|
|
16
|
+
const [popoverConfig, setPopoverConfig] = React.useState();
|
|
17
17
|
const { properties = {} } = schema;
|
|
18
18
|
const columnNames = React.useMemo(() => {
|
|
19
19
|
const columns = Object.keys(properties);
|
|
@@ -143,65 +143,60 @@ export default function SchemaTable({ Heading = VariableSizeList, checkedIndexes
|
|
|
143
143
|
]);
|
|
144
144
|
const getColumnWidth = React.useCallback((columnIndex) => (columnWidths ? columnWidths[columnIndex] : 1), [columnWidths]);
|
|
145
145
|
const filteredRenderData = React.useMemo(() => {
|
|
146
|
-
if (!renderData || (!
|
|
146
|
+
if (!renderData || (!isColumnFilterable && !isSearchable)) {
|
|
147
147
|
return renderData;
|
|
148
148
|
}
|
|
149
149
|
return renderData.filter((item) => {
|
|
150
|
-
const
|
|
151
|
-
|
|
150
|
+
const lcSearchQuery = searchQuery.toLowerCase();
|
|
151
|
+
if (searchQuery &&
|
|
152
|
+
!columnNames.find((columnName) => `${item[columnName]}`.toLowerCase().includes(lcSearchQuery))) {
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
let result = true;
|
|
156
|
+
Object.entries(columnFilterMap).forEach(([propName, columnFilterValue]) => {
|
|
157
|
+
if (!result || columnFilterValue === undefined) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
const propSchema = properties[propName];
|
|
152
161
|
// @ts-ignore
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
return
|
|
162
|
+
const rawValue = data[item._index][propName];
|
|
163
|
+
switch (propSchema.type) {
|
|
164
|
+
case "boolean":
|
|
165
|
+
case "integer":
|
|
166
|
+
result = rawValue === columnFilterValue;
|
|
167
|
+
break;
|
|
168
|
+
// @ts-ignore
|
|
169
|
+
case "string":
|
|
170
|
+
if (typeof columnFilterValue === "object" &&
|
|
171
|
+
(propSchema.format === "date" ||
|
|
172
|
+
propSchema.format === "date-time")) {
|
|
173
|
+
const { from, to } = columnFilterValue;
|
|
174
|
+
const rawDate = rawValue ? new Date(rawValue) : undefined;
|
|
175
|
+
if ((from && (!rawDate || rawDate < from)) ||
|
|
176
|
+
(to && (!rawDate || rawDate > to))) {
|
|
177
|
+
result = false;
|
|
178
|
+
}
|
|
179
|
+
return;
|
|
171
180
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
if (!startDate || !currentDate) {
|
|
182
|
-
return previousValue;
|
|
183
|
-
}
|
|
184
|
-
previousValue.push(startDate && endDate
|
|
185
|
-
? currentDate >= startDate && currentDate <= endDate
|
|
186
|
-
: currentDate >= startDate);
|
|
187
|
-
return previousValue;
|
|
188
|
-
}
|
|
189
|
-
previousValue.push(rawValue
|
|
190
|
-
.toLowerCase()
|
|
191
|
-
.includes(`${columnSearchValue}`.toLowerCase()));
|
|
192
|
-
return previousValue;
|
|
193
|
-
}, [])
|
|
194
|
-
: [true];
|
|
195
|
-
return globalSearchFilterResult && rowColumnValidation.every((el) => el);
|
|
181
|
+
// fall through
|
|
182
|
+
default:
|
|
183
|
+
// fallback by looking at the render value
|
|
184
|
+
result = `${item[propName]}`
|
|
185
|
+
.toLowerCase()
|
|
186
|
+
.includes(`${columnFilterValue}`.toLowerCase());
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
return result;
|
|
196
190
|
});
|
|
197
191
|
}, [
|
|
198
|
-
columnNames,
|
|
199
|
-
columnSearchObj,
|
|
200
|
-
isColumnSearchable,
|
|
201
|
-
isSearchable,
|
|
202
|
-
properties,
|
|
203
192
|
renderData,
|
|
193
|
+
isColumnFilterable,
|
|
194
|
+
isSearchable,
|
|
204
195
|
searchQuery,
|
|
196
|
+
columnNames,
|
|
197
|
+
columnFilterMap,
|
|
198
|
+
properties,
|
|
199
|
+
data,
|
|
205
200
|
]);
|
|
206
201
|
// Sort the filtered data
|
|
207
202
|
const sortedRenderData = React.useMemo(() => {
|
|
@@ -258,21 +253,33 @@ export default function SchemaTable({ Heading = VariableSizeList, checkedIndexes
|
|
|
258
253
|
(filteredRenderData === null || filteredRenderData === void 0 ? void 0 : filteredRenderData.length) === (checkedIndexes === null || checkedIndexes === void 0 ? void 0 : checkedIndexes.length) &&
|
|
259
254
|
(checkedIndexes === null || checkedIndexes === void 0 ? void 0 : checkedIndexes.every((checkedIndex) => filteredRenderData === null || filteredRenderData === void 0 ? void 0 : filteredRenderData.some((el) => el._index === checkedIndex))));
|
|
260
255
|
}, [checkedIndexes, filteredRenderData]);
|
|
256
|
+
const disableColumnFilter = React.useCallback((propName) => {
|
|
257
|
+
const newColumnFilterMap = Object.assign({}, columnFilterMap);
|
|
258
|
+
delete newColumnFilterMap[propName];
|
|
259
|
+
setColumnFilterMap(newColumnFilterMap);
|
|
260
|
+
}, [columnFilterMap]);
|
|
261
261
|
const SchemaTableTh = React.useCallback(({ style, index }) => {
|
|
262
262
|
const propName = columnNames[index];
|
|
263
|
-
|
|
263
|
+
let columnFilterStatus = isColumnFilterable
|
|
264
|
+
? EColumnFilterStatus.AVAILABLE
|
|
265
|
+
: EColumnFilterStatus.UNAVAILABLE;
|
|
266
|
+
if (columnFilterMap[propName] !== undefined) {
|
|
267
|
+
columnFilterStatus = EColumnFilterStatus.ACTIVE;
|
|
268
|
+
}
|
|
269
|
+
return (_jsx(Th, { isAllChecked: isAllRowsChecked, columnFilterStatus: columnFilterStatus, disableColumnFilter: disableColumnFilter, isSortable: !!isSortable, numberOfSelectedRows: checkedIndexes === null || checkedIndexes === void 0 ? void 0 : checkedIndexes.length, onSelectAllIndexesHandler: onSelectAllIndexesHandler, propConfig: config ? config[propName] : undefined, propName: propName, schema: properties[propName], setPopoverConfig: setPopoverConfig, setSortAsc: setSortAsc, setSortColumn: setSortColumn, sortAsc: sortColumn === propName ? sortAsc : undefined, style: style }));
|
|
264
270
|
}, [
|
|
271
|
+
checkedIndexes === null || checkedIndexes === void 0 ? void 0 : checkedIndexes.length,
|
|
272
|
+
columnFilterMap,
|
|
265
273
|
columnNames,
|
|
266
274
|
config,
|
|
275
|
+
disableColumnFilter,
|
|
276
|
+
isAllRowsChecked,
|
|
277
|
+
isColumnFilterable,
|
|
267
278
|
isSortable,
|
|
279
|
+
onSelectAllIndexesHandler,
|
|
268
280
|
properties,
|
|
269
|
-
sortColumn,
|
|
270
281
|
sortAsc,
|
|
271
|
-
|
|
272
|
-
isAllRowsChecked,
|
|
273
|
-
checkedIndexes === null || checkedIndexes === void 0 ? void 0 : checkedIndexes.length,
|
|
274
|
-
columnFilterDropdown,
|
|
275
|
-
isColumnSearchable,
|
|
282
|
+
sortColumn,
|
|
276
283
|
]);
|
|
277
284
|
const SchemaTableTd = React.useCallback(({ columnIndex, rowIndex, style }) => {
|
|
278
285
|
const propName = columnNames[columnIndex];
|
|
@@ -290,9 +297,6 @@ export default function SchemaTable({ Heading = VariableSizeList, checkedIndexes
|
|
|
290
297
|
rowHeight,
|
|
291
298
|
sortedRenderData,
|
|
292
299
|
]);
|
|
293
|
-
const columnSearchHandler = React.useCallback((propName, value) => {
|
|
294
|
-
setColumnSearchObj((columnSearch) => (Object.assign(Object.assign({}, columnSearch), { [propName]: value })));
|
|
295
|
-
}, []);
|
|
296
300
|
const onSearchChange = React.useCallback((e) => {
|
|
297
301
|
setSearchQuery(e.currentTarget.value);
|
|
298
302
|
}, []);
|
|
@@ -306,5 +310,19 @@ export default function SchemaTable({ Heading = VariableSizeList, checkedIndexes
|
|
|
306
310
|
? rowsMaxHeight
|
|
307
311
|
: rowsHeight;
|
|
308
312
|
}, [maxHeight, isSearchable, rowCount, rowHeight]);
|
|
309
|
-
|
|
313
|
+
const onPopoverClose = React.useCallback(() => {
|
|
314
|
+
setPopoverConfig(undefined);
|
|
315
|
+
}, []);
|
|
316
|
+
const onSchemaColumnFilterChange = React.useCallback((newColumnFilterValue) => {
|
|
317
|
+
if (!popoverConfig) {
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
if (newColumnFilterValue === undefined) {
|
|
321
|
+
disableColumnFilter(popoverConfig.propName);
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
setColumnFilterMap((columnFilterMap) => (Object.assign(Object.assign({}, columnFilterMap), { [popoverConfig.propName]: newColumnFilterValue })));
|
|
325
|
+
}, [disableColumnFilter, popoverConfig]);
|
|
326
|
+
return (_jsxs("div", Object.assign({ className: `schema-table${onRowClick ? " schema-table--clickable-rows" : ""}`, style: Object.assign(Object.assign({}, style), { width: rowWidth }), role: "table" }, { children: [_jsxs("div", Object.assign({ className: "schema-table__action-container" }, { children: [_jsx("div", Object.assign({ style: { flex: 1 } }, { children: isSearchable ? (_jsx("input", { 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: rowWidth, sortAsc: sortAsc, setSortAsc: setSortAsc, setSortColumn: setSortColumn, sortColumn: sortColumn, sortedRenderData: sortedRenderData, className: "schema-table__th-row" }, { children: SchemaTableTh }), `thead_${rowWidth}_${sortColumn}_${sortAsc}_${searchQuery}`), _jsx(VariableSizeGrid, Object.assign({ className: "schema-table__tbody", height: tableBodyHeight, width: rowWidth, columnWidth: getColumnWidth, rowHeight: getRowHeight, columnCount: columnCount, rowCount: rowCount }, { children: SchemaTableTd }), `tbody_${tableBodyHeight}_${rowWidth}_${sortColumn}_${sortAsc}_${searchQuery}_${columnCount}`), popoverConfig ? (_jsx(SchemaColumnFilterPopover, { anchorPoint: popoverConfig.anchorPoint, anchorPosition: popoverConfig.anchorPosition, onClose: onPopoverClose, onChange: onSchemaColumnFilterChange, propName: popoverConfig.propName, propSchema: schema.properties[popoverConfig.propName], value: columnFilterMap[popoverConfig.propName] })) : null] })));
|
|
310
327
|
}
|
|
328
|
+
export default React.memo(SchemaTable);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "@testing-library/jest-dom";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
11
|
+
import "@testing-library/jest-dom";
|
|
12
|
+
import { render, screen } from "@testing-library/react";
|
|
13
|
+
import SchemaTable from "./index";
|
|
14
|
+
it("renders an empty table", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
15
|
+
render(_jsx(SchemaTable, { data: [], schema: {}, width: 1 }));
|
|
16
|
+
const table = yield screen.findByRole("table");
|
|
17
|
+
expect(table).toBeInTheDocument();
|
|
18
|
+
}));
|
package/dist/inc/date.d.ts
CHANGED
package/dist/inc/date.js
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
1
|
import { format } from "date-fns";
|
|
2
2
|
import nl from "date-fns/locale/nl";
|
|
3
3
|
export const localeFormat = (date, dateFormat) => format(date, dateFormat, { locale: nl });
|
|
4
|
-
export const getUnixTimeStamp = (date, dateFormat) => {
|
|
5
|
-
return Math.floor(new Date(format(new Date(date), dateFormat || "MM/dd/yyyy")).getTime() /
|
|
6
|
-
1000);
|
|
7
|
-
};
|
package/dist/index.css
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
@import "../../node_modules/react-datepicker/dist/react-datepicker.min.css";
|
|
2
|
+
.react-datepicker {
|
|
3
|
+
display: flex;
|
|
4
|
+
}
|
|
5
|
+
|
|
1
6
|
.schema-table {
|
|
2
7
|
overflow: hidden;
|
|
3
8
|
}
|
|
@@ -87,6 +92,12 @@
|
|
|
87
92
|
font-weight: bold;
|
|
88
93
|
display: flex;
|
|
89
94
|
}
|
|
95
|
+
.schema-table__th--column-filter-status-ACTIVE button {
|
|
96
|
+
font-style: italic;
|
|
97
|
+
}
|
|
98
|
+
.schema-table__th--column-filter-status-ACTIVE svg {
|
|
99
|
+
color: red;
|
|
100
|
+
}
|
|
90
101
|
.schema-table__td {
|
|
91
102
|
overflow: hidden;
|
|
92
103
|
white-space: nowrap;
|
|
@@ -126,3 +137,32 @@
|
|
|
126
137
|
border-radius: 8px;
|
|
127
138
|
padding: 4px 10px;
|
|
128
139
|
}
|
|
140
|
+
.schema-table .schema-column-filter-popover__string_date-time .popover {
|
|
141
|
+
width: 500px;
|
|
142
|
+
max-width: initial;
|
|
143
|
+
}
|
|
144
|
+
.schema-table .lightbox {
|
|
145
|
+
position: fixed;
|
|
146
|
+
top: 0;
|
|
147
|
+
bottom: 0;
|
|
148
|
+
right: 0;
|
|
149
|
+
left: 0;
|
|
150
|
+
background-color: rgba(0, 0, 0, 0.5);
|
|
151
|
+
z-index: 1;
|
|
152
|
+
}
|
|
153
|
+
.schema-table .lightbox--transparent {
|
|
154
|
+
background-color: transparent;
|
|
155
|
+
}
|
|
156
|
+
.schema-table .popover {
|
|
157
|
+
position: fixed;
|
|
158
|
+
border-radius: 2px;
|
|
159
|
+
background: #ddd;
|
|
160
|
+
box-shadow: 0 2px 10px #999999;
|
|
161
|
+
z-index: 1;
|
|
162
|
+
padding: 10px;
|
|
163
|
+
min-width: 150px;
|
|
164
|
+
}
|
|
165
|
+
.schema-table .popover select,
|
|
166
|
+
.schema-table .popover input {
|
|
167
|
+
width: 100%;
|
|
168
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mig-schema-table",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.25",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist/"
|
|
@@ -23,9 +23,10 @@
|
|
|
23
23
|
"react-window": "^1.8.9"
|
|
24
24
|
},
|
|
25
25
|
"scripts": {
|
|
26
|
+
"build": "tsc -p tsconfig.json; sass --no-source-map src/component/index.scss dist/index.css",
|
|
27
|
+
"prepublishOnly": "npm run build",
|
|
26
28
|
"start": "react-scripts start",
|
|
27
|
-
"
|
|
28
|
-
"prepublishOnly": "npm run build"
|
|
29
|
+
"test": "react-scripts test"
|
|
29
30
|
},
|
|
30
31
|
"eslintConfig": {
|
|
31
32
|
"extends": [
|
|
@@ -49,6 +50,8 @@
|
|
|
49
50
|
"@types/date-fns": "^2.6.0",
|
|
50
51
|
"@types/lodash": "^4.14.194",
|
|
51
52
|
"@types/react-window": "^1.8.5",
|
|
53
|
+
"@testing-library/jest-dom": "^5.16.5",
|
|
54
|
+
"@testing-library/react": "^13.4.0",
|
|
52
55
|
"axios": "^1.4.0",
|
|
53
56
|
"prettier": "^2.8.8",
|
|
54
57
|
"react-router-dom": "^6.11.2",
|