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.
Files changed (37) hide show
  1. package/README.md +1 -0
  2. package/dist/SchemaTable/ColumnFilterRow/index.d.ts +7 -3
  3. package/dist/SchemaTable/ColumnFilterRow/index.js +65 -15
  4. package/dist/SchemaTable/SchemaColumnFilterPopover/index.d.ts +2 -6
  5. package/dist/SchemaTable/SchemaColumnFilterPopover/index.js +32 -48
  6. package/dist/SchemaTable/Th/index.js +2 -10
  7. package/dist/SchemaTable/index.js +1 -1
  8. package/dist/component/SchemaTable/SchemaColumnFilterPopover/FilterFormComponent/index.d.ts +11 -0
  9. package/dist/component/SchemaTable/SchemaColumnFilterPopover/FilterFormComponent/index.js +76 -0
  10. package/dist/component/SchemaTable/SchemaColumnFilterPopover/index.d.ts +15 -0
  11. package/dist/component/SchemaTable/SchemaColumnFilterPopover/index.js +37 -0
  12. package/dist/component/SchemaTable/Td/index.d.ts +22 -0
  13. package/dist/component/SchemaTable/Td/index.js +78 -0
  14. package/dist/component/SchemaTable/Th/index.d.ts +27 -0
  15. package/dist/component/SchemaTable/Th/index.js +78 -0
  16. package/dist/component/SchemaTable/constants.d.ts +2 -0
  17. package/dist/component/SchemaTable/constants.js +2 -0
  18. package/dist/component/SchemaTable/index.d.ts +34 -0
  19. package/dist/component/SchemaTable/index.js +343 -0
  20. package/dist/component/SchemaTable/index.test.d.ts +1 -0
  21. package/dist/component/SchemaTable/index.test.js +17 -0
  22. package/dist/component/inc/constant.d.ts +2 -0
  23. package/dist/component/inc/constant.js +2 -0
  24. package/dist/component/inc/date.d.ts +1 -0
  25. package/dist/component/inc/date.js +3 -0
  26. package/dist/component/inc/schema.d.ts +2 -0
  27. package/dist/component/inc/schema.js +32 -0
  28. package/dist/component/inc/string.d.ts +1 -0
  29. package/dist/component/inc/string.js +17 -0
  30. package/dist/component/index.d.ts +4 -0
  31. package/dist/component/index.js +2 -0
  32. package/dist/component/types.d.ts +21 -0
  33. package/dist/component/types.js +1 -0
  34. package/dist/exampleData.d.ts +29 -0
  35. package/dist/exampleData.js +177 -0
  36. package/dist/index.css +16 -89
  37. 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: string | number | boolean) => void;
12
+ columnSearchHandler: (propName: string, value: tColumnSearchValue) => void;
11
13
  value: {
12
- [propName: string]: string | number | boolean;
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
- export default function ColumnFilterRow({ columnNames, getWidth, config, value, columnSearchHandler, schema, }) {
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" ? ["true", "false"] : propSchema.enum;
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, propConfig) => {
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 = (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) : "");
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
- 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 }));
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("div", Object.assign({ className: "schema-table__th" }, { children: field(propSchema, propName, propValue, propConfig) }), `filter-col-${propName}`));
54
- }, [columnNames, config, field, properties, value]);
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
- anchorPoint: {
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<(props: TSchemaColumnFilterPopoverProps) => import("react/jsx-runtime").JSX.Element>;
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
- 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) {
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
- }, [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 }) })) })));
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 rect = e.currentTarget.getBoundingClientRect();
39
+ const referenceElement = e.currentTarget;
40
40
  setPopoverConfig((popoverConfig) => {
41
41
  if (popoverConfig) {
42
42
  return undefined;
43
43
  }
44
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
- },
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, { anchorPoint: popoverConfig.anchorPoint, anchorPosition: popoverConfig.anchorPosition, onClose: onPopoverClose, onChange: onSchemaColumnFilterChange, propName: popoverConfig.propName, propSchema: schema.properties[popoverConfig.propName], value: columnFilterMap[popoverConfig.propName] })) : null] })));
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;