mig-schema-table 3.0.60 → 3.0.62
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/SchemaColumnFilterPopover/FilterFormComponent/index.d.ts +1 -1
- package/dist/SchemaTable/SchemaColumnFilterPopover/FilterFormComponent/index.js +2 -2
- package/dist/SchemaTable/index.d.ts +6 -5
- package/dist/SchemaTable/index.js +55 -7
- package/dist/inc/data.d.ts +2 -0
- package/dist/inc/data.js +24 -0
- package/dist/types.d.ts +2 -1
- package/package.json +1 -1
|
@@ -9,7 +9,7 @@ export interface IFilterFormComponentProps {
|
|
|
9
9
|
propConfig?: IColumnConfig<any>;
|
|
10
10
|
propIsRequired: boolean;
|
|
11
11
|
propName: string;
|
|
12
|
-
propSchema
|
|
12
|
+
propSchema?: oas31.SchemaObject;
|
|
13
13
|
}
|
|
14
14
|
declare const _default: React.MemoExoticComponent<({ columnFilterValue, onChange, onInputKeyDown, propConfig, propIsRequired, propName, propSchema, }: IFilterFormComponentProps) => import("react/jsx-runtime").JSX.Element>;
|
|
15
15
|
export default _default;
|
|
@@ -6,7 +6,7 @@ import DatePicker from "react-datepicker";
|
|
|
6
6
|
import nl from "date-fns/locale/nl";
|
|
7
7
|
import { endOfDay } from "date-fns";
|
|
8
8
|
const FilterFormComponent = ({ columnFilterValue, onChange, onInputKeyDown, propConfig, propIsRequired, propName, propSchema, }) => {
|
|
9
|
-
const { type, format, minimum, maximum } = propSchema;
|
|
9
|
+
const { type, format, minimum, maximum } = propSchema || {};
|
|
10
10
|
const value = columnFilterValue;
|
|
11
11
|
switch (type) {
|
|
12
12
|
case "integer":
|
|
@@ -34,7 +34,7 @@ const FilterFormComponent = ({ columnFilterValue, onChange, onInputKeyDown, prop
|
|
|
34
34
|
} }, { children: [_jsx("option", Object.assign({ value: "" }, { children: "All" }), "all"), ["✓", "✕"].map((optionValue) => (_jsx("option", Object.assign({ value: optionValue }, { children: optionValue }), `column-filter-select-${optionValue}`)))] })));
|
|
35
35
|
// @ts-ignore
|
|
36
36
|
case "string":
|
|
37
|
-
if (propSchema.enum) {
|
|
37
|
+
if (propSchema === null || propSchema === void 0 ? void 0 : propSchema.enum) {
|
|
38
38
|
return (_jsxs("select", Object.assign({ autoFocus: true, className: "form-select", value: value, "data-prop-name": propName, onChange: (e) => {
|
|
39
39
|
onChange(e.currentTarget.value || undefined);
|
|
40
40
|
} }, { children: [_jsx("option", Object.assign({ value: "" }, { children: "All" }), "all"), propSchema.enum.map((name) => {
|
|
@@ -15,7 +15,6 @@ interface IColumnFilterMap {
|
|
|
15
15
|
export interface ISchemaTableProps<T> {
|
|
16
16
|
Heading?: any;
|
|
17
17
|
checkedIndexes?: number[];
|
|
18
|
-
disabledCheckedIndexes?: number[];
|
|
19
18
|
config?: {
|
|
20
19
|
[propName: string]: IColumnConfig<T>;
|
|
21
20
|
};
|
|
@@ -24,13 +23,14 @@ export interface ISchemaTableProps<T> {
|
|
|
24
23
|
defaultColumnFilters?: IColumnFilterMap;
|
|
25
24
|
defaultSortAsc?: boolean;
|
|
26
25
|
defaultSortColumn?: keyof T;
|
|
26
|
+
disabledCheckedIndexes?: number[];
|
|
27
|
+
enableAutoFocus?: boolean;
|
|
27
28
|
getRowClassName?: (rowData: T, dataIndex: number, filteredSortedData: IRenderData[]) => string;
|
|
28
29
|
getRowSelected?: (rowData: T, dataIndex: number) => boolean;
|
|
29
|
-
maxHeight?: number;
|
|
30
|
-
isSearchable?: boolean;
|
|
31
|
-
enableAutoFocus?: boolean;
|
|
32
30
|
isColumnFilterable?: boolean;
|
|
31
|
+
isSearchable?: boolean;
|
|
33
32
|
isSortable?: boolean;
|
|
33
|
+
maxHeight?: number;
|
|
34
34
|
onCheckedIndexesChange?: (dataIndex: number[]) => void;
|
|
35
35
|
onRowClick?: (rowData: T, dataIndex: number, event: React.MouseEvent) => void;
|
|
36
36
|
onRowDoubleClick?: (rowData: T, dataIndex: number, event: React.MouseEvent) => void;
|
|
@@ -38,6 +38,7 @@ export interface ISchemaTableProps<T> {
|
|
|
38
38
|
schema: oas31.SchemaObject;
|
|
39
39
|
searchPlaceholder?: string;
|
|
40
40
|
style?: React.CSSProperties;
|
|
41
|
+
useFilterStateHash?: boolean;
|
|
41
42
|
width: number;
|
|
42
43
|
}
|
|
43
44
|
export interface IDateColumnFilterValue {
|
|
@@ -46,6 +47,6 @@ export interface IDateColumnFilterValue {
|
|
|
46
47
|
filterEmpty?: boolean;
|
|
47
48
|
}
|
|
48
49
|
export type TColumnFilterValue = string | number | boolean | IDateColumnFilterValue;
|
|
49
|
-
declare function SchemaTable<T>({ Heading, checkedIndexes,
|
|
50
|
+
declare function SchemaTable<T>({ Heading, checkedIndexes, config, customElement, data, defaultColumnFilters, defaultSortAsc, defaultSortColumn, disabledCheckedIndexes, enableAutoFocus, getRowClassName, getRowSelected, isColumnFilterable, isSearchable, isSortable, maxHeight, onCheckedIndexesChange, onRowClick, onRowDoubleClick, rowHeight, schema, searchPlaceholder, style, useFilterStateHash, width, }: ISchemaTableProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
50
51
|
declare const _default: typeof SchemaTable;
|
|
51
52
|
export default _default;
|
|
@@ -8,6 +8,7 @@ import { SELECT_ALL_COLUMN_NAME, SELECT_ALL_COLUMN_WIDTH } from "./constants";
|
|
|
8
8
|
import Td from "./Td";
|
|
9
9
|
import { DEFAULT_DATE_FORMAT, DEFAULT_DATE_TIME_FORMAT } from "../inc/constant";
|
|
10
10
|
import SchemaColumnFilterPopover from "./SchemaColumnFilterPopover";
|
|
11
|
+
import { parseLocationHash, serializeLocationHash } from "../inc/data";
|
|
11
12
|
const startOfTheWorldDate = new Date("1000-01-01 00:00:00Z");
|
|
12
13
|
function getSortByValue(propSchema, propConfig) {
|
|
13
14
|
var _a;
|
|
@@ -23,14 +24,15 @@ function getSortByValue(propSchema, propConfig) {
|
|
|
23
24
|
propSchema.type === "integer" ||
|
|
24
25
|
!!(propConfig === null || propConfig === void 0 ? void 0 : propConfig.renderCell));
|
|
25
26
|
}
|
|
26
|
-
function SchemaTable({ Heading = VariableSizeList, checkedIndexes,
|
|
27
|
+
function SchemaTable({ Heading = VariableSizeList, checkedIndexes, config, customElement, data, defaultColumnFilters = {}, defaultSortAsc = false, defaultSortColumn, disabledCheckedIndexes, enableAutoFocus, getRowClassName, getRowSelected, isColumnFilterable, isSearchable, isSortable, maxHeight, onCheckedIndexesChange, onRowClick, onRowDoubleClick, rowHeight = 36, schema, searchPlaceholder, style, useFilterStateHash, width, }) {
|
|
27
28
|
const [sortColumn, setSortColumn] = React.useState(defaultSortColumn);
|
|
28
29
|
const [sortAsc, setSortAsc] = React.useState(defaultSortAsc);
|
|
29
|
-
const [searchQuery, setSearchQuery] = React.useState("");
|
|
30
|
-
const [columnFilterMap, setColumnFilterMap] = React.useState(defaultColumnFilters);
|
|
31
30
|
const [popoverConfig, setPopoverConfig] = React.useState();
|
|
32
31
|
const isDataFunction = data instanceof Function;
|
|
33
32
|
const [sourceData, setSourceData] = React.useState(isDataFunction ? undefined : data);
|
|
33
|
+
const [locationHash, setLocationHash] = React.useState(parseLocationHash(window.location.hash));
|
|
34
|
+
const [searchQuery, setSearchQuery] = React.useState(locationHash.searchQuery || "");
|
|
35
|
+
const [columnFilterMap, setColumnFilterMap] = React.useState(locationHash.columnFilterMap || defaultColumnFilters);
|
|
34
36
|
const [isDirty, setIsDirty] = React.useState(false);
|
|
35
37
|
React.useEffect(() => {
|
|
36
38
|
if (isDataFunction) {
|
|
@@ -219,6 +221,11 @@ function SchemaTable({ Heading = VariableSizeList, checkedIndexes, disabledCheck
|
|
|
219
221
|
if (!result || columnFilterValue === undefined) {
|
|
220
222
|
return;
|
|
221
223
|
}
|
|
224
|
+
const propConfig = config ? config[propName] : undefined;
|
|
225
|
+
if (sourceData && (propConfig === null || propConfig === void 0 ? void 0 : propConfig.filter)) {
|
|
226
|
+
result = propConfig.filter(sourceData[item._index], item._index);
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
222
229
|
const propSchema = properties[propName];
|
|
223
230
|
// @ts-ignore
|
|
224
231
|
const rawValue = sourceData[item._index][propName];
|
|
@@ -263,8 +270,9 @@ function SchemaTable({ Heading = VariableSizeList, checkedIndexes, disabledCheck
|
|
|
263
270
|
searchQuery,
|
|
264
271
|
columnNames,
|
|
265
272
|
columnFilterMap,
|
|
266
|
-
|
|
273
|
+
config,
|
|
267
274
|
sourceData,
|
|
275
|
+
properties,
|
|
268
276
|
]);
|
|
269
277
|
// Sort the filtered data
|
|
270
278
|
const sortedRenderData = React.useMemo(() => {
|
|
@@ -365,7 +373,9 @@ function SchemaTable({ Heading = VariableSizeList, checkedIndexes, disabledCheck
|
|
|
365
373
|
? { type: "boolean" }
|
|
366
374
|
: properties[propName]);
|
|
367
375
|
const propConfig = config ? config[propName] : undefined;
|
|
368
|
-
let columnFilterStatus = isColumnFilterable &&
|
|
376
|
+
let columnFilterStatus = isColumnFilterable &&
|
|
377
|
+
(propSchema || (propConfig === null || propConfig === void 0 ? void 0 : propConfig.FilterForm)) &&
|
|
378
|
+
(propConfig === null || propConfig === void 0 ? void 0 : propConfig.isFilterable) !== false
|
|
369
379
|
? EColumnFilterStatus.AVAILABLE
|
|
370
380
|
: EColumnFilterStatus.UNAVAILABLE;
|
|
371
381
|
if (columnFilterMap[propName] !== undefined) {
|
|
@@ -414,8 +424,12 @@ function SchemaTable({ Heading = VariableSizeList, checkedIndexes, disabledCheck
|
|
|
414
424
|
if (isDataFunction) {
|
|
415
425
|
setIsDirty(true);
|
|
416
426
|
}
|
|
427
|
+
if (useFilterStateHash) {
|
|
428
|
+
window.location.hash = serializeLocationHash(Object.assign(Object.assign({}, locationHash), { searchQuery: e.currentTarget.value }));
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
417
431
|
setSearchQuery(e.currentTarget.value);
|
|
418
|
-
}, [isDataFunction]);
|
|
432
|
+
}, [isDataFunction, locationHash, useFilterStateHash]);
|
|
419
433
|
const refreshData = React.useCallback(() => {
|
|
420
434
|
setIsDirty(false);
|
|
421
435
|
setSourceData(undefined);
|
|
@@ -441,6 +455,29 @@ function SchemaTable({ Heading = VariableSizeList, checkedIndexes, disabledCheck
|
|
|
441
455
|
const onPopoverClose = React.useCallback(() => {
|
|
442
456
|
setPopoverConfig(undefined);
|
|
443
457
|
}, []);
|
|
458
|
+
React.useEffect(() => {
|
|
459
|
+
if (!useFilterStateHash) {
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
const onHashChange = () => {
|
|
463
|
+
setLocationHash(parseLocationHash(window.location.hash));
|
|
464
|
+
};
|
|
465
|
+
window.addEventListener("hashchange", onHashChange);
|
|
466
|
+
return () => {
|
|
467
|
+
window.removeEventListener("hashchange", onHashChange);
|
|
468
|
+
};
|
|
469
|
+
}, [useFilterStateHash]);
|
|
470
|
+
React.useEffect(() => {
|
|
471
|
+
if (!useFilterStateHash) {
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
if (locationHash.columnFilterMap) {
|
|
475
|
+
setColumnFilterMap(locationHash.columnFilterMap);
|
|
476
|
+
}
|
|
477
|
+
if (locationHash.searchQuery !== undefined) {
|
|
478
|
+
setSearchQuery(locationHash.searchQuery);
|
|
479
|
+
}
|
|
480
|
+
}, [locationHash, useFilterStateHash]);
|
|
444
481
|
const onSchemaColumnFilterChange = React.useCallback((newColumnFilterValue) => {
|
|
445
482
|
if (!popoverConfig) {
|
|
446
483
|
return;
|
|
@@ -452,8 +489,19 @@ function SchemaTable({ Heading = VariableSizeList, checkedIndexes, disabledCheck
|
|
|
452
489
|
disableColumnFilter(popoverConfig.propName);
|
|
453
490
|
return;
|
|
454
491
|
}
|
|
492
|
+
if (useFilterStateHash) {
|
|
493
|
+
window.location.hash = serializeLocationHash(Object.assign(Object.assign({}, locationHash), { columnFilterMap: Object.assign(Object.assign({}, columnFilterMap), { [popoverConfig.propName]: newColumnFilterValue }) }));
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
455
496
|
setColumnFilterMap((columnFilterMap) => (Object.assign(Object.assign({}, columnFilterMap), { [popoverConfig.propName]: newColumnFilterValue })));
|
|
456
|
-
}, [
|
|
497
|
+
}, [
|
|
498
|
+
columnFilterMap,
|
|
499
|
+
disableColumnFilter,
|
|
500
|
+
isDataFunction,
|
|
501
|
+
locationHash,
|
|
502
|
+
popoverConfig,
|
|
503
|
+
useFilterStateHash,
|
|
504
|
+
]);
|
|
457
505
|
const searchInputAutoFocus = React.useMemo(() => {
|
|
458
506
|
if (enableAutoFocus === undefined) {
|
|
459
507
|
return true;
|
package/dist/inc/data.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export const parseLocationHash = (search) => {
|
|
2
|
+
if (!search.length) {
|
|
3
|
+
return {};
|
|
4
|
+
}
|
|
5
|
+
const result = {};
|
|
6
|
+
search
|
|
7
|
+
.substring(1)
|
|
8
|
+
.split("&")
|
|
9
|
+
.forEach((pair) => {
|
|
10
|
+
if (!pair) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const splitPair = pair.split("=");
|
|
14
|
+
if (splitPair.length !== 2) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
// @ts-ignore
|
|
18
|
+
result[decodeURIComponent(splitPair[0])] = JSON.parse(decodeURIComponent(splitPair[1]));
|
|
19
|
+
});
|
|
20
|
+
return result;
|
|
21
|
+
};
|
|
22
|
+
export const serializeLocationHash = (params) => `${Object.entries(params)
|
|
23
|
+
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(JSON.stringify(value))}`)
|
|
24
|
+
.join("&")}`;
|
package/dist/types.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { IFilterFormComponentProps } from "./SchemaTable/SchemaColumnFilterPopover/FilterFormComponent";
|
|
3
3
|
export interface IColumnConfig<T> {
|
|
4
|
+
FilterForm?: (props: IFilterFormComponentProps) => React.ReactElement | null;
|
|
4
5
|
align?: "start" | "center" | "end";
|
|
5
6
|
dateFormat?: string;
|
|
6
7
|
defaultSortDesc?: boolean;
|
|
7
|
-
|
|
8
|
+
filter?: (rowData: T, dataIndex: number) => boolean;
|
|
8
9
|
hidden?: boolean;
|
|
9
10
|
hoverTitle?: string;
|
|
10
11
|
isFilterable?: boolean;
|