@snack-uikit/table 0.14.7 → 0.14.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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,32 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## 0.14.9 (2024-02-28)
7
+
8
+ ### Only dependencies have been changed
9
+ * [@snack-uikit/button@0.17.0](https://github.com/cloud-ru-tech/snack-uikit/blob/master/packages/button/CHANGELOG.md)
10
+ * [@snack-uikit/chips@0.12.2](https://github.com/cloud-ru-tech/snack-uikit/blob/master/packages/chips/CHANGELOG.md)
11
+ * [@snack-uikit/icon-predefined@0.5.0](https://github.com/cloud-ru-tech/snack-uikit/blob/master/packages/icon-predefined/CHANGELOG.md)
12
+ * [@snack-uikit/info-block@0.3.1](https://github.com/cloud-ru-tech/snack-uikit/blob/master/packages/info-block/CHANGELOG.md)
13
+ * [@snack-uikit/list@0.6.1](https://github.com/cloud-ru-tech/snack-uikit/blob/master/packages/list/CHANGELOG.md)
14
+ * [@snack-uikit/pagination@0.6.5](https://github.com/cloud-ru-tech/snack-uikit/blob/master/packages/pagination/CHANGELOG.md)
15
+ * [@snack-uikit/toolbar@0.7.17](https://github.com/cloud-ru-tech/snack-uikit/blob/master/packages/toolbar/CHANGELOG.md)
16
+
17
+
18
+
19
+
20
+
21
+ ## 0.14.8 (2024-02-27)
22
+
23
+
24
+ ### Bug Fixes
25
+
26
+ * **FF-3424:** fix table global search ([b5ebe5b](https://github.com/cloud-ru-tech/snack-uikit/commit/b5ebe5b227fbfaefdd1ce1dda858794f1ca546da))
27
+
28
+
29
+
30
+
31
+
6
32
  ## 0.14.7 (2024-02-27)
7
33
 
8
34
  ### Only dependencies have been changed
@@ -23,7 +23,7 @@ export function ServerTable(_a) {
23
23
  const [tempSearch, setTempSearch] = useState(search || '');
24
24
  const handleSearch = useCallback((newValue) => {
25
25
  setTempSearch(newValue);
26
- onSearchDebounced()(newValue.trim(), setSearch);
26
+ onSearchDebounced(newValue.trim(), setSearch);
27
27
  }, [setSearch]);
28
28
  const handlePageChange = useCallback(({ pageSize, pageIndex }) => onChangePage(pageIndex * pageSize, pageSize), [onChangePage]);
29
29
  const pageIndex = useMemo(() => Math.floor(offset / limit), [limit, offset]);
@@ -1,2 +1,2 @@
1
1
  /// <reference types="lodash" />
2
- export declare function onSearchDebounced(): import("lodash").DebouncedFunc<(newValue: string, onChange: (newValue: string) => void) => void>;
2
+ export declare const onSearchDebounced: import("lodash").DebouncedFunc<(newValue: string, onChange: (newValue: string) => void) => void>;
@@ -1,7 +1,5 @@
1
1
  import debounce from 'lodash.debounce';
2
2
  import { SEARCH_DELAY } from './constants';
3
- export function onSearchDebounced() {
4
- return debounce((newValue, onChange) => {
5
- onChange(newValue);
6
- }, SEARCH_DELAY);
7
- }
3
+ export const onSearchDebounced = debounce((newValue, onChange) => {
4
+ onChange(newValue);
5
+ }, SEARCH_DELAY);
@@ -1,6 +1,6 @@
1
1
  import { TableProps } from '../types';
2
2
  /** Компонент таблицы */
3
- export declare function Table<TData extends object>({ data, columnDefinitions, rowSelection, search, sorting, columnFilters, pagination, className, onRowClick, onRefresh, onDelete, pageSize, pageCount, loading, outline, moreActions, exportFileName, dataFiltered, dataError, noDataState, noResultsState, errorDataState, suppressToolbar, toolbarBefore, toolbarAfter, suppressPagination, manualSorting, manualPagination, manualFiltering, scrollRef, scrollContainerRef, ...rest }: TableProps<TData>): import("react/jsx-runtime").JSX.Element;
3
+ export declare function Table<TData extends object>({ data, columnDefinitions, rowSelection: rowSelectionProp, search, sorting: sortingProp, columnFilters, pagination: paginationProp, className, onRowClick, onRefresh, onDelete, pageSize, pageCount, loading, outline, moreActions, exportFileName, dataFiltered, dataError, noDataState, noResultsState, errorDataState, suppressToolbar, toolbarBefore, toolbarAfter, suppressPagination, manualSorting, manualPagination, manualFiltering, scrollRef, scrollContainerRef, ...rest }: TableProps<TData>): import("react/jsx-runtime").JSX.Element;
4
4
  export declare namespace Table {
5
5
  var getStatusColumnDef: typeof import("../../helperComponents").getStatusColumnDef;
6
6
  var statusAppearances: {
@@ -10,31 +10,87 @@ var __rest = (this && this.__rest) || function (s, e) {
10
10
  return t;
11
11
  };
12
12
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
13
+ import { getCoreRowModel, getFilteredRowModel, getPaginationRowModel, getSortedRowModel, useReactTable, } from '@tanstack/react-table';
13
14
  import cn from 'classnames';
14
15
  import { useCallback, useEffect, useMemo } from 'react';
15
16
  import { useLocale } from '@snack-uikit/locale';
16
17
  import { Scroll } from '@snack-uikit/scroll';
17
18
  import { SkeletonContextProvider } from '@snack-uikit/skeleton';
18
19
  import { Toolbar } from '@snack-uikit/toolbar';
20
+ import { TruncateString } from '@snack-uikit/truncate-string';
19
21
  import { extractSupportProps } from '@snack-uikit/utils';
20
22
  import { DEFAULT_PAGE_SIZE } from '../../constants';
21
- import { BodyRow, ExportButton, getColumnId, getRowActionsColumnDef, getStatusColumnDef, HeaderRow, STATUS_APPEARANCE, TableContext, TableEmptyState, TablePagination, useEmptyState, } from '../../helperComponents';
22
- import { useLoadingTable, useTable } from './hooks';
23
+ import { BodyRow, ExportButton, getColumnId, getRowActionsColumnDef, getSelectionCellColumnDef, getStatusColumnDef, HeaderRow, STATUS_APPEARANCE, TableContext, TableEmptyState, TablePagination, useEmptyState, } from '../../helperComponents';
24
+ import { fuzzyFilter } from '../../utils';
25
+ import { useLoadingTable } from './hooks';
26
+ import { useStateControl } from './hooks/useStateControl';
23
27
  import styles from './styles.module.css';
24
28
  /** Компонент таблицы */
25
29
  export function Table(_a) {
26
- var { data, columnDefinitions, rowSelection, search, sorting, columnFilters, pagination, className, onRowClick, onRefresh, onDelete, pageSize = DEFAULT_PAGE_SIZE, pageCount, loading = false, outline = false, moreActions, exportFileName, dataFiltered, dataError, noDataState, noResultsState, errorDataState, suppressToolbar = false, toolbarBefore, toolbarAfter, suppressPagination = false, manualSorting = false, manualPagination = false, manualFiltering = false, scrollRef, scrollContainerRef } = _a, rest = __rest(_a, ["data", "columnDefinitions", "rowSelection", "search", "sorting", "columnFilters", "pagination", "className", "onRowClick", "onRefresh", "onDelete", "pageSize", "pageCount", "loading", "outline", "moreActions", "exportFileName", "dataFiltered", "dataError", "noDataState", "noResultsState", "errorDataState", "suppressToolbar", "toolbarBefore", "toolbarAfter", "suppressPagination", "manualSorting", "manualPagination", "manualFiltering", "scrollRef", "scrollContainerRef"]);
27
- const { table, tableColumns, columnPinning } = useTable({
30
+ var { data, columnDefinitions, rowSelection: rowSelectionProp, search, sorting: sortingProp, columnFilters, pagination: paginationProp, className, onRowClick, onRefresh, onDelete, pageSize = DEFAULT_PAGE_SIZE, pageCount, loading = false, outline = false, moreActions, exportFileName, dataFiltered, dataError, noDataState, noResultsState, errorDataState, suppressToolbar = false, toolbarBefore, toolbarAfter, suppressPagination = false, manualSorting = false, manualPagination = false, manualFiltering = false, scrollRef, scrollContainerRef } = _a, rest = __rest(_a, ["data", "columnDefinitions", "rowSelection", "search", "sorting", "columnFilters", "pagination", "className", "onRowClick", "onRefresh", "onDelete", "pageSize", "pageCount", "loading", "outline", "moreActions", "exportFileName", "dataFiltered", "dataError", "noDataState", "noResultsState", "errorDataState", "suppressToolbar", "toolbarBefore", "toolbarAfter", "suppressPagination", "manualSorting", "manualPagination", "manualFiltering", "scrollRef", "scrollContainerRef"]);
31
+ const { state: globalFilter, onStateChange: onGlobalFilterChange } = useStateControl(search, '');
32
+ const { state: rowSelection, onStateChange: onRowSelectionChange } = useStateControl(rowSelectionProp, {});
33
+ const defaultPaginationState = useMemo(() => ({
34
+ pageIndex: 0,
35
+ pageSize,
36
+ }), [pageSize]);
37
+ const { state: sorting, onStateChange: onSortingChange } = useStateControl(sortingProp, []);
38
+ const { state: pagination, onStateChange: onPaginationChange } = useStateControl(paginationProp, defaultPaginationState);
39
+ const enableSelection = Boolean(rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.enable);
40
+ const tableColumns = useMemo(() => {
41
+ let cols = columnDefinitions;
42
+ if (enableSelection) {
43
+ cols = [getSelectionCellColumnDef(), ...cols];
44
+ }
45
+ return cols;
46
+ }, [columnDefinitions, enableSelection]);
47
+ const columnPinning = useMemo(() => {
48
+ var _a;
49
+ const pinningState = { left: [], right: [] };
50
+ for (const col of tableColumns) {
51
+ const id = getColumnId(col);
52
+ if (col.pinned && id) {
53
+ (_a = pinningState[col.pinned]) === null || _a === void 0 ? void 0 : _a.push(id);
54
+ }
55
+ }
56
+ return pinningState;
57
+ }, [tableColumns]);
58
+ const table = useReactTable({
28
59
  data,
29
- sorting,
30
- manualFiltering,
31
- manualPagination,
32
- manualSorting,
33
- columnDefinitions,
34
- rowSelection,
35
- pagination,
60
+ columns: tableColumns,
61
+ state: {
62
+ columnPinning,
63
+ globalFilter,
64
+ rowSelection,
65
+ sorting,
66
+ pagination,
67
+ },
36
68
  pageCount,
37
- pageSize,
69
+ defaultColumn: {
70
+ enableSorting: false,
71
+ enableResizing: false,
72
+ minSize: 40,
73
+ cell: (cell) => _jsx(TruncateString, { text: String(cell.getValue()), maxLines: 1 }),
74
+ },
75
+ manualSorting,
76
+ manualPagination,
77
+ manualFiltering,
78
+ globalFilterFn: fuzzyFilter,
79
+ onGlobalFilterChange,
80
+ onRowSelectionChange,
81
+ enableRowSelection: rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.enable,
82
+ enableMultiRowSelection: rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.multiRow,
83
+ enableFilters: true,
84
+ getFilteredRowModel: getFilteredRowModel(),
85
+ enableColumnResizing: true,
86
+ enableSorting: true,
87
+ enableMultiSort: true,
88
+ onSortingChange,
89
+ getSortedRowModel: getSortedRowModel(),
90
+ onPaginationChange,
91
+ getPaginationRowModel: getPaginationRowModel(),
92
+ getCoreRowModel: getCoreRowModel(),
93
+ columnResizeMode: 'onEnd',
38
94
  });
39
95
  const { loadingTable } = useLoadingTable({ pageSize, columnDefinitions: tableColumns, columnPinning });
40
96
  const handleOnRefresh = useCallback(() => {
@@ -50,7 +106,7 @@ export function Table(_a) {
50
106
  }
51
107
  }, [loading, onDelete, table]);
52
108
  const handleOnCheck = useCallback(() => {
53
- if (!loading && (rowSelection === null || rowSelection === void 0 ? void 0 : rowSelection.multiRow)) {
109
+ if (!loading && (rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.multiRow)) {
54
110
  table.toggleAllPageRowsSelected();
55
111
  return;
56
112
  }
@@ -58,7 +114,7 @@ export function Table(_a) {
58
114
  table.resetRowSelection();
59
115
  return;
60
116
  }
61
- }, [loading, rowSelection === null || rowSelection === void 0 ? void 0 : rowSelection.multiRow, table]);
117
+ }, [loading, rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.multiRow, table]);
62
118
  useEffect(() => { }, []);
63
119
  const columnSizeVars = useMemo(() => {
64
120
  const originalColumnDefs = table._getColumnDefs();
@@ -92,16 +148,14 @@ export function Table(_a) {
92
148
  const tempPageSize = !suppressPagination ? tablePagination === null || tablePagination === void 0 ? void 0 : tablePagination.pageSize : pageSize;
93
149
  return !tableRows.length ? Math.min(Math.max(tempPageSize, 5), DEFAULT_PAGE_SIZE) : tempPageSize;
94
150
  }, [pageSize, suppressPagination, tablePagination === null || tablePagination === void 0 ? void 0 : tablePagination.pageSize, tableRows.length]);
95
- const enableSelection = Boolean(rowSelection === null || rowSelection === void 0 ? void 0 : rowSelection.enable);
96
151
  return (_jsx(_Fragment, { children: _jsxs("div", Object.assign({ style: {
97
152
  '--page-size': cssPageSize,
98
- // width: table.getTotalSize(),
99
153
  }, className: cn(styles.wrapper, className) }, extractSupportProps(rest), { children: [!suppressToolbar && (_jsxs("div", { className: styles.header, children: [_jsx(Toolbar, { search: {
100
- value: table.getState().globalFilter,
101
- onChange: table.setGlobalFilter,
154
+ value: globalFilter,
155
+ onChange: onGlobalFilterChange,
102
156
  loading: search === null || search === void 0 ? void 0 : search.loading,
103
157
  placeholder: (search === null || search === void 0 ? void 0 : search.placeholder) || t('searchPlaceholder'),
104
- }, checked: table.getIsAllPageRowsSelected(), indeterminate: table.getIsSomePageRowsSelected(), className: styles.toolbar, onRefresh: onRefresh ? handleOnRefresh : undefined, onDelete: enableSelection && onDelete ? handleOnDelete : undefined, onCheck: enableSelection ? handleOnCheck : undefined, outline: outline, selectionMode: (rowSelection === null || rowSelection === void 0 ? void 0 : rowSelection.multiRow) ? 'multiple' : 'single', before: toolbarBefore, after: _jsxs(_Fragment, { children: [toolbarAfter, exportFileName ? (_jsx(ExportButton, { fileName: exportFileName, columnDefinitions: columnDefinitions, data: data })) : undefined] }), moreActions: moreActions }), columnFilters && _jsxs("div", { className: styles.filtersWrapper, children: [" ", columnFilters, " "] })] })), _jsx("div", { className: styles.scrollWrapper, "data-outline": outline || undefined, children: _jsxs(Scroll, { size: 's', className: styles.table, ref: scrollContainerRef, children: [_jsx("div", { className: styles.tableContent, style: columnSizeVars, children: _jsx(TableContext.Provider, { value: { table }, children: loading ? (_jsxs(SkeletonContextProvider, { loading: true, children: [_jsx(HeaderRow, {}), loadingTableRows.map(row => (_jsx(BodyRow, { row: row }, row.id)))] })) : (_jsxs(_Fragment, { children: [tableRows.length ? _jsx(HeaderRow, {}) : null, tableRows.map(row => (_jsx(BodyRow, { row: row, onRowClick: onRowClick }, row.id))), _jsx(TableEmptyState, { emptyStates: emptyStates, dataError: dataError, dataFiltered: dataFiltered || Boolean(table.getState().globalFilter), tableRowsLength: tableRows.length })] })) }) }), _jsx("div", { className: styles.scrollStub, ref: scrollRef })] }) }), !suppressPagination && (_jsx(TablePagination, { table: table, options: pagination === null || pagination === void 0 ? void 0 : pagination.options, optionsLabel: pagination === null || pagination === void 0 ? void 0 : pagination.optionsLabel, pageCount: pageCount }))] })) }));
158
+ }, checked: table.getIsAllPageRowsSelected(), indeterminate: table.getIsSomePageRowsSelected(), className: styles.toolbar, onRefresh: onRefresh ? handleOnRefresh : undefined, onDelete: enableSelection && onDelete ? handleOnDelete : undefined, onCheck: enableSelection ? handleOnCheck : undefined, outline: outline, selectionMode: (rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.multiRow) ? 'multiple' : 'single', before: toolbarBefore, after: toolbarAfter || exportFileName ? (_jsxs(_Fragment, { children: [toolbarAfter, exportFileName && (_jsx(ExportButton, { fileName: exportFileName, columnDefinitions: columnDefinitions, data: data }))] })) : undefined, moreActions: moreActions }), columnFilters && _jsxs("div", { className: styles.filtersWrapper, children: [" ", columnFilters, " "] })] })), _jsx("div", { className: styles.scrollWrapper, "data-outline": outline || undefined, children: _jsxs(Scroll, { size: 's', className: styles.table, ref: scrollContainerRef, children: [_jsx("div", { className: styles.tableContent, style: columnSizeVars, children: _jsx(TableContext.Provider, { value: { table }, children: loading ? (_jsxs(SkeletonContextProvider, { loading: true, children: [_jsx(HeaderRow, {}), loadingTableRows.map(row => (_jsx(BodyRow, { row: row }, row.id)))] })) : (_jsxs(_Fragment, { children: [tableRows.length ? _jsx(HeaderRow, {}) : null, tableRows.map(row => (_jsx(BodyRow, { row: row, onRowClick: onRowClick }, row.id))), _jsx(TableEmptyState, { emptyStates: emptyStates, dataError: dataError, dataFiltered: dataFiltered || Boolean(table.getState().globalFilter), tableRowsLength: tableRows.length })] })) }) }), _jsx("div", { className: styles.scrollStub, ref: scrollRef })] }) }), !suppressPagination && (_jsx(TablePagination, { table: table, options: paginationProp === null || paginationProp === void 0 ? void 0 : paginationProp.options, optionsLabel: paginationProp === null || paginationProp === void 0 ? void 0 : paginationProp.optionsLabel, pageCount: pageCount }))] })) }));
105
159
  }
106
160
  Table.getStatusColumnDef = getStatusColumnDef;
107
161
  Table.statusAppearances = STATUS_APPEARANCE;
@@ -1,2 +1 @@
1
1
  export * from './useLoadingTable';
2
- export * from './useTable';
@@ -1,2 +1 @@
1
1
  export * from './useLoadingTable';
2
- export * from './useTable';
@@ -24,7 +24,10 @@
24
24
  }
25
25
 
26
26
  .tableHeaderCell{
27
- padding:var(--space-table-cell-padding, 8px);
27
+ padding-left:var(--space-table-head-column-horizontal-padding, 8px);
28
+ padding-right:var(--space-table-head-column-horizontal-padding, 8px);
29
+ padding-top:var(--space-table-head-separator-padding, 8px);
30
+ padding-bottom:var(--space-table-head-separator-padding, 8px);
28
31
  position:relative;
29
32
  display:flex;
30
33
  align-items:center;
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "access": "public"
5
5
  },
6
6
  "title": "Table",
7
- "version": "0.14.7",
7
+ "version": "0.14.9",
8
8
  "sideEffects": [
9
9
  "*.css",
10
10
  "*.woff",
@@ -32,18 +32,18 @@
32
32
  "license": "Apache-2.0",
33
33
  "scripts": {},
34
34
  "dependencies": {
35
- "@snack-uikit/button": "0.16.1",
36
- "@snack-uikit/chips": "0.12.0",
37
- "@snack-uikit/icon-predefined": "0.4.2",
35
+ "@snack-uikit/button": "0.17.0",
36
+ "@snack-uikit/chips": "0.12.2",
37
+ "@snack-uikit/icon-predefined": "0.5.0",
38
38
  "@snack-uikit/icons": "0.20.1",
39
- "@snack-uikit/info-block": "0.3.0",
40
- "@snack-uikit/list": "0.5.0",
41
- "@snack-uikit/pagination": "0.6.4",
39
+ "@snack-uikit/info-block": "0.3.1",
40
+ "@snack-uikit/list": "0.6.1",
41
+ "@snack-uikit/pagination": "0.6.5",
42
42
  "@snack-uikit/scroll": "0.5.2",
43
43
  "@snack-uikit/skeleton": "0.3.3",
44
- "@snack-uikit/tag": "0.8.0",
44
+ "@snack-uikit/tag": "0.8.1",
45
45
  "@snack-uikit/toggles": "0.9.6",
46
- "@snack-uikit/toolbar": "0.7.15",
46
+ "@snack-uikit/toolbar": "0.7.17",
47
47
  "@snack-uikit/truncate-string": "0.4.9",
48
48
  "@snack-uikit/typography": "0.6.1",
49
49
  "@snack-uikit/utils": "3.2.0",
@@ -58,5 +58,5 @@
58
58
  "peerDependencies": {
59
59
  "@snack-uikit/locale": "*"
60
60
  },
61
- "gitHead": "bfdd4a8e3c077eab0d45e177172a62b6dcbda06b"
61
+ "gitHead": "0054db0a5550fb69d388335d844017bca31fffe7"
62
62
  }
@@ -31,7 +31,7 @@ export function ServerTable<TData extends object>({
31
31
  const handleSearch = useCallback(
32
32
  (newValue: string) => {
33
33
  setTempSearch(newValue);
34
- onSearchDebounced()(newValue.trim(), setSearch);
34
+ onSearchDebounced(newValue.trim(), setSearch);
35
35
  },
36
36
 
37
37
  [setSearch],
@@ -2,8 +2,6 @@ import debounce from 'lodash.debounce';
2
2
 
3
3
  import { SEARCH_DELAY } from './constants';
4
4
 
5
- export function onSearchDebounced() {
6
- return debounce((newValue: string, onChange: (newValue: string) => void) => {
7
- onChange(newValue);
8
- }, SEARCH_DELAY);
9
- }
5
+ export const onSearchDebounced = debounce((newValue: string, onChange: (newValue: string) => void) => {
6
+ onChange(newValue);
7
+ }, SEARCH_DELAY);
@@ -1,3 +1,15 @@
1
+ import {
2
+ CellContext,
3
+ ColumnPinningState,
4
+ getCoreRowModel,
5
+ getFilteredRowModel,
6
+ getPaginationRowModel,
7
+ getSortedRowModel,
8
+ PaginationState,
9
+ RowSelectionState,
10
+ SortingState,
11
+ useReactTable,
12
+ } from '@tanstack/react-table';
1
13
  import cn from 'classnames';
2
14
  import { RefObject, useCallback, useEffect, useMemo } from 'react';
3
15
 
@@ -5,6 +17,7 @@ import { useLocale } from '@snack-uikit/locale';
5
17
  import { Scroll } from '@snack-uikit/scroll';
6
18
  import { SkeletonContextProvider } from '@snack-uikit/skeleton';
7
19
  import { Toolbar } from '@snack-uikit/toolbar';
20
+ import { TruncateString } from '@snack-uikit/truncate-string';
8
21
  import { extractSupportProps } from '@snack-uikit/utils';
9
22
 
10
23
  import { DEFAULT_PAGE_SIZE } from '../../constants';
@@ -13,6 +26,7 @@ import {
13
26
  ExportButton,
14
27
  getColumnId,
15
28
  getRowActionsColumnDef,
29
+ getSelectionCellColumnDef,
16
30
  getStatusColumnDef,
17
31
  HeaderRow,
18
32
  STATUS_APPEARANCE,
@@ -21,19 +35,22 @@ import {
21
35
  TablePagination,
22
36
  useEmptyState,
23
37
  } from '../../helperComponents';
38
+ import { ColumnDefinition } from '../../types';
39
+ import { fuzzyFilter } from '../../utils';
24
40
  import { TableProps } from '../types';
25
- import { useLoadingTable, useTable } from './hooks';
41
+ import { useLoadingTable } from './hooks';
42
+ import { useStateControl } from './hooks/useStateControl';
26
43
  import styles from './styles.module.scss';
27
44
 
28
45
  /** Компонент таблицы */
29
46
  export function Table<TData extends object>({
30
47
  data,
31
48
  columnDefinitions,
32
- rowSelection,
49
+ rowSelection: rowSelectionProp,
33
50
  search,
34
- sorting,
51
+ sorting: sortingProp,
35
52
  columnFilters,
36
- pagination,
53
+ pagination: paginationProp,
37
54
  className,
38
55
  onRowClick,
39
56
  onRefresh,
@@ -61,17 +78,84 @@ export function Table<TData extends object>({
61
78
 
62
79
  ...rest
63
80
  }: TableProps<TData>) {
64
- const { table, tableColumns, columnPinning } = useTable<TData>({
81
+ const { state: globalFilter, onStateChange: onGlobalFilterChange } = useStateControl<string>(search, '');
82
+ const { state: rowSelection, onStateChange: onRowSelectionChange } = useStateControl<RowSelectionState>(
83
+ rowSelectionProp,
84
+ {},
85
+ );
86
+ const defaultPaginationState = useMemo(
87
+ () => ({
88
+ pageIndex: 0,
89
+ pageSize,
90
+ }),
91
+ [pageSize],
92
+ );
93
+
94
+ const { state: sorting, onStateChange: onSortingChange } = useStateControl<SortingState>(sortingProp, []);
95
+ const { state: pagination, onStateChange: onPaginationChange } = useStateControl<PaginationState>(
96
+ paginationProp,
97
+ defaultPaginationState,
98
+ );
99
+ const enableSelection = Boolean(rowSelectionProp?.enable);
100
+
101
+ const tableColumns: ColumnDefinition<TData>[] = useMemo(() => {
102
+ let cols: ColumnDefinition<TData>[] = columnDefinitions;
103
+ if (enableSelection) {
104
+ cols = [getSelectionCellColumnDef(), ...cols];
105
+ }
106
+ return cols;
107
+ }, [columnDefinitions, enableSelection]);
108
+ const columnPinning = useMemo(() => {
109
+ const pinningState: Required<ColumnPinningState> = { left: [], right: [] };
110
+ for (const col of tableColumns) {
111
+ const id = getColumnId(col);
112
+ if (col.pinned && id) {
113
+ pinningState[col.pinned]?.push(id);
114
+ }
115
+ }
116
+ return pinningState;
117
+ }, [tableColumns]);
118
+
119
+ const table = useReactTable<TData>({
65
120
  data,
66
- sorting,
67
- manualFiltering,
68
- manualPagination,
69
- manualSorting,
70
- columnDefinitions,
71
- rowSelection,
72
- pagination,
121
+ columns: tableColumns,
122
+ state: {
123
+ columnPinning,
124
+ globalFilter,
125
+ rowSelection,
126
+ sorting,
127
+ pagination,
128
+ },
73
129
  pageCount,
74
- pageSize,
130
+ defaultColumn: {
131
+ enableSorting: false,
132
+ enableResizing: false,
133
+ minSize: 40,
134
+ cell: (cell: CellContext<TData, unknown>) => <TruncateString text={String(cell.getValue())} maxLines={1} />,
135
+ },
136
+
137
+ manualSorting,
138
+ manualPagination,
139
+ manualFiltering,
140
+
141
+ globalFilterFn: fuzzyFilter,
142
+ onGlobalFilterChange,
143
+
144
+ onRowSelectionChange,
145
+ enableRowSelection: rowSelectionProp?.enable,
146
+ enableMultiRowSelection: rowSelectionProp?.multiRow,
147
+ enableFilters: true,
148
+ getFilteredRowModel: getFilteredRowModel(),
149
+ enableColumnResizing: true,
150
+ enableSorting: true,
151
+ enableMultiSort: true,
152
+ onSortingChange,
153
+ getSortedRowModel: getSortedRowModel(),
154
+ onPaginationChange,
155
+ getPaginationRowModel: getPaginationRowModel(),
156
+ getCoreRowModel: getCoreRowModel(),
157
+
158
+ columnResizeMode: 'onEnd',
75
159
  });
76
160
 
77
161
  const { loadingTable } = useLoadingTable({ pageSize, columnDefinitions: tableColumns, columnPinning });
@@ -92,7 +176,7 @@ export function Table<TData extends object>({
92
176
  }, [loading, onDelete, table]);
93
177
 
94
178
  const handleOnCheck = useCallback(() => {
95
- if (!loading && rowSelection?.multiRow) {
179
+ if (!loading && rowSelectionProp?.multiRow) {
96
180
  table.toggleAllPageRowsSelected();
97
181
  return;
98
182
  }
@@ -101,7 +185,7 @@ export function Table<TData extends object>({
101
185
  table.resetRowSelection();
102
186
  return;
103
187
  }
104
- }, [loading, rowSelection?.multiRow, table]);
188
+ }, [loading, rowSelectionProp?.multiRow, table]);
105
189
 
106
190
  useEffect(() => {}, []);
107
191
 
@@ -148,14 +232,11 @@ export function Table<TData extends object>({
148
232
  return !tableRows.length ? Math.min(Math.max(tempPageSize, 5), DEFAULT_PAGE_SIZE) : tempPageSize;
149
233
  }, [pageSize, suppressPagination, tablePagination?.pageSize, tableRows.length]);
150
234
 
151
- const enableSelection = Boolean(rowSelection?.enable);
152
-
153
235
  return (
154
236
  <>
155
237
  <div
156
238
  style={{
157
239
  '--page-size': cssPageSize,
158
- // width: table.getTotalSize(),
159
240
  }}
160
241
  className={cn(styles.wrapper, className)}
161
242
  {...extractSupportProps(rest)}
@@ -164,8 +245,8 @@ export function Table<TData extends object>({
164
245
  <div className={styles.header}>
165
246
  <Toolbar
166
247
  search={{
167
- value: table.getState().globalFilter,
168
- onChange: table.setGlobalFilter,
248
+ value: globalFilter,
249
+ onChange: onGlobalFilterChange,
169
250
  loading: search?.loading,
170
251
  placeholder: search?.placeholder || t('searchPlaceholder'),
171
252
  }}
@@ -176,15 +257,17 @@ export function Table<TData extends object>({
176
257
  onDelete={enableSelection && onDelete ? handleOnDelete : undefined}
177
258
  onCheck={enableSelection ? handleOnCheck : undefined}
178
259
  outline={outline}
179
- selectionMode={rowSelection?.multiRow ? 'multiple' : 'single'}
260
+ selectionMode={rowSelectionProp?.multiRow ? 'multiple' : 'single'}
180
261
  before={toolbarBefore}
181
262
  after={
182
- <>
183
- {toolbarAfter}
184
- {exportFileName ? (
185
- <ExportButton fileName={exportFileName} columnDefinitions={columnDefinitions} data={data} />
186
- ) : undefined}
187
- </>
263
+ toolbarAfter || exportFileName ? (
264
+ <>
265
+ {toolbarAfter}
266
+ {exportFileName && (
267
+ <ExportButton fileName={exportFileName} columnDefinitions={columnDefinitions} data={data} />
268
+ )}
269
+ </>
270
+ ) : undefined
188
271
  }
189
272
  moreActions={moreActions}
190
273
  />
@@ -228,8 +311,8 @@ export function Table<TData extends object>({
228
311
  {!suppressPagination && (
229
312
  <TablePagination
230
313
  table={table}
231
- options={pagination?.options}
232
- optionsLabel={pagination?.optionsLabel}
314
+ options={paginationProp?.options}
315
+ optionsLabel={paginationProp?.optionsLabel}
233
316
  pageCount={pageCount}
234
317
  />
235
318
  )}
@@ -1,2 +1 @@
1
1
  export * from './useLoadingTable';
2
- export * from './useTable';
@@ -1,10 +0,0 @@
1
- import { ColumnPinningState } from '@tanstack/react-table';
2
- import { ColumnDefinition } from '../../../types';
3
- import { TableProps } from '../../types';
4
- type UseTableProps<TData extends object> = Pick<TableProps<TData>, 'search' | 'rowSelection' | 'sorting' | 'pagination' | 'pageSize' | 'columnDefinitions' | 'data' | 'manualFiltering' | 'manualSorting' | 'manualPagination' | 'pageCount'>;
5
- export declare function useTable<TData extends object>({ search, pageSize, pagination: paginationProp, rowSelection: rowSelectionProp, sorting: sortingProp, columnDefinitions, manualFiltering, manualPagination, manualSorting, pageCount, data, }: UseTableProps<TData>): {
6
- table: import("@tanstack/react-table").Table<TData>;
7
- tableColumns: ColumnDefinition<TData>[];
8
- columnPinning: Required<ColumnPinningState>;
9
- };
10
- export {};
@@ -1,75 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { getCoreRowModel, getFilteredRowModel, getPaginationRowModel, getSortedRowModel, useReactTable, } from '@tanstack/react-table';
3
- import { useMemo } from 'react';
4
- import { TruncateString } from '@snack-uikit/truncate-string';
5
- import { DEFAULT_PAGE_SIZE } from '../../../constants';
6
- import { getColumnId, getSelectionCellColumnDef } from '../../../helperComponents';
7
- import { fuzzyFilter } from '../../../utils';
8
- import { useStateControl } from './useStateControl';
9
- export function useTable({ search, pageSize = DEFAULT_PAGE_SIZE, pagination: paginationProp, rowSelection: rowSelectionProp, sorting: sortingProp, columnDefinitions, manualFiltering, manualPagination, manualSorting, pageCount, data, }) {
10
- const { state: globalFilter, onStateChange: onGlobalFilterChange } = useStateControl(search, '');
11
- const { state: rowSelection, onStateChange: onRowSelectionChange } = useStateControl(rowSelectionProp, {});
12
- const defaultPaginationState = useMemo(() => ({
13
- pageIndex: 0,
14
- pageSize,
15
- }), [pageSize]);
16
- const { state: sorting, onStateChange: onSortingChange } = useStateControl(sortingProp, []);
17
- const { state: pagination, onStateChange: onPaginationChange } = useStateControl(paginationProp, defaultPaginationState);
18
- const enableSelection = Boolean(rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.enable);
19
- const tableColumns = useMemo(() => {
20
- let cols = columnDefinitions;
21
- if (enableSelection) {
22
- cols = [getSelectionCellColumnDef(), ...cols];
23
- }
24
- return cols;
25
- }, [columnDefinitions, enableSelection]);
26
- const columnPinning = useMemo(() => {
27
- var _a;
28
- const pinningState = { left: [], right: [] };
29
- for (const col of tableColumns) {
30
- const id = getColumnId(col);
31
- if (col.pinned && id) {
32
- (_a = pinningState[col.pinned]) === null || _a === void 0 ? void 0 : _a.push(id);
33
- }
34
- }
35
- return pinningState;
36
- }, [tableColumns]);
37
- const table = useReactTable({
38
- data,
39
- columns: tableColumns,
40
- state: {
41
- columnPinning,
42
- globalFilter,
43
- rowSelection,
44
- sorting,
45
- pagination,
46
- },
47
- pageCount,
48
- defaultColumn: {
49
- enableSorting: true,
50
- enableResizing: true,
51
- minSize: 40,
52
- cell: (cell) => _jsx(TruncateString, { text: String(cell.getValue()), maxLines: 1 }),
53
- },
54
- manualSorting,
55
- manualPagination,
56
- manualFiltering,
57
- globalFilterFn: fuzzyFilter,
58
- onGlobalFilterChange,
59
- onRowSelectionChange,
60
- enableRowSelection: rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.enable,
61
- enableMultiRowSelection: rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.multiRow,
62
- enableFilters: true,
63
- getFilteredRowModel: getFilteredRowModel(),
64
- enableColumnResizing: true,
65
- enableSorting: true,
66
- enableMultiSort: true,
67
- onSortingChange,
68
- getSortedRowModel: getSortedRowModel(),
69
- onPaginationChange,
70
- getPaginationRowModel: getPaginationRowModel(),
71
- getCoreRowModel: getCoreRowModel(),
72
- columnResizeMode: 'onEnd',
73
- });
74
- return { table, tableColumns, columnPinning };
75
- }
@@ -1,132 +0,0 @@
1
- import {
2
- CellContext,
3
- ColumnPinningState,
4
- getCoreRowModel,
5
- getFilteredRowModel,
6
- getPaginationRowModel,
7
- getSortedRowModel,
8
- PaginationState,
9
- RowSelectionState,
10
- SortingState,
11
- useReactTable,
12
- } from '@tanstack/react-table';
13
- import { useMemo } from 'react';
14
-
15
- import { TruncateString } from '@snack-uikit/truncate-string';
16
-
17
- import { DEFAULT_PAGE_SIZE } from '../../../constants';
18
- import { getColumnId, getSelectionCellColumnDef } from '../../../helperComponents';
19
- import { ColumnDefinition } from '../../../types';
20
- import { fuzzyFilter } from '../../../utils';
21
- import { TableProps } from '../../types';
22
- import { useStateControl } from './useStateControl';
23
-
24
- type UseTableProps<TData extends object> = Pick<
25
- TableProps<TData>,
26
- | 'search'
27
- | 'rowSelection'
28
- | 'sorting'
29
- | 'pagination'
30
- | 'pageSize'
31
- | 'columnDefinitions'
32
- | 'data'
33
- | 'manualFiltering'
34
- | 'manualSorting'
35
- | 'manualPagination'
36
- | 'pageCount'
37
- >;
38
-
39
- export function useTable<TData extends object>({
40
- search,
41
- pageSize = DEFAULT_PAGE_SIZE,
42
- pagination: paginationProp,
43
- rowSelection: rowSelectionProp,
44
- sorting: sortingProp,
45
- columnDefinitions,
46
- manualFiltering,
47
- manualPagination,
48
- manualSorting,
49
- pageCount,
50
- data,
51
- }: UseTableProps<TData>) {
52
- const { state: globalFilter, onStateChange: onGlobalFilterChange } = useStateControl<string>(search, '');
53
- const { state: rowSelection, onStateChange: onRowSelectionChange } = useStateControl<RowSelectionState>(
54
- rowSelectionProp,
55
- {},
56
- );
57
- const defaultPaginationState = useMemo(
58
- () => ({
59
- pageIndex: 0,
60
- pageSize,
61
- }),
62
- [pageSize],
63
- );
64
-
65
- const { state: sorting, onStateChange: onSortingChange } = useStateControl<SortingState>(sortingProp, []);
66
- const { state: pagination, onStateChange: onPaginationChange } = useStateControl<PaginationState>(
67
- paginationProp,
68
- defaultPaginationState,
69
- );
70
- const enableSelection = Boolean(rowSelectionProp?.enable);
71
- const tableColumns: ColumnDefinition<TData>[] = useMemo(() => {
72
- let cols: ColumnDefinition<TData>[] = columnDefinitions;
73
- if (enableSelection) {
74
- cols = [getSelectionCellColumnDef(), ...cols];
75
- }
76
- return cols;
77
- }, [columnDefinitions, enableSelection]);
78
- const columnPinning = useMemo(() => {
79
- const pinningState: Required<ColumnPinningState> = { left: [], right: [] };
80
- for (const col of tableColumns) {
81
- const id = getColumnId(col);
82
- if (col.pinned && id) {
83
- pinningState[col.pinned]?.push(id);
84
- }
85
- }
86
- return pinningState;
87
- }, [tableColumns]);
88
-
89
- const table = useReactTable<TData>({
90
- data,
91
- columns: tableColumns,
92
- state: {
93
- columnPinning,
94
- globalFilter,
95
- rowSelection,
96
- sorting,
97
- pagination,
98
- },
99
- pageCount,
100
- defaultColumn: {
101
- enableSorting: true,
102
- enableResizing: true,
103
- minSize: 40,
104
- cell: (cell: CellContext<TData, unknown>) => <TruncateString text={String(cell.getValue())} maxLines={1} />,
105
- },
106
-
107
- manualSorting,
108
- manualPagination,
109
- manualFiltering,
110
-
111
- globalFilterFn: fuzzyFilter,
112
- onGlobalFilterChange,
113
-
114
- onRowSelectionChange,
115
- enableRowSelection: rowSelectionProp?.enable,
116
- enableMultiRowSelection: rowSelectionProp?.multiRow,
117
- enableFilters: true,
118
- getFilteredRowModel: getFilteredRowModel(),
119
- enableColumnResizing: true,
120
- enableSorting: true,
121
- enableMultiSort: true,
122
- onSortingChange,
123
- getSortedRowModel: getSortedRowModel(),
124
- onPaginationChange,
125
- getPaginationRowModel: getPaginationRowModel(),
126
- getCoreRowModel: getCoreRowModel(),
127
-
128
- columnResizeMode: 'onEnd',
129
- });
130
-
131
- return { table, tableColumns, columnPinning };
132
- }