mig-schema-table 1.0.12 → 2.0.1

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 CHANGED
@@ -34,7 +34,7 @@ const userSchema ={
34
34
  ```
35
35
  ```typescript jsx
36
36
  import React from 'react';
37
- import { SchemaTableComponent, IColumnConfig } from "mig-schema-table";
37
+ import { SchemaTable, IColumnConfig } from "mig-schema-table";
38
38
  import "mig-schema-table/dist/index.css";
39
39
 
40
40
  const config:{[keyName: string]: IColumnConfig} ={
@@ -1,5 +1,5 @@
1
1
  import { oas31 } from "openapi3-ts";
2
- import { CSSProperties, Dispatch, SetStateAction } from "react";
2
+ import React, { CSSProperties, Dispatch, SetStateAction } from "react";
3
3
  import { IColumnConfig } from "../../../types/type";
4
4
  interface IThProps {
5
5
  columnFilters?: {
@@ -16,6 +16,9 @@ interface IThProps {
16
16
  setSortColumn: Dispatch<SetStateAction<string>>;
17
17
  sortAsc?: boolean;
18
18
  style: CSSProperties;
19
+ onSelectAllIndexesHandler?: (e: React.ChangeEvent<HTMLInputElement>) => void;
20
+ isAllChecked?: boolean;
21
+ numberOfSelectedRows?: number;
19
22
  }
20
- declare const _default: ({ columnFilters, config, isSortable, name, schema, setColumnFilters, setSortAsc, setSortColumn, sortAsc, style, }: IThProps) => import("react/jsx-runtime").JSX.Element;
23
+ declare const _default: ({ columnFilters, config, isSortable, name, schema, setColumnFilters, setSortAsc, setSortColumn, sortAsc, style, onSelectAllIndexesHandler, isAllChecked, numberOfSelectedRows, }: IThProps) => import("react/jsx-runtime").JSX.Element;
21
24
  export default _default;
@@ -1,12 +1,13 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import React from "react";
3
3
  import { uncamel } from "../../../inc/string";
4
- const Th = ({ columnFilters, config, isSortable, name, schema, setColumnFilters, setSortAsc, setSortColumn, sortAsc, style, }) => {
4
+ import { SELECT_ALL_COLUMN_NAME } from "../constants";
5
+ const Th = ({ columnFilters, config, isSortable, name, schema, setColumnFilters, setSortAsc, setSortColumn, sortAsc, style, onSelectAllIndexesHandler, isAllChecked, numberOfSelectedRows, }) => {
5
6
  const thDivProps = {
6
7
  style,
7
8
  className: `schema-table__th ${isSortable ? "schema-table__th--sortable" : "schema-table__th--unsortable"}`,
8
9
  };
9
- const onFilterButtonClick = React.useCallback((e) => {
10
+ const onFilterButtonClick = React.useCallback(() => {
10
11
  if (!setColumnFilters) {
11
12
  return;
12
13
  }
@@ -23,6 +24,9 @@ const Th = ({ columnFilters, config, isSortable, name, schema, setColumnFilters,
23
24
  }
24
25
  setSortAsc((sortAsc) => !sortAsc);
25
26
  }, [config === null || config === void 0 ? void 0 : config.defaultSortDesc, name, setSortAsc, setSortColumn, sortAsc]);
27
+ if (name === SELECT_ALL_COLUMN_NAME) {
28
+ return (_jsx("div", Object.assign({}, thDivProps, { children: _jsx("div", Object.assign({ style: { marginTop: 12 }, title: `${numberOfSelectedRows || 0} selected` }, { children: _jsx("input", { type: "checkbox", checked: isAllChecked, onChange: onSelectAllIndexesHandler }) })) })));
29
+ }
26
30
  if (!schema) {
27
31
  return _jsx("div", Object.assign({}, thDivProps));
28
32
  }
@@ -39,6 +43,6 @@ const Th = ({ columnFilters, config, isSortable, name, schema, setColumnFilters,
39
43
  thDivProps.className += ` text-${(config === null || config === void 0 ? void 0 : config.align) || "end"}`;
40
44
  }
41
45
  }
42
- return (_jsxs("div", Object.assign({}, thDivProps, { children: [isSortable ? (_jsxs("button", Object.assign({ className: "px-0", disabled: (config === null || config === void 0 ? void 0 : config.sortable) === false, onClick: onSortButtonClick }, { children: [(config === null || config === void 0 ? void 0 : config.title) || uncamel(name), sortAsc === undefined ? null : sortAsc ? "▲" : "▼"] }))) : (_jsx("div", Object.assign({ style: { lineHeight: "44px" } }, { children: (config === null || config === void 0 ? void 0 : config.title) || uncamel(name) }))), (config === null || config === void 0 ? void 0 : config.isFilterable) ? (_jsx("button", Object.assign({ onClick: onFilterButtonClick }, { children: _jsx("svg", Object.assign({ viewBox: "0 0 36 36", xmlns: "http://www.w3.org/2000/svg", height: 16, width: 16, style: { display: "block" } }, { children: _jsx("polygon", { fill: "#231F20", points: "14,30 22,25 22,17 35.999,0 17.988,0 0,0 14,17 " }) })) }))) : null] })));
46
+ return (_jsxs("div", Object.assign({}, thDivProps, { children: [isSortable ? (_jsxs("button", Object.assign({ className: "px-0", disabled: (config === null || config === void 0 ? void 0 : config.sortable) === false, onClick: onSortButtonClick }, { children: [(config === null || config === void 0 ? void 0 : config.title) === undefined ? uncamel(name) : config === null || config === void 0 ? void 0 : config.title, sortAsc === undefined ? null : sortAsc ? "▲" : "▼"] }))) : (_jsx("div", Object.assign({ style: { lineHeight: "44px" } }, { children: (config === null || config === void 0 ? void 0 : config.title) === undefined ? uncamel(name) : config === null || config === void 0 ? void 0 : config.title }))), (config === null || config === void 0 ? void 0 : config.isFilterable) ? (_jsx("button", Object.assign({ onClick: onFilterButtonClick }, { children: _jsx("svg", Object.assign({ viewBox: "0 0 36 36", xmlns: "http://www.w3.org/2000/svg", height: 16, width: 16, style: { display: "block" } }, { children: _jsx("polygon", { fill: "#231F20", points: "14,30 22,25 22,17 35.999,0 17.988,0 0,0 14,17 " }) })) }))) : null] })));
43
47
  };
44
48
  export default React.memo(Th);
@@ -0,0 +1 @@
1
+ export declare const SELECT_ALL_COLUMN_NAME = "SELECT_ALL_COLUMN_NAME";
@@ -0,0 +1 @@
1
+ export const SELECT_ALL_COLUMN_NAME = "SELECT_ALL_COLUMN_NAME";
@@ -22,5 +22,7 @@ export interface ISchemaTableComponentProps<T> {
22
22
  customElement?: React.ReactNode;
23
23
  tableTitle?: string;
24
24
  searchPlaceholder?: string;
25
+ onCheckedIndexesChange?: (rowIndex: number[]) => void;
26
+ checkedIndexes?: number[];
25
27
  }
26
- export default function SchemaTableComponent<T>(props: ISchemaTableComponentProps<T>): import("react/jsx-runtime").JSX.Element;
28
+ export default function SchemaTable<T>(props: ISchemaTableComponentProps<T>): import("react/jsx-runtime").JSX.Element;
@@ -4,8 +4,9 @@ import { VariableSizeList, VariableSizeGrid } from "react-window";
4
4
  import { localeFormat } from "../../inc/date";
5
5
  import { uncamel } from "../../inc/string";
6
6
  import Th from "./Th";
7
- export default function SchemaTableComponent(props) {
8
- const { config, data, defaultSortColumn, defaultSortAsc = false, Heading = VariableSizeList, isSearchable, isSortable, onRowClick, getRowClassName, getRowSelected, rowHeight = 36, schema, style, customElement, tableTitle, searchPlaceholder } = props;
7
+ import { SELECT_ALL_COLUMN_NAME } from "./constants";
8
+ export default function SchemaTable(props) {
9
+ const { config, data, defaultSortColumn, defaultSortAsc = false, Heading = VariableSizeList, isSearchable, isSortable, onRowClick, getRowClassName, getRowSelected, rowHeight = 36, schema, style, customElement, tableTitle, searchPlaceholder, onCheckedIndexesChange, checkedIndexes, } = props;
9
10
  const [sortColumn, setSortColumn] = React.useState(defaultSortColumn);
10
11
  const [sortAsc, setSortAsc] = React.useState(defaultSortAsc);
11
12
  const [searchQuery, setSearchQuery] = React.useState("");
@@ -13,6 +14,9 @@ export default function SchemaTableComponent(props) {
13
14
  const { properties = {} } = schema;
14
15
  const columnNames = React.useMemo(() => {
15
16
  const columns = Object.keys(properties);
17
+ if (onCheckedIndexesChange) {
18
+ columns.unshift(SELECT_ALL_COLUMN_NAME);
19
+ }
16
20
  if (!config) {
17
21
  return columns;
18
22
  }
@@ -33,6 +37,10 @@ export default function SchemaTableComponent(props) {
33
37
  if (orderB === undefined) {
34
38
  orderB = Object.keys(properties).findIndex((propName) => propName === columnB);
35
39
  }
40
+ if (columnB === SELECT_ALL_COLUMN_NAME ||
41
+ columnA === SELECT_ALL_COLUMN_NAME) {
42
+ return 0;
43
+ }
36
44
  if (orderA === -1) {
37
45
  return 1;
38
46
  }
@@ -41,7 +49,7 @@ export default function SchemaTableComponent(props) {
41
49
  }
42
50
  return orderA - orderB;
43
51
  });
44
- }, [config, properties]);
52
+ }, [config, onCheckedIndexesChange, properties]);
45
53
  const renderData = React.useMemo(() => data
46
54
  ? data.map((object, rowIndex) => columnNames.reduce((prev, propName) => {
47
55
  const schema = properties[propName];
@@ -50,6 +58,10 @@ export default function SchemaTableComponent(props) {
50
58
  prev[propName] = propConfig.renderData(object, rowIndex);
51
59
  return prev;
52
60
  }
61
+ if (propName === SELECT_ALL_COLUMN_NAME) {
62
+ prev[propName] = "asd";
63
+ return prev;
64
+ }
53
65
  if (!schema) {
54
66
  prev[propName] = "?";
55
67
  return prev;
@@ -81,7 +93,7 @@ export default function SchemaTableComponent(props) {
81
93
  return prev;
82
94
  }
83
95
  if (schema.enum) {
84
- prev[propName] = rawValue ? uncamel(rawValue) : '';
96
+ prev[propName] = rawValue ? uncamel(rawValue) : "";
85
97
  return prev;
86
98
  }
87
99
  // fallthrough
@@ -108,23 +120,14 @@ export default function SchemaTableComponent(props) {
108
120
  const dynamicColumnWidth = Math.floor((gridWidth - 16 - fixedWidthColumnsWidth) / dynamicWidthColumnCount);
109
121
  const columnWidths = columnNames.map((propName) => {
110
122
  const propConfig = config ? config[propName] : undefined;
123
+ if (propName === SELECT_ALL_COLUMN_NAME) {
124
+ return 50;
125
+ }
111
126
  return (propConfig === null || propConfig === void 0 ? void 0 : propConfig.width) || dynamicColumnWidth;
112
127
  });
113
128
  return { columnWidths, dynamicWidthColumnCount, fixedWidthColumnsWidth };
114
129
  }, [columnNames, config, gridWidth]);
115
130
  const getColumnWidth = React.useCallback((columnIndex) => columnWidths[columnIndex], [columnWidths]);
116
- const SchemaTableTh = React.useCallback(({ style, index }) => {
117
- const propName = columnNames[index];
118
- return (_jsx(Th, { columnFilters: columnFilters, config: config ? config[propName] : undefined, isSortable: !!isSortable, name: propName, schema: properties[propName], setColumnFilters: setColumnFilters, setSortColumn: setSortColumn, setSortAsc: setSortAsc, sortAsc: sortColumn === propName ? sortAsc : undefined, style: style }));
119
- }, [
120
- columnFilters,
121
- columnNames,
122
- config,
123
- isSortable,
124
- properties,
125
- sortAsc,
126
- sortColumn,
127
- ]);
128
131
  const filteredRenderData = React.useMemo(() => {
129
132
  let result = renderData;
130
133
  if (!result) {
@@ -188,6 +191,30 @@ export default function SchemaTableComponent(props) {
188
191
  return (x < y ? 1 : -1) * (sortAsc ? -1 : 1);
189
192
  });
190
193
  }, [config, data, filteredRenderData, properties, sortAsc, sortColumn]);
194
+ const onSelectAllIndexesHandler = React.useCallback(() => {
195
+ if (!onCheckedIndexesChange || !filteredRenderData) {
196
+ return;
197
+ }
198
+ onCheckedIndexesChange(filteredRenderData.map((el) => el._index));
199
+ }, [onCheckedIndexesChange, filteredRenderData]);
200
+ const isAllRowsChecked = React.useMemo(() => {
201
+ return (checkedIndexes === null || checkedIndexes === void 0 ? void 0 : checkedIndexes.length) === (filteredRenderData === null || filteredRenderData === void 0 ? void 0 : filteredRenderData.length);
202
+ }, [checkedIndexes, filteredRenderData]);
203
+ const SchemaTableTh = React.useCallback(({ style, index }) => {
204
+ const propName = columnNames[index];
205
+ return (_jsx(Th, { columnFilters: columnFilters, config: config ? config[propName] : undefined, isSortable: !!isSortable, name: propName, schema: properties[propName], setColumnFilters: setColumnFilters, setSortColumn: setSortColumn, setSortAsc: setSortAsc, sortAsc: sortColumn === propName ? sortAsc : undefined, style: style, onSelectAllIndexesHandler: onSelectAllIndexesHandler, isAllChecked: isAllRowsChecked, numberOfSelectedRows: checkedIndexes === null || checkedIndexes === void 0 ? void 0 : checkedIndexes.length }));
206
+ }, [
207
+ columnNames,
208
+ columnFilters,
209
+ config,
210
+ isSortable,
211
+ properties,
212
+ sortColumn,
213
+ sortAsc,
214
+ onSelectAllIndexesHandler,
215
+ isAllRowsChecked,
216
+ checkedIndexes === null || checkedIndexes === void 0 ? void 0 : checkedIndexes.length,
217
+ ]);
191
218
  const onTdClick = React.useCallback((e) => {
192
219
  if (!sortedRenderData || !onRowClick) {
193
220
  return;
@@ -222,6 +249,15 @@ export default function SchemaTableComponent(props) {
222
249
  if (propConfig === null || propConfig === void 0 ? void 0 : propConfig.renderCell) {
223
250
  return (_jsx("div", Object.assign({}, tdDivProps, { children: propConfig.renderCell(data[row._index], rowIndex) })));
224
251
  }
252
+ if (propName === SELECT_ALL_COLUMN_NAME) {
253
+ const onChecked = () => {
254
+ if (!onCheckedIndexesChange) {
255
+ return;
256
+ }
257
+ onCheckedIndexesChange([rowIndex]);
258
+ };
259
+ return (_jsx("div", Object.assign({}, tdDivProps, { children: _jsx("div", Object.assign({ style: { marginLeft: 8 } }, { children: _jsx("input", { type: "checkbox", onChange: onChecked, checked: checkedIndexes === null || checkedIndexes === void 0 ? void 0 : checkedIndexes.includes(rowIndex) }) })) })));
260
+ }
225
261
  if (!schema) {
226
262
  return null;
227
263
  }
@@ -251,6 +287,8 @@ export default function SchemaTableComponent(props) {
251
287
  getRowSelected,
252
288
  data,
253
289
  getRowClassName,
290
+ checkedIndexes,
291
+ onCheckedIndexesChange,
254
292
  ]);
255
293
  const onSearchChange = React.useCallback((e) => {
256
294
  setSearchQuery(e.currentTarget.value);
@@ -260,5 +298,5 @@ export default function SchemaTableComponent(props) {
260
298
  const totalWidth = React.useMemo(() => columnWidths.reduce((a, b) => {
261
299
  return a + b;
262
300
  }, 0), [columnWidths]);
263
- return (_jsxs("div", Object.assign({ className: `schema-table${onRowClick ? " schema-table--clickable-rows" : ""}`, style: Object.assign(Object.assign({}, style), { width: dynamicWidthColumnCount ? gridWidth : fixedWidthColumnsWidth }) }, { children: [_jsx("div", Object.assign({ className: "tableTitle" }, { children: tableTitle })), _jsxs("div", Object.assign({ className: "form-action-container" }, { children: [_jsx("div", Object.assign({ className: "flex-1" }, { children: isSearchable ? (_jsx("input", { id: "input-filter", type: "text", placeholder: searchPlaceholder, value: searchQuery, onChange: onSearchChange, autoFocus: true })) : null })), customElement] })), _jsx(Heading, Object.assign({ height: 50, itemCount: columnCount, itemSize: getColumnWidth, layout: "horizontal", width: width, sortAsc: sortAsc, setSortAsc: setSortAsc, setSortColumn: setSortColumn, sortColumn: sortColumn, sortedRenderData: sortedRenderData, className: "schema-table__th-row" }, { children: SchemaTableTh }), `thead_${width}_${sortColumn}_${sortAsc}_${searchQuery}`), _jsx(VariableSizeGrid, Object.assign({ className: "schema-table__tbody", height: props.height - (isSearchable ? 50 : 0), width: totalWidth, columnWidth: getColumnWidth, rowHeight: getRowHeight, columnCount: columnCount, rowCount: sortedRenderData ? sortedRenderData.length : 0 }, { children: Td }), `tbody_${width}_${sortColumn}_${sortAsc}_${searchQuery}_${columnCount}`)] })));
301
+ return (_jsxs("div", Object.assign({ className: `schema-table${onRowClick ? " schema-table--clickable-rows" : ""}`, style: Object.assign(Object.assign({}, style), { width: dynamicWidthColumnCount ? gridWidth : fixedWidthColumnsWidth }) }, { children: [_jsx("div", Object.assign({ className: "tableTitle" }, { children: tableTitle })), _jsxs("div", Object.assign({ className: "action-container" }, { children: [_jsx("div", Object.assign({ style: { flex: 1 } }, { children: isSearchable ? (_jsx("input", { id: "input-filter", 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: width, sortAsc: sortAsc, setSortAsc: setSortAsc, setSortColumn: setSortColumn, sortColumn: sortColumn, sortedRenderData: sortedRenderData, className: "schema-table__th-row" }, { children: SchemaTableTh }), `thead_${width}_${sortColumn}_${sortAsc}_${searchQuery}`), _jsx(VariableSizeGrid, Object.assign({ className: "schema-table__tbody", height: props.height - (isSearchable ? 50 : 0), width: totalWidth, columnWidth: getColumnWidth, rowHeight: getRowHeight, columnCount: columnCount, rowCount: sortedRenderData ? sortedRenderData.length : 0 }, { children: Td }), `tbody_${width}_${sortColumn}_${sortAsc}_${searchQuery}_${columnCount}`)] })));
264
302
  }
package/dist/index.css CHANGED
@@ -54,3 +54,16 @@
54
54
  .schema-table button {
55
55
  border: 1px solid transparent;
56
56
  }
57
+ .schema-table .action-container {
58
+ display: flex;
59
+ flex-direction: row;
60
+ }
61
+ .schema-table .action-container #input-filter {
62
+ width: 30%;
63
+ border-radius: 8px;
64
+ padding: 4px 10px;
65
+ }
66
+ .schema-table .action-container img {
67
+ margin-right: 1.5rem;
68
+ margin-top: 5px;
69
+ }
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import SchemaTableComponent from "./component/SchemaTable";
1
+ import SchemaTable from "./component/SchemaTable";
2
2
  import { IColumnConfig, IRenderData } from "./types/type";
3
3
  export type { IColumnConfig, IRenderData };
4
- export { SchemaTableComponent };
4
+ export { SchemaTable };
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import SchemaTableComponent from "./component/SchemaTable";
2
- export { SchemaTableComponent };
1
+ import SchemaTable from "./component/SchemaTable";
2
+ export { SchemaTable };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mig-schema-table",
3
- "version": "1.0.12",
3
+ "version": "2.0.1",
4
4
  "main": "dist/index.js",
5
5
  "files": [
6
6
  "dist/"
@@ -20,6 +20,7 @@
20
20
  "lodash": "^4.17.21",
21
21
  "openapi-typescript": "^6.2.4",
22
22
  "openapi3-ts": "^4.1.2",
23
+ "prettier": "^2.8.8",
23
24
  "react": "^18.2.0",
24
25
  "react-dom": "^18.2.0",
25
26
  "react-scripts": "5.0.1",