mig-schema-table 3.0.7 → 3.0.9

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.
@@ -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", { 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
+ case "string":
72
+ if (propSchema.format === "date" || propSchema.format === "date-time") {
73
+ tdDivProps.className += ` text-${(propConfig === null || propConfig === void 0 ? void 0 : propConfig.align) || "end"}`;
74
+ }
75
+ }
76
+ return _jsx("div", Object.assign({}, tdDivProps, { children: row[propName] }));
77
+ }
78
+ export default React.memo(Td);
@@ -15,6 +15,7 @@ export interface ISchemaTableComponentProps<T> {
15
15
  getRowSelected?: (rowData: T) => boolean;
16
16
  maxHeight?: number;
17
17
  isSearchable?: boolean;
18
+ isColumnSearchable?: boolean;
18
19
  isSortable?: boolean;
19
20
  onCheckedIndexesChange?: (dataIndex: number[]) => void;
20
21
  onRowClick?: (rowData: T, dataIndex: number, event: React.MouseEvent) => void;
@@ -24,4 +25,4 @@ export interface ISchemaTableComponentProps<T> {
24
25
  style?: React.CSSProperties;
25
26
  width: number;
26
27
  }
27
- export default function SchemaTable<T>({ Heading, checkedIndexes, config, customElement, data, defaultSortAsc, defaultSortColumn, getRowClassName, getRowSelected, maxHeight, isSearchable, isSortable, onCheckedIndexesChange, onRowClick, rowHeight, schema, searchPlaceholder, style, width, }: ISchemaTableComponentProps<T>): import("react/jsx-runtime").JSX.Element;
28
+ export default function SchemaTable<T>({ Heading, checkedIndexes, config, customElement, data, defaultSortAsc, defaultSortColumn, getRowClassName, getRowSelected, maxHeight, isSearchable, isColumnSearchable, isSortable, onCheckedIndexesChange, onRowClick, rowHeight, schema, searchPlaceholder, style, width, }: ISchemaTableComponentProps<T>): import("react/jsx-runtime").JSX.Element;
@@ -5,11 +5,13 @@ import { localeFormat } from "../inc/date";
5
5
  import { uncamel } from "../inc/string";
6
6
  import Th from "./Th";
7
7
  import { SELECT_ALL_COLUMN_NAME, SELECT_ALL_COLUMN_WIDTH } from "./constants";
8
- export default function SchemaTable({ Heading = VariableSizeList, checkedIndexes, config, customElement, data, defaultSortAsc = false, defaultSortColumn, getRowClassName, getRowSelected, maxHeight, isSearchable, isSortable, onCheckedIndexesChange, onRowClick, rowHeight = 36, schema, searchPlaceholder, style, width, }) {
8
+ import Td from "./Td";
9
+ export default function SchemaTable({ Heading = VariableSizeList, checkedIndexes, config, customElement, data, defaultSortAsc = false, defaultSortColumn, getRowClassName, getRowSelected, maxHeight, isSearchable, isColumnSearchable, isSortable, onCheckedIndexesChange, onRowClick, rowHeight = 36, schema, searchPlaceholder, style, width, }) {
9
10
  const [sortColumn, setSortColumn] = React.useState(defaultSortColumn);
10
11
  const [sortAsc, setSortAsc] = React.useState(defaultSortAsc);
11
12
  const [searchQuery, setSearchQuery] = React.useState("");
12
13
  const [columnFilters, setColumnFilters] = React.useState();
14
+ const [columnSearchObj, setColumnSearchObj] = React.useState({});
13
15
  const { properties = {} } = schema;
14
16
  const columnNames = React.useMemo(() => {
15
17
  const columns = Object.keys(properties);
@@ -51,24 +53,25 @@ export default function SchemaTable({ Heading = VariableSizeList, checkedIndexes
51
53
  }, [config, onCheckedIndexesChange, properties]);
52
54
  const renderData = React.useMemo(() => data
53
55
  ? data.map((object, rowIndex) => columnNames.reduce((prev, propName) => {
56
+ var _a;
54
57
  const schema = properties[propName];
55
58
  const propConfig = config ? config[propName] : undefined;
56
59
  if (propConfig === null || propConfig === void 0 ? void 0 : propConfig.renderData) {
57
60
  prev[propName] = propConfig.renderData(object, rowIndex);
58
61
  return prev;
59
62
  }
60
- if (propName === SELECT_ALL_COLUMN_NAME) {
61
- prev[propName] = "asd";
62
- return prev;
63
- }
64
- if (!schema) {
63
+ if (!schema || propName === SELECT_ALL_COLUMN_NAME) {
65
64
  prev[propName] = "?";
66
65
  return prev;
67
66
  }
68
67
  const rawValue = object[propName];
69
68
  switch (schema.type) {
70
69
  case "array":
71
- prev[propName] = JSON.stringify(rawValue);
70
+ prev[propName] =
71
+ ((_a = schema.items) === null || _a === void 0 ? void 0 : _a.type) === "string" &&
72
+ rawValue
73
+ ? rawValue.map(uncamel).join(", ")
74
+ : JSON.stringify(rawValue);
72
75
  return prev;
73
76
  case "boolean":
74
77
  prev[propName] = rawValue ? "✓" : "✕";
@@ -148,6 +151,18 @@ export default function SchemaTable({ Heading = VariableSizeList, checkedIndexes
148
151
  // @ts-ignore
149
152
  `${item[columnName]}`.toLowerCase().includes(lcQuery)));
150
153
  }
154
+ if (isColumnSearchable) {
155
+ return result.filter((item) => {
156
+ const rowColumnValidation = Object.keys(columnSearchObj).reduce((previousValue, propName) => {
157
+ const columnSearchText = columnSearchObj[propName];
158
+ previousValue.push(`${item[propName]}`
159
+ .toLowerCase()
160
+ .includes(columnSearchText.toLowerCase()));
161
+ return previousValue;
162
+ }, []);
163
+ return rowColumnValidation.every((el) => el);
164
+ });
165
+ }
151
166
  if (!columnFilters) {
152
167
  return result;
153
168
  }
@@ -155,7 +170,15 @@ export default function SchemaTable({ Heading = VariableSizeList, checkedIndexes
155
170
  return result.filter((item) => columnFilterEntries.find(([columnName, columnFilterValue]) =>
156
171
  // @ts-ignore
157
172
  data[item._index][columnName] === columnFilterValue));
158
- }, [columnFilters, columnNames, data, renderData, searchQuery]);
173
+ }, [
174
+ columnFilters,
175
+ columnNames,
176
+ columnSearchObj,
177
+ data,
178
+ isColumnSearchable,
179
+ renderData,
180
+ searchQuery,
181
+ ]);
159
182
  // Sort the filtered data
160
183
  const sortedRenderData = React.useMemo(() => {
161
184
  if (!sortColumn || !filteredRenderData) {
@@ -226,81 +249,36 @@ export default function SchemaTable({ Heading = VariableSizeList, checkedIndexes
226
249
  isAllRowsChecked,
227
250
  checkedIndexes === null || checkedIndexes === void 0 ? void 0 : checkedIndexes.length,
228
251
  ]);
229
- const onTdClick = React.useCallback((e) => {
230
- if (!sortedRenderData || !onRowClick) {
231
- return;
232
- }
233
- const { rowIndex } = e.currentTarget.dataset;
234
- if (!rowIndex) {
235
- return;
236
- }
237
- const row = sortedRenderData[parseInt(rowIndex, 10)];
238
- onRowClick(data[row._index], row._index, e);
239
- }, [data, onRowClick, sortedRenderData]);
240
- const Td = React.useCallback(({ columnIndex, rowIndex, style }) => {
241
- if (!sortedRenderData) {
242
- return null;
243
- }
252
+ const SchemaTableTd = React.useCallback(({ columnIndex, rowIndex, style }) => {
244
253
  const propName = columnNames[columnIndex];
245
- const propConfig = config ? config[propName] : undefined;
246
- const row = sortedRenderData[rowIndex];
247
- const schema = properties[propName];
248
- const tdDivProps = {
249
- "data-row-index": rowIndex,
250
- "data-column-index": columnIndex,
251
- key: propName,
252
- style,
253
- onClick: !(propConfig === null || propConfig === void 0 ? void 0 : propConfig.renderCell) ? onTdClick : undefined,
254
- className: `schema-table__td schema-table__td--${rowIndex % 2 ? "odd" : "even"}${row && getRowSelected && getRowSelected(data[row._index])
255
- ? " schema-table__td--selected"
256
- : ""} ${row && getRowClassName
257
- ? getRowClassName(data[row._index], row._index)
258
- : ""}`,
259
- };
260
- if (propConfig === null || propConfig === void 0 ? void 0 : propConfig.renderCell) {
261
- return (_jsx("div", Object.assign({}, tdDivProps, { children: propConfig.renderCell(data[row._index], row._index, rowIndex) })));
262
- }
263
- if (propName === SELECT_ALL_COLUMN_NAME) {
264
- const onChecked = () => {
265
- if (!onCheckedIndexesChange) {
266
- return;
267
- }
268
- onCheckedIndexesChange([row._index]);
269
- };
270
- return (_jsx("div", Object.assign({}, tdDivProps, { children: _jsx("div", Object.assign({ style: { textAlign: "center" } }, { children: _jsx("input", { type: "checkbox", onChange: onChecked, checked: checkedIndexes === null || checkedIndexes === void 0 ? void 0 : checkedIndexes.includes(row._index) }) })) })));
271
- }
272
- if (!schema) {
273
- return null;
274
- }
275
- // @ts-ignore
276
- switch (schema.type) {
277
- case "boolean":
278
- tdDivProps.className += ` text-${(propConfig === null || propConfig === void 0 ? void 0 : propConfig.align) || "center"}`;
279
- break;
280
- case "number":
281
- case "integer":
282
- tdDivProps.className += ` text-${(propConfig === null || propConfig === void 0 ? void 0 : propConfig.align) || "end"}`;
283
- break;
284
- case "string":
285
- // @ts-ignore
286
- tdDivProps.title = row[propName];
287
- if (schema.format === "date" || schema.format === "date-time") {
288
- tdDivProps.className += ` text-${(propConfig === null || propConfig === void 0 ? void 0 : propConfig.align) || "end"}`;
289
- }
290
- }
291
- return _jsx("div", Object.assign({}, tdDivProps, { children: row[propName] }));
254
+ return (_jsx(Td, { checkedIndexes: checkedIndexes, columnIndex: columnIndex, data: data, getRowClassName: getRowClassName, getRowSelected: getRowSelected, onCheckedIndexesChange: onCheckedIndexesChange, propConfig: config ? config[propName] : undefined, propName: propName, propSchema: properties[propName], rowHeight: rowHeight, rowIndex: rowIndex, sortedRenderData: sortedRenderData, style: style }));
292
255
  }, [
293
- sortedRenderData,
256
+ checkedIndexes,
294
257
  columnNames,
295
258
  config,
296
- properties,
297
- onTdClick,
298
- getRowSelected,
299
259
  data,
300
260
  getRowClassName,
301
- checkedIndexes,
261
+ getRowSelected,
302
262
  onCheckedIndexesChange,
263
+ properties,
264
+ rowHeight,
265
+ sortedRenderData,
303
266
  ]);
267
+ const columnSearchHandler = React.useCallback((e) => {
268
+ setColumnSearchObj((columnSearch) => (Object.assign(Object.assign({}, columnSearch), { [e.target.dataset.propName]: e.target.value })));
269
+ }, []);
270
+ const SchemaColumnFilter = React.useCallback((index) => {
271
+ const propName = columnNames[index];
272
+ // const propSchema = properties[propName] as oas31.SchemaObject;
273
+ const propConfig = config ? config[propName] : undefined;
274
+ if (propName === SELECT_ALL_COLUMN_NAME || !(propConfig === null || propConfig === void 0 ? void 0 : propConfig.isSearchable)) {
275
+ return _jsx("div", { className: "schema-table__th", style: style });
276
+ }
277
+ return (_jsx("div", Object.assign({ className: "schema-table__th" }, { children: _jsx("input", { value: columnSearchObj === null || columnSearchObj === void 0 ? void 0 : columnSearchObj[propName], "data-prop-name": propName, onChange: columnSearchHandler, style: {
278
+ marginRight: 2,
279
+ width: "90%",
280
+ } }) }), `filter-col-${propName}`));
281
+ }, [columnNames, columnSearchHandler, columnSearchObj, config, style]);
304
282
  const onSearchChange = React.useCallback((e) => {
305
283
  setSearchQuery(e.currentTarget.value);
306
284
  }, []);
@@ -314,5 +292,11 @@ export default function SchemaTable({ Heading = VariableSizeList, checkedIndexes
314
292
  ? rowsMaxHeight
315
293
  : rowsHeight;
316
294
  }, [maxHeight, isSearchable, rowCount, rowHeight]);
317
- return (_jsxs("div", Object.assign({ className: `schema-table${onRowClick ? " schema-table--clickable-rows" : ""}`, style: Object.assign(Object.assign({}, style), { width: rowWidth }) }, { 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: Td }), `tbody_${rowWidth}_${sortColumn}_${sortAsc}_${searchQuery}_${columnCount}`)] })));
295
+ return (_jsxs("div", Object.assign({ className: `schema-table${onRowClick ? " schema-table--clickable-rows" : ""}`, style: Object.assign(Object.assign({}, style), { width: rowWidth }) }, { 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("div", Object.assign({ className: "schema-table__th-row", style: { display: "flex", flex: "row" } }, { children: columnNames.map((columnName, index) => {
296
+ return (_jsx("div", Object.assign({ className: "schema-table__th", style: {
297
+ width: getColumnWidth(index),
298
+ height: 20,
299
+ paddingBottom: 8,
300
+ } }, { children: SchemaColumnFilter(index) }), `filter-${index}`));
301
+ }) })), _jsx(VariableSizeGrid, Object.assign({ className: "schema-table__tbody", height: tableBodyHeight, width: rowWidth, columnWidth: getColumnWidth, rowHeight: getRowHeight, columnCount: columnCount, rowCount: rowCount }, { children: SchemaTableTd }), `tbody_${rowWidth}_${sortColumn}_${sortAsc}_${searchQuery}_${columnCount}`)] })));
318
302
  }
package/dist/index.css CHANGED
@@ -32,7 +32,6 @@
32
32
  text-overflow: ellipsis;
33
33
  padding-left: 8px;
34
34
  align-items: center;
35
- line-height: 40px;
36
35
  }
37
36
  .schema-table__td--odd {
38
37
  background-color: #ddd;
@@ -49,7 +48,6 @@
49
48
  }
50
49
  .schema-table__search input {
51
50
  width: 100%;
52
- line-height: 20px;
53
51
  }
54
52
  .schema-table--clickable-rows .schema-table__td {
55
53
  cursor: pointer;
package/dist/types.d.ts CHANGED
@@ -13,8 +13,9 @@ export interface IColumnConfig<T> {
13
13
  title?: string | React.ReactElement;
14
14
  width?: number;
15
15
  order?: number;
16
+ isSearchable?: boolean;
16
17
  }
17
18
  export interface IRenderData {
18
19
  _index: number;
19
- [key: string]: any;
20
+ [key: string]: string | any;
20
21
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mig-schema-table",
3
- "version": "3.0.7",
3
+ "version": "3.0.9",
4
4
  "main": "dist/index.js",
5
5
  "files": [
6
6
  "dist/"