mig-schema-table 3.0.27 → 3.0.29
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 -0
- package/dist/SchemaTable/ColumnFilterRow/index.d.ts +7 -3
- package/dist/SchemaTable/ColumnFilterRow/index.js +65 -15
- package/dist/SchemaTable/SchemaColumnFilterPopover/index.d.ts +2 -6
- package/dist/SchemaTable/SchemaColumnFilterPopover/index.js +32 -48
- package/dist/SchemaTable/Th/index.js +2 -10
- package/dist/SchemaTable/index.js +1 -1
- package/dist/component/SchemaTable/SchemaColumnFilterPopover/FilterFormComponent/index.d.ts +11 -0
- package/dist/component/SchemaTable/SchemaColumnFilterPopover/FilterFormComponent/index.js +76 -0
- package/dist/component/SchemaTable/SchemaColumnFilterPopover/index.d.ts +15 -0
- package/dist/component/SchemaTable/SchemaColumnFilterPopover/index.js +37 -0
- package/dist/component/SchemaTable/Td/index.d.ts +22 -0
- package/dist/component/SchemaTable/Td/index.js +78 -0
- package/dist/component/SchemaTable/Th/index.d.ts +27 -0
- package/dist/component/SchemaTable/Th/index.js +78 -0
- package/dist/component/SchemaTable/constants.d.ts +2 -0
- package/dist/component/SchemaTable/constants.js +2 -0
- package/dist/component/SchemaTable/index.d.ts +34 -0
- package/dist/component/SchemaTable/index.js +343 -0
- package/dist/component/SchemaTable/index.test.d.ts +1 -0
- package/dist/component/SchemaTable/index.test.js +17 -0
- package/dist/component/inc/constant.d.ts +2 -0
- package/dist/component/inc/constant.js +2 -0
- package/dist/component/inc/date.d.ts +1 -0
- package/dist/component/inc/date.js +3 -0
- package/dist/component/inc/schema.d.ts +2 -0
- package/dist/component/inc/schema.js +32 -0
- package/dist/component/inc/string.d.ts +1 -0
- package/dist/component/inc/string.js +17 -0
- package/dist/component/index.d.ts +4 -0
- package/dist/component/index.js +2 -0
- package/dist/component/types.d.ts +21 -0
- package/dist/component/types.js +1 -0
- package/dist/exampleData.d.ts +29 -0
- package/dist/exampleData.js +177 -0
- package/dist/index.css +16 -89
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -42,6 +42,7 @@ import { SchemaTable, IColumnConfig } from "mig-schema-table";
|
|
|
42
42
|
import "mig-schema-table/dist/index.css";
|
|
43
43
|
// Add this for default datepicker styling
|
|
44
44
|
import "react-datepicker/dist/react-datepicker.css";
|
|
45
|
+
// Optionally add bootstrap5 styles
|
|
45
46
|
|
|
46
47
|
const config: { [keyName: string]: IColumnConfig } = {
|
|
47
48
|
id: {
|
|
@@ -1,17 +1,21 @@
|
|
|
1
|
+
import { Dispatch, SetStateAction } from "react";
|
|
1
2
|
import { IColumnConfig } from "../../types";
|
|
2
3
|
import { oas31 } from "openapi3-ts";
|
|
3
4
|
import "react-datepicker/dist/react-datepicker.css";
|
|
5
|
+
import { tColumnSearchValue } from "../index";
|
|
4
6
|
interface IColumnFilterRowProps {
|
|
5
7
|
columnNames: string[];
|
|
6
8
|
getWidth: (index: number) => number;
|
|
7
9
|
config?: {
|
|
8
10
|
[propName: string]: IColumnConfig<any>;
|
|
9
11
|
};
|
|
10
|
-
columnSearchHandler: (propName: string, value:
|
|
12
|
+
columnSearchHandler: (propName: string, value: tColumnSearchValue) => void;
|
|
11
13
|
value: {
|
|
12
|
-
[propName: string]:
|
|
14
|
+
[propName: string]: tColumnSearchValue;
|
|
13
15
|
};
|
|
14
16
|
schema: oas31.SchemaObject;
|
|
17
|
+
columnFilterDropdown?: string;
|
|
18
|
+
setColumnFilterDropdown?: Dispatch<SetStateAction<string | undefined>>;
|
|
15
19
|
}
|
|
16
|
-
export default function ColumnFilterRow({ columnNames, getWidth, config, value, columnSearchHandler, schema, }: IColumnFilterRowProps): import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
export default function ColumnFilterRow({ columnNames, getWidth, config, value, columnSearchHandler, schema, columnFilterDropdown, setColumnFilterDropdown, }: IColumnFilterRowProps): import("react/jsx-runtime").JSX.Element;
|
|
17
21
|
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";
|
|
8
7
|
import { DEFAULT_DATE_FORMAT, DEFAULT_DATE_TIME_FORMAT, } from "../../inc/constant";
|
|
9
|
-
|
|
8
|
+
import { getUnixTimeStamp } from "../../inc/date";
|
|
9
|
+
export default function ColumnFilterRow({ columnNames, getWidth, config, value, columnSearchHandler, schema, columnFilterDropdown, setColumnFilterDropdown, }) {
|
|
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" ? ["✓", "✕"] : 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) => {
|
|
16
16
|
const { type, format, minimum, maximum } = propSchema;
|
|
17
17
|
const inputChangeHandler = (event) => {
|
|
18
18
|
columnSearchHandler(propName, event.target.value);
|
|
@@ -24,24 +24,68 @@ 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
|
-
|
|
27
|
+
const dateFormat = format === "date"
|
|
28
|
+
? DEFAULT_DATE_FORMAT
|
|
29
|
+
: DEFAULT_DATE_TIME_FORMAT;
|
|
30
|
+
const dateRangeValue = propValue;
|
|
31
|
+
const startDate = (dateRangeValue === null || dateRangeValue === void 0 ? void 0 : dateRangeValue.from)
|
|
32
|
+
? new Date(dateRangeValue.from)
|
|
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 : ""}` }));
|
|
33
42
|
};
|
|
34
|
-
|
|
43
|
+
const endDateChangeHandler = (date) => {
|
|
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" })] }))] })) })));
|
|
35
52
|
}
|
|
36
|
-
return (_jsx("input", { value: strValue, "data-prop-name": propName, onChange: inputChangeHandler, placeholder: `Search ${propName}` }));
|
|
53
|
+
return (_jsx("div", Object.assign({ className: "p-1" }, { children: _jsx("input", { value: strValue, "data-prop-name": propName, onChange: inputChangeHandler, placeholder: `Search ${propName}` }) })));
|
|
37
54
|
case "integer":
|
|
38
|
-
return (_jsx("input", { type: "number", value: strValue, "data-prop-name": propName, onChange: inputChangeHandler, placeholder: `Search ${propName}`, min: minimum, max: maximum }));
|
|
55
|
+
return (_jsx("div", Object.assign({ className: "d-flex p-1" }, { children: _jsx("input", { type: "number", value: strValue, "data-prop-name": propName, onChange: inputChangeHandler, placeholder: `Search ${propName}`, min: minimum, max: maximum }) })));
|
|
39
56
|
case "boolean":
|
|
40
57
|
return getSelectComponent(propSchema, propName, strValue, inputChangeHandler);
|
|
41
58
|
default:
|
|
42
59
|
return _jsx(_Fragment, {});
|
|
43
60
|
}
|
|
44
61
|
}, [columnSearchHandler, getSelectComponent]);
|
|
62
|
+
const removeDropdown = React.useCallback((e) => {
|
|
63
|
+
if (!columnFilterDropdown) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
let columnFilterEl = null;
|
|
67
|
+
let parentNode = e.target;
|
|
68
|
+
while (parentNode && parentNode.nodeName !== "HTML") {
|
|
69
|
+
if (typeof parentNode.className === "string" &&
|
|
70
|
+
parentNode.className.includes("schema-table__column-filter")) {
|
|
71
|
+
columnFilterEl = parentNode;
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
parentNode = parentNode.parentNode;
|
|
75
|
+
}
|
|
76
|
+
if (!columnFilterEl) {
|
|
77
|
+
setColumnFilterDropdown && setColumnFilterDropdown(undefined);
|
|
78
|
+
}
|
|
79
|
+
}, [columnFilterDropdown, setColumnFilterDropdown]);
|
|
80
|
+
React.useEffect(() => {
|
|
81
|
+
if (!columnFilterDropdown) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
window.addEventListener("click", removeDropdown, { capture: true });
|
|
85
|
+
return () => {
|
|
86
|
+
window.removeEventListener("click", removeDropdown, { capture: true });
|
|
87
|
+
};
|
|
88
|
+
}, [columnFilterDropdown, removeDropdown]);
|
|
45
89
|
const SchemaColumnFilter = React.useCallback((index) => {
|
|
46
90
|
const propName = columnNames[index];
|
|
47
91
|
const propSchema = properties[propName];
|
|
@@ -50,8 +94,14 @@ export default function ColumnFilterRow({ columnNames, getWidth, config, value,
|
|
|
50
94
|
if (propName === SELECT_ALL_COLUMN_NAME || !(propConfig === null || propConfig === void 0 ? void 0 : propConfig.isFilterable)) {
|
|
51
95
|
return _jsx("div", { className: "schema-table__th" });
|
|
52
96
|
}
|
|
53
|
-
return (_jsx("
|
|
54
|
-
|
|
97
|
+
return (_jsx("ul", Object.assign({ id: "test", className: `dropdown-menu dropdown-menu-lg-end ${columnFilterDropdown && columnFilterDropdown === propName
|
|
98
|
+
? "show"
|
|
99
|
+
: ""}`, style: {
|
|
100
|
+
position: "fixed",
|
|
101
|
+
marginTop: -10,
|
|
102
|
+
minHeight: 100,
|
|
103
|
+
} }, { children: _jsx("div", Object.assign({ id: "filter-dropdown-item", style: { margin: 10 } }, { children: field(propSchema, propName, propValue) })) })));
|
|
104
|
+
}, [columnFilterDropdown, columnNames, config, field, properties, value]);
|
|
55
105
|
return (_jsx("div", Object.assign({ className: "schema-table__th-row", style: { display: "flex", flex: "row" } }, { children: columnNames.map((columnName, index) => {
|
|
56
106
|
return (_jsx("div", Object.assign({ className: "schema-table__column-filter", style: {
|
|
57
107
|
width: getWidth(index),
|
|
@@ -2,11 +2,7 @@ import React from "react";
|
|
|
2
2
|
import { oas31 } from "openapi3-ts";
|
|
3
3
|
import { TColumnFilterValue } from "../index";
|
|
4
4
|
export interface ISchemaColumnFilterPopoverConfig {
|
|
5
|
-
|
|
6
|
-
x: number;
|
|
7
|
-
y: number;
|
|
8
|
-
};
|
|
9
|
-
anchorPosition?: "bottomLeft" | "bottomRight" | "topLeft" | "topRight";
|
|
5
|
+
referenceElement: HTMLElement;
|
|
10
6
|
propName: string;
|
|
11
7
|
}
|
|
12
8
|
type TSchemaColumnFilterPopoverProps = ISchemaColumnFilterPopoverConfig & {
|
|
@@ -15,5 +11,5 @@ type TSchemaColumnFilterPopoverProps = ISchemaColumnFilterPopoverConfig & {
|
|
|
15
11
|
value: TColumnFilterValue;
|
|
16
12
|
onClose: () => void;
|
|
17
13
|
};
|
|
18
|
-
declare const _default: React.MemoExoticComponent<(
|
|
14
|
+
declare const _default: React.MemoExoticComponent<({ onChange, onClose, propName, propSchema, referenceElement, value, }: TSchemaColumnFilterPopoverProps) => import("react/jsx-runtime").JSX.Element>;
|
|
19
15
|
export default _default;
|
|
@@ -1,53 +1,37 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import FilterFormComponent from "./FilterFormComponent";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const [
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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) {
|
|
4
|
+
import { usePopper } from "react-popper";
|
|
5
|
+
const SchemaColumnFilterPopover = ({ onChange, onClose, propName, propSchema, referenceElement, value, }) => {
|
|
6
|
+
const [popperElement, setPopperElement] = React.useState(null);
|
|
7
|
+
const [arrowElement, setArrowElement] = React.useState(null);
|
|
8
|
+
const { styles, attributes } = usePopper(referenceElement, popperElement, {
|
|
9
|
+
modifiers: [{ name: "arrow", options: { element: arrowElement } }],
|
|
10
|
+
});
|
|
11
|
+
React.useEffect(() => {
|
|
12
|
+
const onWindowClick = (e) => {
|
|
13
|
+
if (!popperElement) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
let parent = e.target;
|
|
17
|
+
while (parent && popperElement) {
|
|
18
|
+
if (parent === popperElement) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
parent =
|
|
22
|
+
parent.parentNode === window.document ? null : parent.parentNode;
|
|
23
|
+
}
|
|
48
24
|
onClose();
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
|
|
25
|
+
};
|
|
26
|
+
window.addEventListener("click", onWindowClick, { capture: true });
|
|
27
|
+
return () => {
|
|
28
|
+
window.removeEventListener("click", onWindowClick, { capture: true });
|
|
29
|
+
};
|
|
30
|
+
}, [onClose, popperElement]);
|
|
31
|
+
const classNames = ["popover"];
|
|
32
|
+
if (attributes.popper) {
|
|
33
|
+
classNames.push(`bs-popover-${attributes.popper["data-popper-placement"]}`);
|
|
34
|
+
}
|
|
35
|
+
return (_jsxs("div", Object.assign({ className: classNames.join(" "), role: "tooltip", ref: setPopperElement, style: styles.popper }, attributes.popper, { children: [_jsx("div", { className: "popover-arrow", ref: setArrowElement, style: styles.arrow }), _jsx("div", Object.assign({ className: "popover-body" }, { children: _jsx(FilterFormComponent, { onChange: onChange, propSchema: propSchema, propName: propName, columnFilterValue: value }) }))] })));
|
|
52
36
|
};
|
|
53
37
|
export default React.memo(SchemaColumnFilterPopover);
|
|
@@ -36,21 +36,13 @@ const Th = ({ isAllChecked, columnFilterStatus, disableColumnFilter, isSortable,
|
|
|
36
36
|
if (!setPopoverConfig) {
|
|
37
37
|
return;
|
|
38
38
|
}
|
|
39
|
-
const
|
|
39
|
+
const referenceElement = e.currentTarget;
|
|
40
40
|
setPopoverConfig((popoverConfig) => {
|
|
41
41
|
if (popoverConfig) {
|
|
42
42
|
return undefined;
|
|
43
43
|
}
|
|
44
44
|
return {
|
|
45
|
-
|
|
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
|
-
},
|
|
45
|
+
referenceElement,
|
|
54
46
|
propName,
|
|
55
47
|
};
|
|
56
48
|
});
|
|
@@ -324,6 +324,6 @@ function SchemaTable({ Heading = VariableSizeList, checkedIndexes, config, custo
|
|
|
324
324
|
}
|
|
325
325
|
setColumnFilterMap((columnFilterMap) => (Object.assign(Object.assign({}, columnFilterMap), { [popoverConfig.propName]: newColumnFilterValue })));
|
|
326
326
|
}, [disableColumnFilter, popoverConfig]);
|
|
327
|
-
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, {
|
|
327
|
+
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, { referenceElement: popoverConfig.referenceElement, onClose: onPopoverClose, onChange: onSchemaColumnFilterChange, propName: popoverConfig.propName, propSchema: schema.properties[popoverConfig.propName], value: columnFilterMap[popoverConfig.propName] })) : null] })));
|
|
328
328
|
}
|
|
329
329
|
export default React.memo(SchemaTable);
|
|
@@ -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: "input-group" }, { children: _jsx("input", { className: "form-control", 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({ className: "form-select", 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({ className: "form-select", 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 (_jsxs("div", Object.assign({ className: "input-group d-flex" }, { 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: "input-group" }, { children: _jsx("input", { type: "text", className: "form-control", placeholder: `Search ${propName}`, "aria-label": `Search ${propName}`, autoFocus: true, value: (value || ""), "data-prop-name": propName, onChange: (e) => {
|
|
72
|
+
onChange(e.currentTarget.value || undefined);
|
|
73
|
+
} }) })));
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
export default React.memo(FilterFormComponent);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { oas31 } from "openapi3-ts";
|
|
3
|
+
import { TColumnFilterValue } from "../index";
|
|
4
|
+
export interface ISchemaColumnFilterPopoverConfig {
|
|
5
|
+
referenceElement: HTMLElement;
|
|
6
|
+
propName: string;
|
|
7
|
+
}
|
|
8
|
+
type TSchemaColumnFilterPopoverProps = ISchemaColumnFilterPopoverConfig & {
|
|
9
|
+
onChange: (newValue?: TColumnFilterValue) => void;
|
|
10
|
+
propSchema: oas31.SchemaObject;
|
|
11
|
+
value: TColumnFilterValue;
|
|
12
|
+
onClose: () => void;
|
|
13
|
+
};
|
|
14
|
+
declare const _default: React.MemoExoticComponent<({ onChange, onClose, propName, propSchema, referenceElement, value, }: TSchemaColumnFilterPopoverProps) => import("react/jsx-runtime").JSX.Element>;
|
|
15
|
+
export default _default;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import FilterFormComponent from "./FilterFormComponent";
|
|
4
|
+
import { usePopper } from "react-popper";
|
|
5
|
+
const SchemaColumnFilterPopover = ({ onChange, onClose, propName, propSchema, referenceElement, value, }) => {
|
|
6
|
+
const [popperElement, setPopperElement] = React.useState(null);
|
|
7
|
+
const [arrowElement, setArrowElement] = React.useState(null);
|
|
8
|
+
const { styles, attributes } = usePopper(referenceElement, popperElement, {
|
|
9
|
+
modifiers: [{ name: "arrow", options: { element: arrowElement } }],
|
|
10
|
+
});
|
|
11
|
+
React.useEffect(() => {
|
|
12
|
+
const onWindowClick = (e) => {
|
|
13
|
+
if (!popperElement) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
let parent = e.target;
|
|
17
|
+
while (parent && popperElement) {
|
|
18
|
+
if (parent === popperElement) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
parent =
|
|
22
|
+
parent.parentNode === window.document ? null : parent.parentNode;
|
|
23
|
+
}
|
|
24
|
+
onClose();
|
|
25
|
+
};
|
|
26
|
+
window.addEventListener("click", onWindowClick, { capture: true });
|
|
27
|
+
return () => {
|
|
28
|
+
window.removeEventListener("click", onWindowClick, { capture: true });
|
|
29
|
+
};
|
|
30
|
+
}, [onClose, popperElement]);
|
|
31
|
+
const classNames = ["popover", "schema-column-filter-popover"];
|
|
32
|
+
if (attributes.popper) {
|
|
33
|
+
classNames.push(`bs-popover-${attributes.popper["data-popper-placement"]}`);
|
|
34
|
+
}
|
|
35
|
+
return (_jsxs("div", Object.assign({ className: classNames.join(" "), role: "tooltip", ref: setPopperElement, style: styles.popper }, attributes.popper, { children: [_jsx("div", { className: "popover-arrow", ref: setArrowElement, style: styles.arrow }), _jsx("div", Object.assign({ className: "popover-body" }, { children: _jsx(FilterFormComponent, { onChange: onChange, propSchema: propSchema, propName: propName, columnFilterValue: value }) }))] })));
|
|
36
|
+
};
|
|
37
|
+
export default React.memo(SchemaColumnFilterPopover);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { oas31 } from "openapi3-ts";
|
|
3
|
+
import { IColumnConfig, IRenderData } from "../../types";
|
|
4
|
+
interface ITdProps<T> {
|
|
5
|
+
checkedIndexes?: number[];
|
|
6
|
+
columnIndex: number;
|
|
7
|
+
data: T[];
|
|
8
|
+
getRowClassName?: (rowData: T, dataIndex: number) => string;
|
|
9
|
+
getRowSelected?: (rowData: T) => boolean;
|
|
10
|
+
rowHeight: number;
|
|
11
|
+
rowIndex: number;
|
|
12
|
+
onCheckedIndexesChange?: (dataIndex: number[]) => void;
|
|
13
|
+
onRowClick?: (rowData: T, dataIndex: number, event: React.MouseEvent) => void;
|
|
14
|
+
propConfig?: IColumnConfig<any>;
|
|
15
|
+
propName: string;
|
|
16
|
+
propSchema: oas31.SchemaObject;
|
|
17
|
+
sortedRenderData?: IRenderData[];
|
|
18
|
+
style: React.CSSProperties;
|
|
19
|
+
}
|
|
20
|
+
declare function Td<T>({ checkedIndexes, columnIndex, data, getRowClassName, getRowSelected, onCheckedIndexesChange, onRowClick, propConfig, propName, propSchema, rowHeight, rowIndex, sortedRenderData, style, }: ITdProps<T>): import("react/jsx-runtime").JSX.Element | null;
|
|
21
|
+
declare const _default: typeof Td;
|
|
22
|
+
export default _default;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { SELECT_ALL_COLUMN_NAME } from "../constants";
|
|
4
|
+
function Td({ checkedIndexes, columnIndex, data, getRowClassName, getRowSelected, onCheckedIndexesChange, onRowClick, propConfig, propName, propSchema, rowHeight, rowIndex, sortedRenderData, style, }) {
|
|
5
|
+
const onTdClick = React.useCallback((e) => {
|
|
6
|
+
if (!sortedRenderData || !onRowClick) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
const { rowIndex } = e.currentTarget.dataset;
|
|
10
|
+
if (!rowIndex) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const row = sortedRenderData[parseInt(rowIndex, 10)];
|
|
14
|
+
onRowClick(data[row._index], row._index, e);
|
|
15
|
+
}, [data, onRowClick, sortedRenderData]);
|
|
16
|
+
const row = sortedRenderData ? sortedRenderData[rowIndex] : undefined;
|
|
17
|
+
const tdDivProps = React.useMemo(() => {
|
|
18
|
+
if (!row) {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
"data-row-index": rowIndex,
|
|
23
|
+
"data-column-index": columnIndex,
|
|
24
|
+
key: propName,
|
|
25
|
+
style: Object.assign(Object.assign({}, style), { lineHeight: `${rowHeight}px` }),
|
|
26
|
+
onClick: !(propConfig === null || propConfig === void 0 ? void 0 : propConfig.renderCell) ? onTdClick : undefined,
|
|
27
|
+
className: `schema-table__td schema-table__td--${rowIndex % 2 ? "odd" : "even"}${getRowSelected && getRowSelected(data[row._index])
|
|
28
|
+
? " schema-table__td--selected"
|
|
29
|
+
: ""} ${getRowClassName ? getRowClassName(data[row._index], row._index) : ""}`,
|
|
30
|
+
title: row[propName],
|
|
31
|
+
};
|
|
32
|
+
}, [
|
|
33
|
+
columnIndex,
|
|
34
|
+
data,
|
|
35
|
+
getRowClassName,
|
|
36
|
+
getRowSelected,
|
|
37
|
+
onTdClick,
|
|
38
|
+
propConfig === null || propConfig === void 0 ? void 0 : propConfig.renderCell,
|
|
39
|
+
propName,
|
|
40
|
+
row,
|
|
41
|
+
rowHeight,
|
|
42
|
+
rowIndex,
|
|
43
|
+
style,
|
|
44
|
+
]);
|
|
45
|
+
if (!row || !tdDivProps) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
if (propConfig === null || propConfig === void 0 ? void 0 : propConfig.renderCell) {
|
|
49
|
+
return (_jsx("div", Object.assign({}, tdDivProps, { children: propConfig.renderCell(data[row._index], row._index, rowIndex) })));
|
|
50
|
+
}
|
|
51
|
+
if (propName === SELECT_ALL_COLUMN_NAME) {
|
|
52
|
+
const onChecked = () => {
|
|
53
|
+
if (!onCheckedIndexesChange) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
onCheckedIndexesChange([row._index]);
|
|
57
|
+
};
|
|
58
|
+
return (_jsx("div", Object.assign({}, tdDivProps, { children: _jsx("div", Object.assign({ style: { textAlign: "center" } }, { children: _jsx("input", { "data-key": "row-checkbox", type: "checkbox", onChange: onChecked, checked: checkedIndexes === null || checkedIndexes === void 0 ? void 0 : checkedIndexes.includes(row._index) }) })) })));
|
|
59
|
+
}
|
|
60
|
+
if (!propSchema) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
switch (propSchema.type) {
|
|
64
|
+
case "boolean":
|
|
65
|
+
tdDivProps.className += ` text-${(propConfig === null || propConfig === void 0 ? void 0 : propConfig.align) || "center"}`;
|
|
66
|
+
break;
|
|
67
|
+
case "number":
|
|
68
|
+
case "integer":
|
|
69
|
+
tdDivProps.className += ` text-${(propConfig === null || propConfig === void 0 ? void 0 : propConfig.align) || "end"}`;
|
|
70
|
+
break;
|
|
71
|
+
default:
|
|
72
|
+
if (propConfig === null || propConfig === void 0 ? void 0 : propConfig.align) {
|
|
73
|
+
tdDivProps.className += ` text-${propConfig.align}`;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return _jsx("div", Object.assign({}, tdDivProps, { children: row[propName] }));
|
|
77
|
+
}
|
|
78
|
+
export default React.memo(Td);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { oas31 } from "openapi3-ts";
|
|
2
|
+
import React, { CSSProperties, Dispatch, SetStateAction } from "react";
|
|
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
|
+
}
|
|
10
|
+
interface IThProps {
|
|
11
|
+
columnFilterStatus: EColumnFilterStatus;
|
|
12
|
+
disableColumnFilter: (propName: string) => void;
|
|
13
|
+
isAllChecked?: boolean;
|
|
14
|
+
isSortable: boolean;
|
|
15
|
+
numberOfSelectedRows?: number;
|
|
16
|
+
onSelectAllIndexesHandler?: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
|
17
|
+
propConfig?: IColumnConfig<any>;
|
|
18
|
+
propName: string;
|
|
19
|
+
schema: oas31.SchemaObject;
|
|
20
|
+
setPopoverConfig?: Dispatch<SetStateAction<ISchemaColumnFilterPopoverConfig | undefined>>;
|
|
21
|
+
setSortAsc: Dispatch<SetStateAction<boolean>>;
|
|
22
|
+
setSortColumn: Dispatch<SetStateAction<string>>;
|
|
23
|
+
sortAsc?: boolean;
|
|
24
|
+
style: CSSProperties;
|
|
25
|
+
}
|
|
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;
|
|
27
|
+
export default _default;
|