mig-schema-table 3.0.92 → 3.0.94

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.
@@ -11,25 +11,43 @@ var __rest = (this && this.__rest) || function (s, e) {
11
11
  };
12
12
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
13
  import React from "react";
14
- import { DEFAULT_DATE_FORMAT, DEFAULT_DATE_TIME_FORMAT, } from "../../../inc/constant";
14
+ import { DEFAULT_DATE_FORMAT, DEFAULT_DATE_TIME_FORMAT, ENumberColumnFilterOperation, } from "../../../inc/constant";
15
15
  import DatePicker from "react-datepicker";
16
16
  import nl from "date-fns/locale/nl";
17
17
  import { endOfDay } from "date-fns";
18
+ const numberColumnFilterOperationsLabelMap = {
19
+ [ENumberColumnFilterOperation.GT]: ">",
20
+ [ENumberColumnFilterOperation.LT]: "<",
21
+ [ENumberColumnFilterOperation.EQ]: "=",
22
+ };
18
23
  const FilterMenuComponent = ({ columnFilterValue, onChange, onInputKeyDown, propIsRequired, propName, propSchema, translate, }) => {
19
24
  const { type, format, minimum, maximum } = propSchema || {};
20
25
  const value = columnFilterValue;
21
26
  const isDateTime = format === "date-time";
22
27
  switch (type) {
28
+ case "number":
23
29
  case "integer":
24
- return (_jsx("ol", Object.assign({ className: "schema-table-menu schema-table__th-menu__filter-menu-component" }, { children: _jsx("li", { children: _jsx("input", { autoFocus: true, className: "form-control", type: "number", value: (value || ""), "data-prop-name": propName, onChange: (e) => {
25
- onChange(e.currentTarget.value === ""
26
- ? undefined
27
- : parseInt(e.currentTarget.value), false);
28
- }, onBlur: (e) => {
29
- onChange(e.currentTarget.value === ""
30
- ? undefined
31
- : parseInt(e.currentTarget.value), true);
32
- }, onKeyDown: onInputKeyDown, placeholder: `Search ${propName}`, min: minimum, max: maximum }) }) })));
30
+ const numberColumnFilterValue = (value || {});
31
+ const changeOperationValue = (operation, el, persistState) => {
32
+ const newValue = Object.assign(Object.assign({}, numberColumnFilterValue), { [operation]: el.value === "" ? undefined : parseInt(el.value) });
33
+ const hasValue = Object.values(newValue).find((opValue) => isFinite(opValue));
34
+ onChange(hasValue ? newValue : undefined, persistState);
35
+ };
36
+ return (_jsxs("ol", Object.assign({ className: "schema-table-menu schema-table__th-menu__filter-menu-component" }, { children: [propIsRequired ? null : (_jsxs("li", Object.assign({ style: { padding: 8 } }, { children: [_jsxs("label", Object.assign({ className: "d-flex" }, { children: [_jsx("input", { type: "checkbox", style: { marginRight: 14 }, checked: !!numberColumnFilterValue.filterEmpty, onChange: () => {
37
+ const { filterEmpty } = numberColumnFilterValue, newNumberColumnFilterValue = __rest(numberColumnFilterValue, ["filterEmpty"]);
38
+ if (!filterEmpty) {
39
+ newNumberColumnFilterValue.filterEmpty = true;
40
+ }
41
+ onChange(Object.keys(newNumberColumnFilterValue).length
42
+ ? newNumberColumnFilterValue
43
+ : undefined, true);
44
+ } }), "Hide empty values"] })), _jsx("hr", {})] }))), Object.keys(ENumberColumnFilterOperation).map((operation) => {
45
+ return (_jsxs("li", { children: [_jsx("label", Object.assign({ style: { width: 40, paddingLeft: 16 } }, { children: numberColumnFilterOperationsLabelMap[operation] })), _jsx("input", { className: "form-control", style: { width: 120 }, type: "number", value: numberColumnFilterValue[operation] || "", "data-prop-name": propName, onChange: (e) => {
46
+ changeOperationValue(operation, e.currentTarget, false);
47
+ }, onBlur: (e) => {
48
+ changeOperationValue(operation, e.currentTarget, true);
49
+ }, onKeyDown: onInputKeyDown, min: minimum, max: maximum })] }, operation));
50
+ })] })));
33
51
  case "boolean":
34
52
  let selectValue = value ? "✓" : "✕";
35
53
  if (value === undefined) {
@@ -65,7 +83,7 @@ const FilterMenuComponent = ({ columnFilterValue, onChange, onInputKeyDown, prop
65
83
  to: undefined,
66
84
  filterEmpty: undefined,
67
85
  });
68
- return (_jsxs("ol", Object.assign({ className: "schema-table-menu schema-table__th-menu__filter-menu-component" }, { children: [propIsRequired ? null : (_jsxs("li", Object.assign({ style: { padding: 8 } }, { children: [_jsxs("label", Object.assign({ className: "d-flex" }, { children: [_jsx("input", { type: "checkbox", className: "m-0 me-1", checked: !!dateRangeValue.filterEmpty, onChange: () => {
86
+ return (_jsxs("ol", Object.assign({ className: "schema-table-menu schema-table__th-menu__filter-menu-component" }, { children: [propIsRequired ? null : (_jsxs("li", Object.assign({ style: { padding: 8 } }, { children: [_jsxs("label", Object.assign({ className: "d-flex" }, { children: [_jsx("input", { type: "checkbox", checked: !!dateRangeValue.filterEmpty, onChange: () => {
69
87
  const { filterEmpty } = dateRangeValue, newDateRangeValue = __rest(dateRangeValue, ["filterEmpty"]);
70
88
  if (!filterEmpty) {
71
89
  newDateRangeValue.filterEmpty = true;
@@ -1,6 +1,7 @@
1
1
  import React from "react";
2
2
  import { oas31 } from "openapi3-ts";
3
3
  import { IColumnConfig, IRenderData } from "../types";
4
+ import { ENumberColumnFilterOperation } from "../inc/constant";
4
5
  export interface IGetDataProps {
5
6
  searchQuery: string;
6
7
  columnFilterMap: {
@@ -25,6 +26,7 @@ export interface ISchemaTableProps<T> {
25
26
  defaultSortColumn?: keyof T;
26
27
  disabledCheckedIndexes?: number[];
27
28
  enableAutoFocus?: boolean;
29
+ enableRowCounter?: boolean;
28
30
  getRowClassName?: (rowData: T, dataIndex: number, filteredSortedData: IRenderData[]) => string;
29
31
  getRowSelected?: (rowData: T, dataIndex: number) => boolean;
30
32
  isColumnFilterable?: boolean;
@@ -49,7 +51,13 @@ export interface IDateColumnFilterValue {
49
51
  to?: Date;
50
52
  filterEmpty?: true;
51
53
  }
52
- export type TColumnFilterValue = string | number | boolean | IDateColumnFilterValue;
53
- declare function SchemaTable<T>({ Heading, checkedIndexes, config, customElement, data, defaultColumnFilters, defaultSortAsc, defaultSortColumn, disabledCheckedIndexes, enableAutoFocus, getRowClassName, getRowSelected, isColumnFilterable, isExportable, isSearchable, isSortable, maxHeight, onCheckedIndexesChange, onRowClick, onRowDoubleClick, onSearchEnter, rowHeight, schema, searchPlaceholder, style, translate, useFilterStateHash, width, }: ISchemaTableProps<T>): import("react/jsx-runtime").JSX.Element;
54
+ export interface INumberColumnFilterValue {
55
+ [ENumberColumnFilterOperation.GT]: number;
56
+ [ENumberColumnFilterOperation.LT]: number;
57
+ [ENumberColumnFilterOperation.EQ]: number;
58
+ filterEmpty?: true;
59
+ }
60
+ export type TColumnFilterValue = string | boolean | IDateColumnFilterValue | INumberColumnFilterValue;
61
+ declare function SchemaTable<T>({ Heading, checkedIndexes, config, customElement, data, defaultColumnFilters, defaultSortAsc, defaultSortColumn, disabledCheckedIndexes, enableAutoFocus, enableRowCounter, getRowClassName, getRowSelected, isColumnFilterable, isExportable, isSearchable, isSortable, maxHeight, onCheckedIndexesChange, onRowClick, onRowDoubleClick, onSearchEnter, rowHeight, schema, searchPlaceholder, style, translate, useFilterStateHash, width, }: ISchemaTableProps<T>): import("react/jsx-runtime").JSX.Element;
54
62
  declare const _default: typeof SchemaTable;
55
63
  export default _default;
@@ -16,7 +16,7 @@ import { localeFormat } from "../inc/date";
16
16
  import { defaultTranslate } from "../inc/string";
17
17
  import { SELECT_ALL_COLUMN_NAME, SELECT_ALL_COLUMN_WIDTH } from "./constants";
18
18
  import Td from "./Td";
19
- import { DEFAULT_DATE_FORMAT, DEFAULT_DATE_TIME_FORMAT } from "../inc/constant";
19
+ import { DEFAULT_DATE_FORMAT, DEFAULT_DATE_TIME_FORMAT, ENumberColumnFilterOperation, } from "../inc/constant";
20
20
  import { parseLocationHash, serializeLocationHash } from "../inc/data";
21
21
  import Th, { EColumnFilterStatus } from "./Th";
22
22
  import ThMenu from "./ThMenu";
@@ -46,7 +46,7 @@ function getIsColumnSortable(isTableSortable, propSchema, propConfig) {
46
46
  return !!(isTableSortable &&
47
47
  (propSchema || (propConfig === null || propConfig === void 0 ? void 0 : propConfig.renderData) || (propConfig === null || propConfig === void 0 ? void 0 : propConfig.sort)));
48
48
  }
49
- function SchemaTable({ Heading = VariableSizeList, checkedIndexes, config, customElement, data, defaultColumnFilters = {}, defaultSortAsc = false, defaultSortColumn, disabledCheckedIndexes, enableAutoFocus, getRowClassName, getRowSelected, isColumnFilterable = true, isExportable = true, isSearchable = true, isSortable = true, maxHeight, onCheckedIndexesChange, onRowClick, onRowDoubleClick, onSearchEnter, rowHeight = 36, schema, searchPlaceholder, style, translate = defaultTranslate, useFilterStateHash, width, }) {
49
+ function SchemaTable({ Heading = VariableSizeList, checkedIndexes, config, customElement, data, defaultColumnFilters = {}, defaultSortAsc = false, defaultSortColumn, disabledCheckedIndexes, enableAutoFocus = true, enableRowCounter = true, getRowClassName, getRowSelected, isColumnFilterable = true, isExportable = true, isSearchable = true, isSortable = true, maxHeight, onCheckedIndexesChange, onRowClick, onRowDoubleClick, onSearchEnter, rowHeight = 36, schema, searchPlaceholder, style, translate = defaultTranslate, useFilterStateHash, width, }) {
50
50
  const [sortColumn, setSortColumn] = React.useState(defaultSortColumn);
51
51
  const [sortAsc, setSortAsc] = React.useState(defaultSortAsc);
52
52
  const [thMenuConfig, setThMenuConfig] = React.useState();
@@ -255,8 +255,38 @@ function SchemaTable({ Heading = VariableSizeList, checkedIndexes, config, custo
255
255
  const rawValue = sourceData[item._index][propName];
256
256
  switch (propSchema === null || propSchema === void 0 ? void 0 : propSchema.type) {
257
257
  case "boolean":
258
+ case "number":
258
259
  case "integer":
259
- result = rawValue === columnFilterValue;
260
+ if (typeof columnFilterValue === "object") {
261
+ if (columnFilterValue.filterEmpty && rawValue === undefined) {
262
+ result = false;
263
+ }
264
+ for (const operation of Object.keys(ENumberColumnFilterOperation)) {
265
+ const operationFilterValue = columnFilterValue[operation];
266
+ if (result && isFinite(operationFilterValue)) {
267
+ switch (operation) {
268
+ case ENumberColumnFilterOperation.EQ:
269
+ if (rawValue !== operationFilterValue) {
270
+ result = false;
271
+ }
272
+ break;
273
+ case ENumberColumnFilterOperation.GT:
274
+ if (rawValue <= operationFilterValue) {
275
+ result = false;
276
+ }
277
+ break;
278
+ case ENumberColumnFilterOperation.LT:
279
+ if (rawValue >= operationFilterValue) {
280
+ result = false;
281
+ }
282
+ break;
283
+ }
284
+ }
285
+ }
286
+ }
287
+ else {
288
+ result = rawValue === columnFilterValue;
289
+ }
260
290
  break;
261
291
  // @ts-ignore
262
292
  case "string":
@@ -532,12 +562,6 @@ function SchemaTable({ Heading = VariableSizeList, checkedIndexes, config, custo
532
562
  thMenuConfig,
533
563
  useFilterStateHash,
534
564
  ]);
535
- const searchInputAutoFocus = React.useMemo(() => {
536
- if (enableAutoFocus === undefined) {
537
- return true;
538
- }
539
- return enableAutoFocus;
540
- }, [enableAutoFocus]);
541
565
  const onClearFiltersButtonClick = React.useCallback(() => {
542
566
  if (useFilterStateHash) {
543
567
  window.location.hash = "";
@@ -569,7 +593,7 @@ function SchemaTable({ Heading = VariableSizeList, checkedIndexes, config, custo
569
593
  type: "text/csv;charset=utf-8",
570
594
  }), "export.csv");
571
595
  }, [sortedRenderData]);
572
- 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", { children: isSearchable ? (_jsx("input", { className: "schema-table__search", type: "text", placeholder: searchPlaceholder || "Search...", value: searchQuery, onChange: onSearchChange, onKeyDown: onInputKeyDown, autoFocus: searchInputAutoFocus, onBlur: onSearchBlur })) : null }), customElement || (_jsx("div", { className: "schema-table__custom_element_placeholder" })), isExportable ? (_jsx("button", Object.assign({ onClick: onExportDataClick, style: { marginLeft: 8 }, disabled: !(sortedRenderData === null || sortedRenderData === void 0 ? void 0 : sortedRenderData.length) }, { children: "Export data" }))) : null, isSearchable || isColumnFilterable ? (_jsx("button", Object.assign({ onClick: onClearFiltersButtonClick, style: { marginLeft: 8 }, disabled: Object.keys(columnFilterMap).length + searchQuery.length === 0 }, { children: "Clear filters" }))) : null] })), _jsx(Heading, Object.assign({ height: 50, itemCount: columnCount, itemSize: getColumnWidth, layout: "horizontal", width: rowWidth, sortAsc: sortAsc, setSortAsc: onSetSortAsc, setSortColumn: onSetSortColumn, sortColumn: sortColumn, sortedRenderData: sortedRenderData, className: "schema-table__th-row" }, { children: ConfiguredTh }), `thead_${rowWidth}_${sortColumn}_${sortAsc}_${searchQuery}`), sourceData && !isDirty ? (_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}`)) : (_jsx("div", Object.assign({ style: {
596
+ 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", { children: isSearchable ? (_jsx("input", { className: "schema-table__search", type: "text", placeholder: searchPlaceholder || "Search...", value: searchQuery, onChange: onSearchChange, onKeyDown: onInputKeyDown, autoFocus: enableAutoFocus, onBlur: onSearchBlur })) : null }), customElement || (_jsx("div", { className: "schema-table__custom_element_placeholder" })), enableRowCounter ? (_jsx("span", Object.assign({ className: "schema-table__row_counter" }, { children: translate("showingFilteredCountOfTotalCount", (sortedRenderData === null || sortedRenderData === void 0 ? void 0 : sortedRenderData.length) || 0, data.length) }))) : null, isExportable ? (_jsx("button", Object.assign({ onClick: onExportDataClick, style: { marginLeft: 8 }, disabled: !(sortedRenderData === null || sortedRenderData === void 0 ? void 0 : sortedRenderData.length) }, { children: translate("exportData") }))) : null, isSearchable || isColumnFilterable ? (_jsx("button", Object.assign({ onClick: onClearFiltersButtonClick, style: { marginLeft: 8 }, disabled: Object.keys(columnFilterMap).length + searchQuery.length === 0 }, { children: translate("clearFilters") }))) : null] })), _jsx(Heading, Object.assign({ height: 50, itemCount: columnCount, itemSize: getColumnWidth, layout: "horizontal", width: rowWidth, sortAsc: sortAsc, setSortAsc: onSetSortAsc, setSortColumn: onSetSortColumn, sortColumn: sortColumn, sortedRenderData: sortedRenderData, className: "schema-table__th-row" }, { children: ConfiguredTh }), `thead_${rowWidth}_${sortColumn}_${sortAsc}_${searchQuery}`), sourceData && !isDirty ? (_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}`)) : (_jsx("div", Object.assign({ style: {
573
597
  width: rowWidth,
574
598
  height: Math.max(50, tableBodyHeight),
575
599
  border: "1px solid #BBB",
@@ -1,2 +1,7 @@
1
1
  export declare const DEFAULT_DATE_FORMAT = "dd MMM yyyy";
2
2
  export declare const DEFAULT_DATE_TIME_FORMAT = "dd MMM yyyy HH:mm";
3
+ export declare enum ENumberColumnFilterOperation {
4
+ "GT" = "GT",
5
+ "LT" = "LT",
6
+ "EQ" = "EQ"
7
+ }
@@ -1,2 +1,8 @@
1
1
  export const DEFAULT_DATE_FORMAT = "dd MMM yyyy";
2
2
  export const DEFAULT_DATE_TIME_FORMAT = "dd MMM yyyy HH:mm";
3
+ export var ENumberColumnFilterOperation;
4
+ (function (ENumberColumnFilterOperation) {
5
+ ENumberColumnFilterOperation["GT"] = "GT";
6
+ ENumberColumnFilterOperation["LT"] = "LT";
7
+ ENumberColumnFilterOperation["EQ"] = "EQ";
8
+ })(ENumberColumnFilterOperation || (ENumberColumnFilterOperation = {}));
@@ -20,6 +20,7 @@ const db = {
20
20
  "Europe/Berlin": "AMS",
21
21
  "Asia/Jakarta": "JKT",
22
22
  "Asia/Bangkok": "JKT",
23
+ showingFilteredCountOfTotalCount: "Showing {0} of {1}",
23
24
  };
24
25
  export function defaultTranslate(key, ...args) {
25
26
  let string = db[key] || uncamel(key);
package/dist/index.css CHANGED
@@ -44,6 +44,9 @@
44
44
  padding-bottom: 1rem;
45
45
  align-items: center;
46
46
  }
47
+ .schema-table__row_counter {
48
+ font-size: 0.835rem;
49
+ }
47
50
 
48
51
  .schema-table__th {
49
52
  background-color: #fcfcfc;
package/dist/types.d.ts CHANGED
@@ -18,9 +18,6 @@ export interface IColumnConfig<T> {
18
18
  sortByValue?: boolean;
19
19
  sortable?: boolean;
20
20
  title?: string | React.ReactElement;
21
- translation?: {
22
- [keyName: string]: string;
23
- };
24
21
  width?: number;
25
22
  }
26
23
  export interface IRenderData {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mig-schema-table",
3
- "version": "3.0.92",
3
+ "version": "3.0.94",
4
4
  "main": "dist/index.js",
5
5
  "files": [
6
6
  "dist/"