@snack-uikit/table 0.19.6-preview-cb303567.0 → 0.19.6
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 +9 -0
- package/README.md +7 -11
- package/dist/components/Table/Table.d.ts +1 -1
- package/dist/components/Table/Table.js +11 -24
- package/dist/components/Table/hooks/usePageReset.d.ts +1 -2
- package/dist/components/Table/hooks/usePageReset.js +2 -4
- package/dist/components/Table/styles.module.css +4 -4
- package/dist/components/types.d.ts +5 -12
- package/dist/helperComponents/Cells/BodyCell/styles.module.css +1 -1
- package/dist/helperComponents/Cells/HeaderCell/styles.module.css +4 -4
- package/dist/helperComponents/Cells/StatusCell/styles.module.css +4 -4
- package/dist/helperComponents/ExportButton/ExportButton.d.ts +3 -17
- package/dist/helperComponents/ExportButton/ExportButton.js +4 -15
- package/dist/helperComponents/Rows/styles.module.css +6 -6
- package/dist/helperComponents/TablePagination/TablePagination.d.ts +1 -2
- package/dist/helperComponents/TablePagination/TablePagination.js +2 -5
- package/package.json +3 -3
- package/src/components/Table/Table.tsx +16 -40
- package/src/components/Table/hooks/usePageReset.ts +1 -5
- package/src/components/types.ts +5 -13
- package/src/helperComponents/ExportButton/ExportButton.tsx +6 -45
- package/src/helperComponents/TablePagination/TablePagination.tsx +2 -10
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,15 @@
|
|
|
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.19.6 (2024-07-09)
|
|
7
|
+
|
|
8
|
+
### Only dependencies have been changed
|
|
9
|
+
* [@snack-uikit/toolbar@0.7.46](https://github.com/cloud-ru-tech/snack-uikit/blob/master/packages/toolbar/CHANGELOG.md)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
6
15
|
## 0.19.5 (2024-06-27)
|
|
7
16
|
|
|
8
17
|
### Only dependencies have been changed
|
package/README.md
CHANGED
|
@@ -111,16 +111,14 @@ const columnDefinitions: ColumnDefinition<TableData>[] = [
|
|
|
111
111
|
|------|------|---------------|-------------|
|
|
112
112
|
| columnDefinitions* | `ColumnDefinition<TData>[]` | - | Определение внешнего вида и функционала колонок |
|
|
113
113
|
| data* | `TData[]` | - | Данные для отрисовки |
|
|
114
|
-
| keepPinnedRows | `boolean` | - | Параметр
|
|
115
|
-
|
|
|
116
|
-
| enableSelectPinned | `boolean` | - | Параметр отвечает за чекбокс выбора закрепленных строк |
|
|
114
|
+
| keepPinnedRows | `boolean` | - | Параметр овтечает за сохранение закрепленных строк на всех страницах таблицы |
|
|
115
|
+
| enableSelectPinned | `boolean` | - | Параметр овтечает за чекбокс выбора закрепленных строк |
|
|
117
116
|
| sorting | `{ initialState?: SortingState; state?: SortingState; onChange?(state: SortingState): void; }` | - | Параметры отвечают за возможность сортировки, их стоит использовать если нужно отслеживать состояние <br> <strong>initialState</strong>: Начальное состояние сортировки <br> <strong>state</strong>: Состояние сортировки, жестко устанавливаемое снаружи <br> <strong>onChange</strong>: Колбэк на изменение сортировки |
|
|
118
117
|
| rowSelection | `{ initialState?: RowSelectionState; state?: RowSelectionState; enable?: boolean \| ((row: Row<TData>) => boolean); multiRow?: boolean; onChange?(state: RowSelectionState): void; }` | - | Параметры отвечают за возможность выбора строк <br> <strong>initialState</strong>: Начальное состояние выбора строк <br> <strong>state</strong>: Состояние выбора строк, жестко устанавливаемое снаружи <br> <strong>enable</strong>: Колбэк определяющий можно ли выбрать строку <br> <strong>multiRow</strong>: Мульти-выбор строк (включен по-умолчанию, когда включается выбор) <br> <strong>onChange</strong>: Колбэк на выбор строк |
|
|
119
118
|
| search | `{ initialState?: string; state?: string; placeholder?: string; loading?: boolean; onChange?(value: string): void; }` | 'Search'<br> <strong>loading</strong>: Состояние загрузки в строке поиска <br> <strong>onChange</strong>: Колбэк на изменение данных в строке поиска | Параметры отвечают за глобальный поиск в таблице <br> <strong>initialState</strong>: Начальное состояние строки поиска <br> <strong>state</strong>: Состояние строки поиска, жестко устанавливаемое снаружи <br> <strong>placeholder</strong>: Placeholder строки поиска |
|
|
120
119
|
| enableFuzzySearch | `boolean` | - | Включить нечеткий поиск |
|
|
121
120
|
| pageSize | `number` | 10 | Максимальное кол-во строк на страницу |
|
|
122
|
-
| pagination | `{ state?: PaginationState; options?: number[]; optionsLabel?: string; onChange?(state: PaginationState): void;
|
|
123
|
-
| autoResetPageIndex | `boolean` | - | Автоматический сброс пагинации к первой странице при изменении данных или состояния (e.g фильтры, сортировки, и т.д) |
|
|
121
|
+
| pagination | `{ state?: PaginationState; options?: number[]; optionsLabel?: string; onChange?(state: PaginationState): void; }` | 'Rows volume: ' <br> <strong>onChange</strong>: Колбэк на изменение пагинации | Параметры отвечают за пагинацию в таблице <br> <strong>state</strong>: Состояние строки поиска, жестко устанавливаемое снаружи <br> <strong>options</strong>: Варианты в выпадающем селекторе для установки кол-ва строк на страницу <br> <strong>optionsLabel</strong>: Текст для селектора кол-ва строк на страницу |
|
|
124
122
|
| pageCount | `number` | - | Кол-во страниц (используется для внешнего управления) |
|
|
125
123
|
| onRowClick | `RowClickHandler<TData>` | - | Колбэк клика по строке |
|
|
126
124
|
| className | `string` | - | CSS-класс |
|
|
@@ -131,7 +129,7 @@ const columnDefinitions: ColumnDefinition<TableData>[] = [
|
|
|
131
129
|
| columnFilters | `ReactNode` | - | Фильтры |
|
|
132
130
|
| dataFiltered | `boolean` | - | |
|
|
133
131
|
| dataError | `boolean` | - | |
|
|
134
|
-
|
|
|
132
|
+
| exportFileName | `string` | - | Название файла при экспорте CSV/XLSX |
|
|
135
133
|
| moreActions | `Action[]` | - | Элементы выпадающего списка кнопки с действиями |
|
|
136
134
|
| noDataState | `EmptyStateProps` | - | Экран при отстутствии данных |
|
|
137
135
|
| noResultsState | `EmptyStateProps` | - | Экран при отстутствии результатов поиска или фильтров |
|
|
@@ -173,13 +171,11 @@ const columnDefinitions: ColumnDefinition<TableData>[] = [
|
|
|
173
171
|
| onChangePage* | `(offset: number, limit: number) => void` | - | |
|
|
174
172
|
| columnDefinitions* | `ColumnDefinition<TData>[]` | - | Определение внешнего вида и функционала колонок |
|
|
175
173
|
| loading | `boolean` | - | Состояние загрузки |
|
|
176
|
-
| keepPinnedRows | `boolean` |
|
|
177
|
-
|
|
|
178
|
-
| enableSelectPinned | `boolean` | - | Параметр отвечает за чекбокс выбора закрепленных строк |
|
|
174
|
+
| keepPinnedRows | `boolean` | - | Параметр овтечает за сохранение закрепленных строк на всех страницах таблицы |
|
|
175
|
+
| enableSelectPinned | `boolean` | - | Параметр овтечает за чекбокс выбора закрепленных строк |
|
|
179
176
|
| sorting | `{ initialState?: SortingState; state?: SortingState; onChange?(state: SortingState): void; }` | - | Параметры отвечают за возможность сортировки, их стоит использовать если нужно отслеживать состояние <br> <strong>initialState</strong>: Начальное состояние сортировки <br> <strong>state</strong>: Состояние сортировки, жестко устанавливаемое снаружи <br> <strong>onChange</strong>: Колбэк на изменение сортировки |
|
|
180
177
|
| rowSelection | `{ initialState?: RowSelectionState; state?: RowSelectionState; enable?: boolean \| ((row: Row<TData>) => boolean); multiRow?: boolean; onChange?(state: RowSelectionState): void; }` | - | Параметры отвечают за возможность выбора строк <br> <strong>initialState</strong>: Начальное состояние выбора строк <br> <strong>state</strong>: Состояние выбора строк, жестко устанавливаемое снаружи <br> <strong>enable</strong>: Колбэк определяющий можно ли выбрать строку <br> <strong>multiRow</strong>: Мульти-выбор строк (включен по-умолчанию, когда включается выбор) <br> <strong>onChange</strong>: Колбэк на выбор строк |
|
|
181
178
|
| enableFuzzySearch | `boolean` | - | Включить нечеткий поиск |
|
|
182
|
-
| autoResetPageIndex | `boolean` | - | Автоматический сброс пагинации к первой странице при изменении данных или состояния (e.g фильтры, сортировки, и т.д) |
|
|
183
179
|
| onRowClick | `RowClickHandler<TData>` | - | Колбэк клика по строке |
|
|
184
180
|
| className | `string` | - | CSS-класс |
|
|
185
181
|
| onRefresh | `() => void` | - | Колбек обновления данных |
|
|
@@ -188,7 +184,7 @@ const columnDefinitions: ColumnDefinition<TableData>[] = [
|
|
|
188
184
|
| columnFilters | `ReactNode` | - | Фильтры |
|
|
189
185
|
| dataFiltered | `boolean` | - | |
|
|
190
186
|
| dataError | `boolean` | - | |
|
|
191
|
-
|
|
|
187
|
+
| exportFileName | `string` | - | Название файла при экспорте CSV/XLSX |
|
|
192
188
|
| moreActions | `Action[]` | - | Элементы выпадающего списка кнопки с действиями |
|
|
193
189
|
| noDataState | `EmptyStateProps` | - | Экран при отстутствии данных |
|
|
194
190
|
| noResultsState | `EmptyStateProps` | - | Экран при отстутствии результатов поиска или фильтров |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { TableProps } from '../types';
|
|
2
2
|
/** Компонент таблицы */
|
|
3
|
-
export declare function Table<TData extends object>({ data, rowPinning, columnDefinitions, keepPinnedRows,
|
|
3
|
+
export declare function Table<TData extends object>({ data, rowPinning, columnDefinitions, keepPinnedRows, enableSelectPinned, 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, getRowId, enableFuzzySearch, ...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: {
|
|
@@ -30,7 +30,7 @@ import { getColumnStyleVars, getCurrentlyConfiguredHeaderWidth } from './utils';
|
|
|
30
30
|
export function Table(_a) {
|
|
31
31
|
var { data, rowPinning = {
|
|
32
32
|
top: [],
|
|
33
|
-
}, columnDefinitions, keepPinnedRows = false,
|
|
33
|
+
}, columnDefinitions, keepPinnedRows = false, enableSelectPinned = false, 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, getRowId, enableFuzzySearch } = _a, rest = __rest(_a, ["data", "rowPinning", "columnDefinitions", "keepPinnedRows", "enableSelectPinned", "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", "getRowId", "enableFuzzySearch"]);
|
|
34
34
|
const { state: globalFilter, onStateChange: onGlobalFilterChange } = useStateControl(search, '');
|
|
35
35
|
const { state: rowSelection, onStateChange: onRowSelectionChange } = useStateControl(rowSelectionProp, {});
|
|
36
36
|
const defaultPaginationState = useMemo(() => ({
|
|
@@ -93,17 +93,13 @@ export function Table(_a) {
|
|
|
93
93
|
onSortingChange,
|
|
94
94
|
getSortedRowModel: getSortedRowModel(),
|
|
95
95
|
onPaginationChange,
|
|
96
|
-
autoResetPageIndex,
|
|
96
|
+
autoResetPageIndex: false,
|
|
97
97
|
getPaginationRowModel: getPaginationRowModel(),
|
|
98
98
|
getCoreRowModel: getCoreRowModel(),
|
|
99
99
|
columnResizeMode: 'onEnd',
|
|
100
100
|
keepPinnedRows,
|
|
101
101
|
});
|
|
102
|
-
const { loadingTable } = useLoadingTable({
|
|
103
|
-
pageSize: Math.min(Math.max(pageSize, 5), DEFAULT_PAGE_SIZE),
|
|
104
|
-
columnDefinitions: tableColumns,
|
|
105
|
-
columnPinning,
|
|
106
|
-
});
|
|
102
|
+
const { loadingTable } = useLoadingTable({ pageSize, columnDefinitions: tableColumns, columnPinning });
|
|
107
103
|
const handleOnRefresh = useCallback(() => {
|
|
108
104
|
table.resetRowSelection();
|
|
109
105
|
onRefresh === null || onRefresh === void 0 ? void 0 : onRefresh();
|
|
@@ -117,22 +113,15 @@ export function Table(_a) {
|
|
|
117
113
|
}
|
|
118
114
|
}, [loading, onDelete, table]);
|
|
119
115
|
const handleOnCheck = useCallback(() => {
|
|
120
|
-
if (!loading && !enableSelectPinned && table.getTopRows().length) {
|
|
121
|
-
const centerRows = table.getCenterRows();
|
|
122
|
-
const isSomeRowsSelected = table.getIsSomePageRowsSelected();
|
|
123
|
-
const isAllCenterRowsSelected = centerRows.every(row => row.getIsSelected());
|
|
124
|
-
if (isAllCenterRowsSelected) {
|
|
125
|
-
table.resetRowSelection();
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
centerRows.forEach(row => row.toggleSelected(isSomeRowsSelected ? true : undefined));
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
116
|
if (!loading && (rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.multiRow)) {
|
|
132
117
|
table.toggleAllPageRowsSelected();
|
|
133
118
|
return;
|
|
134
119
|
}
|
|
135
|
-
|
|
120
|
+
if (!loading && table.getIsSomePageRowsSelected()) {
|
|
121
|
+
table.resetRowSelection();
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
}, [loading, rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.multiRow, table]);
|
|
136
125
|
const columnSizeVarsRef = useRef();
|
|
137
126
|
const headers = table.getFlatHeaders();
|
|
138
127
|
const columnSizeVars = useMemo(() => {
|
|
@@ -184,19 +173,17 @@ export function Table(_a) {
|
|
|
184
173
|
const filteredTopRows = table.getState().globalFilter
|
|
185
174
|
? topRows.filter(tr => tableFilteredRowsIds.includes(tr.id))
|
|
186
175
|
: topRows;
|
|
187
|
-
const centerRows = copyPinnedRows ? tableRows : tableCenterRows;
|
|
188
176
|
const { t } = useLocale('Table');
|
|
189
177
|
const emptyStates = useEmptyState({ noDataState, noResultsState, errorDataState });
|
|
190
178
|
const cssPageSize = useMemo(() => {
|
|
191
|
-
const tempPageSize =
|
|
179
|
+
const tempPageSize = !suppressPagination ? tablePagination === null || tablePagination === void 0 ? void 0 : tablePagination.pageSize : pageSize;
|
|
192
180
|
return !tableRows.length ? Math.min(Math.max(tempPageSize, 5), DEFAULT_PAGE_SIZE) : tempPageSize;
|
|
193
|
-
}, [
|
|
181
|
+
}, [pageSize, suppressPagination, tablePagination === null || tablePagination === void 0 ? void 0 : tablePagination.pageSize, tableRows.length]);
|
|
194
182
|
usePageReset({
|
|
195
183
|
manualPagination,
|
|
196
184
|
maximumAvailablePage: pageCount || data.length / pagination.pageSize,
|
|
197
185
|
pagination,
|
|
198
186
|
onPaginationChange,
|
|
199
|
-
autoResetPageIndex,
|
|
200
187
|
});
|
|
201
188
|
return (_jsx(_Fragment, { children: _jsxs("div", Object.assign({ style: {
|
|
202
189
|
'--page-size': cssPageSize,
|
|
@@ -205,7 +192,7 @@ export function Table(_a) {
|
|
|
205
192
|
onChange: onGlobalFilterChange,
|
|
206
193
|
loading: search === null || search === void 0 ? void 0 : search.loading,
|
|
207
194
|
placeholder: (search === null || search === void 0 ? void 0 : search.placeholder) || t('searchPlaceholder'),
|
|
208
|
-
}, 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 ||
|
|
195
|
+
}, 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: [tableCenterRows.length || filteredTopRows.length ? _jsx(HeaderRow, {}) : null, filteredTopRows.length ? (_jsx("div", { className: styles.topRowWrapper, children: filteredTopRows.map(row => (_jsx(BodyRow, { row: row, onRowClick: onRowClick }, row.id))) })) : null, tableCenterRows.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 }))] })) }));
|
|
209
196
|
}
|
|
210
197
|
Table.getStatusColumnDef = getStatusColumnDef;
|
|
211
198
|
Table.statusAppearances = STATUS_APPEARANCE;
|
|
@@ -4,7 +4,6 @@ type UsePageResetProps = {
|
|
|
4
4
|
maximumAvailablePage: number;
|
|
5
5
|
pagination: PaginationState;
|
|
6
6
|
onPaginationChange(state: PaginationState): void;
|
|
7
|
-
autoResetPageIndex: boolean;
|
|
8
7
|
};
|
|
9
|
-
export declare function usePageReset({ manualPagination, pagination, maximumAvailablePage, onPaginationChange,
|
|
8
|
+
export declare function usePageReset({ manualPagination, pagination, maximumAvailablePage, onPaginationChange, }: UsePageResetProps): void;
|
|
10
9
|
export {};
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { useEffect } from 'react';
|
|
2
|
-
export function usePageReset({ manualPagination, pagination, maximumAvailablePage, onPaginationChange,
|
|
2
|
+
export function usePageReset({ manualPagination, pagination, maximumAvailablePage, onPaginationChange, }) {
|
|
3
3
|
useEffect(() => {
|
|
4
|
-
if (autoResetPageIndex)
|
|
5
|
-
return;
|
|
6
4
|
const { pageIndex } = pagination;
|
|
7
5
|
if (!manualPagination && pageIndex > 0 && pageIndex >= maximumAvailablePage) {
|
|
8
6
|
onPaginationChange(Object.assign(Object.assign({}, pagination), { pageIndex: 0 }));
|
|
9
7
|
}
|
|
10
|
-
}, [maximumAvailablePage, manualPagination, onPaginationChange, pagination
|
|
8
|
+
}, [maximumAvailablePage, manualPagination, onPaginationChange, pagination]);
|
|
11
9
|
}
|
|
@@ -9,13 +9,13 @@
|
|
|
9
9
|
width:100%;
|
|
10
10
|
height:auto;
|
|
11
11
|
max-height:calc(var(--page-size, 10) * var(--size-table-line-height, 40px) + var(--size-table-line-height, 40px) + var(--border-width-table, 1px) * 2);
|
|
12
|
-
background-color:var(--sys-neutral-background1-level, #
|
|
13
|
-
border-color:var(--sys-neutral-background1-level, #
|
|
12
|
+
background-color:var(--sys-neutral-background1-level, #fdfdfd);
|
|
13
|
+
border-color:var(--sys-neutral-background1-level, #fdfdfd);
|
|
14
14
|
border-style:solid;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
.scrollWrapper[data-outline] .table{
|
|
18
|
-
border-color:var(--sys-neutral-decor-default, #
|
|
18
|
+
border-color:var(--sys-neutral-decor-default, #dde0ea);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
.header{
|
|
@@ -61,5 +61,5 @@
|
|
|
61
61
|
z-index:3;
|
|
62
62
|
top:calc(var(--size-table-line-height, 40px));
|
|
63
63
|
margin-bottom:calc(-1 * var(--border-width-table, 1px));
|
|
64
|
-
border-bottom:var(--border-width-table, 1px) solid var(--sys-neutral-decor-default, #
|
|
64
|
+
border-bottom:var(--border-width-table, 1px) solid var(--sys-neutral-decor-default, #dde0ea);
|
|
65
65
|
}
|
|
@@ -2,18 +2,16 @@ import { PaginationState, Row, RowPinningState, RowSelectionOptions, RowSelectio
|
|
|
2
2
|
import { ReactNode, RefObject } from 'react';
|
|
3
3
|
import { ToolbarProps } from '@snack-uikit/toolbar';
|
|
4
4
|
import { WithSupportProps } from '@snack-uikit/utils';
|
|
5
|
-
import { EmptyStateProps,
|
|
5
|
+
import { EmptyStateProps, RowClickHandler } from '../helperComponents';
|
|
6
6
|
import { ColumnDefinition } from '../types';
|
|
7
7
|
export type TableProps<TData extends object> = WithSupportProps<{
|
|
8
8
|
/** Данные для отрисовки */
|
|
9
9
|
data: TData[];
|
|
10
10
|
/** Определение внешнего вида и функционала колонок */
|
|
11
11
|
columnDefinitions: ColumnDefinition<TData>[];
|
|
12
|
-
/** Параметр
|
|
12
|
+
/** Параметр овтечает за сохранение закрепленных строк на всех страницах таблицы */
|
|
13
13
|
keepPinnedRows?: boolean;
|
|
14
|
-
/** Параметр
|
|
15
|
-
copyPinnedRows?: boolean;
|
|
16
|
-
/** Параметр отвечает за чекбокс выбора закрепленных строк */
|
|
14
|
+
/** Параметр овтечает за чекбокс выбора закрепленных строк */
|
|
17
15
|
enableSelectPinned?: boolean;
|
|
18
16
|
/** Параметры отвечают за возможность сортировки, их стоит использовать если нужно отслеживать состояние <br>
|
|
19
17
|
* <strong>initialState</strong>: Начальное состояние сортировки <br>
|
|
@@ -68,12 +66,7 @@ export type TableProps<TData extends object> = WithSupportProps<{
|
|
|
68
66
|
options?: number[];
|
|
69
67
|
optionsLabel?: string;
|
|
70
68
|
onChange?(state: PaginationState): void;
|
|
71
|
-
optionsRender?(value: string | number, idx: number): string | number;
|
|
72
69
|
};
|
|
73
|
-
/** Автоматический сброс пагинации к первой странице при изменении данных или состояния
|
|
74
|
-
* (e.g фильтры, сортировки, и т.д)
|
|
75
|
-
* */
|
|
76
|
-
autoResetPageIndex?: boolean;
|
|
77
70
|
/** Кол-во страниц (используется для внешнего управления) */
|
|
78
71
|
pageCount?: number;
|
|
79
72
|
/** Колбэк клика по строке */
|
|
@@ -92,8 +85,8 @@ export type TableProps<TData extends object> = WithSupportProps<{
|
|
|
92
85
|
columnFilters?: ReactNode;
|
|
93
86
|
dataFiltered?: boolean;
|
|
94
87
|
dataError?: boolean;
|
|
95
|
-
/**
|
|
96
|
-
|
|
88
|
+
/** Название файла при экспорте CSV/XLSX */
|
|
89
|
+
exportFileName?: string;
|
|
97
90
|
/** Элементы выпадающего списка кнопки с действиями */
|
|
98
91
|
moreActions?: ToolbarProps['moreActions'];
|
|
99
92
|
/** Экран при отстутствии данных */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
gap:var(--space-table-cell-gap, 4px);
|
|
3
3
|
padding-left:var(--space-table-cell-padding, 8px);
|
|
4
4
|
padding-right:var(--space-table-cell-padding, 8px);
|
|
5
|
-
color:var(--sys-neutral-text-main, #
|
|
5
|
+
color:var(--sys-neutral-text-main, #33343f);
|
|
6
6
|
}
|
|
7
7
|
.tableBodyCell[data-align=right]{
|
|
8
8
|
justify-content:flex-end;
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
transform:translateX(var(--offset));
|
|
33
33
|
width:1px;
|
|
34
34
|
height:100%;
|
|
35
|
-
background-color:var(--sys-neutral-decor-activated, #
|
|
35
|
+
background-color:var(--sys-neutral-decor-activated, #bec2cf);
|
|
36
36
|
}
|
|
37
37
|
.tableHeaderResizeIndicator::after{
|
|
38
38
|
content:"";
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
transform:translateX(-50%);
|
|
67
67
|
width:calc(100% - var(--space-table-head-separator-padding, 8px) * 2);
|
|
68
68
|
height:var(--border-width-table, 1px);
|
|
69
|
-
background-color:var(--sys-neutral-decor-default, #
|
|
69
|
+
background-color:var(--sys-neutral-decor-default, #dde0ea);
|
|
70
70
|
}
|
|
71
71
|
.tableHeaderCell:hover .tableHeaderResizeHandle:not([data-resizing]){
|
|
72
72
|
opacity:1;
|
|
@@ -118,13 +118,13 @@
|
|
|
118
118
|
align-items:center;
|
|
119
119
|
box-sizing:border-box;
|
|
120
120
|
min-width:0;
|
|
121
|
-
color:var(--sys-neutral-text-light, #
|
|
121
|
+
color:var(--sys-neutral-text-light, #8b8e9b);
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
.tableHeaderIcon{
|
|
125
125
|
display:flex;
|
|
126
126
|
box-sizing:border-box;
|
|
127
|
-
color:var(--sys-neutral-text-light, #
|
|
127
|
+
color:var(--sys-neutral-text-light, #8b8e9b);
|
|
128
128
|
}
|
|
129
129
|
.tableHeaderIcon svg{
|
|
130
130
|
width:var(--size-icon-container-xs, 16px) !important;
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
.statusCellLabel{
|
|
15
15
|
box-sizing:border-box;
|
|
16
16
|
min-width:0;
|
|
17
|
-
color:var(--sys-neutral-text-support, #
|
|
17
|
+
color:var(--sys-neutral-text-support, #6d707f);
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
.statusCellIndicator{
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
background-color:var(--sys-primary-accent-default, #794ed3);
|
|
45
45
|
}
|
|
46
46
|
.statusCellIndicator[data-appearance=neutral]::after{
|
|
47
|
-
background-color:var(--sys-neutral-accent-default, #
|
|
47
|
+
background-color:var(--sys-neutral-accent-default, #787b8a);
|
|
48
48
|
}
|
|
49
49
|
.statusCellIndicator[data-appearance=red]::after{
|
|
50
50
|
background-color:var(--sys-red-accent-default, #cd3c3c);
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
background-color:var(--sys-orange-accent-default, #ff8b37);
|
|
54
54
|
}
|
|
55
55
|
.statusCellIndicator[data-appearance=yellow]::after{
|
|
56
|
-
background-color:var(--sys-yellow-accent-default, #
|
|
56
|
+
background-color:var(--sys-yellow-accent-default, #ffc443);
|
|
57
57
|
}
|
|
58
58
|
.statusCellIndicator[data-appearance=green]::after{
|
|
59
59
|
background-color:var(--sys-green-accent-default, #57b762);
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
left:0;
|
|
77
77
|
width:100%;
|
|
78
78
|
height:auto;
|
|
79
|
-
background-color:var(--sys-neutral-decor-default, #
|
|
79
|
+
background-color:var(--sys-neutral-decor-default, #dde0ea);
|
|
80
80
|
animation:loading ease-in-out 0.8s infinite alternate;
|
|
81
81
|
}
|
|
82
82
|
|
|
@@ -1,24 +1,10 @@
|
|
|
1
|
-
import { Row } from '@tanstack/react-table';
|
|
2
1
|
import { ColumnDefinition } from '../../types';
|
|
3
|
-
type
|
|
4
|
-
csv?: boolean;
|
|
5
|
-
xslx?: boolean;
|
|
6
|
-
};
|
|
7
|
-
export type ExportButtonProps<TData extends object> = {
|
|
2
|
+
type ExportButtonProps<TData extends object> = {
|
|
8
3
|
/** Данные для отрисовки */
|
|
9
4
|
data: TData[];
|
|
10
5
|
/** Определение внешнего вида и функционала колонок */
|
|
11
6
|
columnDefinitions: ColumnDefinition<TData>[];
|
|
12
|
-
|
|
13
|
-
/** Название файла при экспорте */
|
|
14
|
-
fileName: string;
|
|
15
|
-
/** Доступные форматы экспорта */
|
|
16
|
-
format?: Format;
|
|
17
|
-
/** Настройка фильтрации данных */
|
|
18
|
-
filterData?: boolean;
|
|
19
|
-
};
|
|
20
|
-
topRows: Row<TData>[];
|
|
21
|
-
centerRows: Row<TData>[];
|
|
7
|
+
fileName?: string;
|
|
22
8
|
};
|
|
23
|
-
export declare function ExportButton<TData extends object>({
|
|
9
|
+
export declare function ExportButton<TData extends object>({ fileName, data, columnDefinitions }: ExportButtonProps<TData>): import("react/jsx-runtime").JSX.Element;
|
|
24
10
|
export {};
|
|
@@ -1,38 +1,27 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { useState } from 'react';
|
|
3
3
|
import { ButtonFunction } from '@snack-uikit/button';
|
|
4
4
|
import { DownloadSVG } from '@snack-uikit/icons';
|
|
5
5
|
import { Droplist } from '@snack-uikit/list';
|
|
6
6
|
import { useLocale } from '@snack-uikit/locale';
|
|
7
7
|
import { exportToCSV, exportToXLSX } from '../../exportTable';
|
|
8
|
-
export function ExportButton({
|
|
8
|
+
export function ExportButton({ fileName, data, columnDefinitions }) {
|
|
9
9
|
const [isOpen, setIsOpen] = useState(false);
|
|
10
10
|
const { t } = useLocale('Table');
|
|
11
|
-
const { fileName, filterData = true } = settings;
|
|
12
|
-
const format = Object.assign({ csv: true, xslx: true }, settings.format);
|
|
13
|
-
const filteredData = useMemo(() => {
|
|
14
|
-
let newData = data;
|
|
15
|
-
if (filterData) {
|
|
16
|
-
newData = [...topRows, ...centerRows].map(row => row.original);
|
|
17
|
-
}
|
|
18
|
-
return newData;
|
|
19
|
-
}, [centerRows, data, filterData, topRows]);
|
|
20
11
|
return (_jsx(Droplist, { trigger: 'clickAndFocusVisible', open: isOpen, onOpenChange: setIsOpen, scroll: true, placement: 'bottom-end', items: [
|
|
21
12
|
{
|
|
22
13
|
content: { option: t('export') + 'CSV' },
|
|
23
14
|
onClick: () => {
|
|
24
|
-
exportToCSV({ fileName, columnDefinitions, data
|
|
15
|
+
exportToCSV({ fileName, columnDefinitions, data });
|
|
25
16
|
setIsOpen(false);
|
|
26
17
|
},
|
|
27
|
-
hidden: !format.csv,
|
|
28
18
|
},
|
|
29
19
|
{
|
|
30
20
|
content: { option: t('export') + 'XLSX' },
|
|
31
21
|
onClick: () => {
|
|
32
|
-
exportToXLSX({ fileName, columnDefinitions, data
|
|
22
|
+
exportToXLSX({ fileName, columnDefinitions, data });
|
|
33
23
|
setIsOpen(false);
|
|
34
24
|
},
|
|
35
|
-
hidden: !format.xslx,
|
|
36
25
|
},
|
|
37
26
|
], children: _jsx(ButtonFunction, { size: 'm', icon: _jsx(DownloadSVG, {}) }) }));
|
|
38
27
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
.tableRow{
|
|
2
|
-
--snack-ui-table-row-background:var(--sys-neutral-background1-level, #
|
|
2
|
+
--snack-ui-table-row-background:var(--sys-neutral-background1-level, #fdfdfd);
|
|
3
3
|
height:var(--size-table-line-height, 40px);
|
|
4
4
|
border-top:var(--border-width-table, 1px);
|
|
5
5
|
border-bottom:var(--border-width-table, 1px);
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
display:flex;
|
|
18
18
|
box-sizing:border-box;
|
|
19
19
|
background-color:var(--snack-ui-table-row-background);
|
|
20
|
-
border-color:var(--sys-neutral-decor-default, #
|
|
20
|
+
border-color:var(--sys-neutral-decor-default, #dde0ea);
|
|
21
21
|
}
|
|
22
22
|
.rowPinnedCells::after{
|
|
23
23
|
pointer-events:none;
|
|
@@ -48,10 +48,10 @@
|
|
|
48
48
|
|
|
49
49
|
.bodyRow[data-disabled]{
|
|
50
50
|
cursor:not-allowed;
|
|
51
|
-
background-color:var(--sys-neutral-background, #
|
|
51
|
+
background-color:var(--sys-neutral-background, #eeeff3);
|
|
52
52
|
}
|
|
53
53
|
.bodyRow[data-disabled] .rowPinnedCells{
|
|
54
|
-
background-color:var(--sys-neutral-background, #
|
|
54
|
+
background-color:var(--sys-neutral-background, #eeeff3);
|
|
55
55
|
}
|
|
56
56
|
.bodyRow[data-selected]{
|
|
57
57
|
background-color:color-mix(in srgb, var(--sys-primary-accent-default, #794ed3), var(--snack-ui-table-row-background) calc((1 - var(--opacity-a008, 0.08)) * 100%));
|
|
@@ -72,11 +72,11 @@
|
|
|
72
72
|
cursor:pointer;
|
|
73
73
|
}
|
|
74
74
|
.bodyRow:not([data-disabled]):not([data-selected]):hover, .bodyRow:not([data-disabled]):not([data-selected])[data-actions-opened]{
|
|
75
|
-
background-color:color-mix(in srgb, var(--sys-neutral-accent-default, #
|
|
75
|
+
background-color:color-mix(in srgb, var(--sys-neutral-accent-default, #787b8a), var(--snack-ui-table-row-background) calc((1 - var(--opacity-a008, 0.08)) * 100%));
|
|
76
76
|
border-color:var(--sys-neutral-decor-hovered, #cfd2dc);
|
|
77
77
|
}
|
|
78
78
|
.bodyRow:not([data-disabled]):not([data-selected]):hover .rowPinnedCells, .bodyRow:not([data-disabled]):not([data-selected])[data-actions-opened] .rowPinnedCells{
|
|
79
|
-
background-color:color-mix(in srgb, var(--sys-neutral-accent-default, #
|
|
79
|
+
background-color:color-mix(in srgb, var(--sys-neutral-accent-default, #787b8a), var(--snack-ui-table-row-background) calc((1 - var(--opacity-a008, 0.08)) * 100%));
|
|
80
80
|
border-color:inherit;
|
|
81
81
|
}
|
|
82
82
|
|
|
@@ -3,7 +3,6 @@ export type TablePaginationProps<TData> = {
|
|
|
3
3
|
table: Table<TData>;
|
|
4
4
|
options?: number[];
|
|
5
5
|
optionsLabel?: string;
|
|
6
|
-
optionsRender?(value: number, idx: number): string | number;
|
|
7
6
|
pageCount?: number;
|
|
8
7
|
};
|
|
9
|
-
export declare function TablePagination<TData>({ table, options: optionsProp, optionsLabel: optionsLabelProp,
|
|
8
|
+
export declare function TablePagination<TData>({ table, options: optionsProp, optionsLabel: optionsLabelProp, }: TablePaginationProps<TData>): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -4,7 +4,7 @@ import { ChipChoice } from '@snack-uikit/chips';
|
|
|
4
4
|
import { useLocale } from '@snack-uikit/locale';
|
|
5
5
|
import { Pagination } from '@snack-uikit/pagination';
|
|
6
6
|
import styles from './styles.module.css';
|
|
7
|
-
export function TablePagination({ table, options: optionsProp, optionsLabel: optionsLabelProp,
|
|
7
|
+
export function TablePagination({ table, options: optionsProp, optionsLabel: optionsLabelProp, }) {
|
|
8
8
|
const { t } = useLocale('Table');
|
|
9
9
|
const optionsLabel = optionsLabelProp !== null && optionsLabelProp !== void 0 ? optionsLabelProp : t('rowsOptionsLabel');
|
|
10
10
|
const handlePaginationOnChange = useCallback((pageIndex) => {
|
|
@@ -13,10 +13,7 @@ export function TablePagination({ table, options: optionsProp, optionsLabel: opt
|
|
|
13
13
|
const handleRowsVolumeOnChange = useCallback((value) => {
|
|
14
14
|
table.setPageSize(Number(value));
|
|
15
15
|
}, [table]);
|
|
16
|
-
const options = useMemo(() => optionsProp === null || optionsProp === void 0 ? void 0 : optionsProp.sort((a, b) => a - b).map((value,
|
|
17
|
-
label: String(optionsRender ? optionsRender(value, idx) : value),
|
|
18
|
-
value: String(value),
|
|
19
|
-
})), [optionsProp, optionsRender]);
|
|
16
|
+
const options = useMemo(() => optionsProp === null || optionsProp === void 0 ? void 0 : optionsProp.sort((a, b) => a - b).map(value => ({ label: String(value), value: String(value) })), [optionsProp]);
|
|
20
17
|
const tablePaginationState = table.getState().pagination;
|
|
21
18
|
if (table.getPageCount() <= 1 && !options) {
|
|
22
19
|
return null;
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
6
|
"title": "Table",
|
|
7
|
-
"version": "0.19.6
|
|
7
|
+
"version": "0.19.6",
|
|
8
8
|
"sideEffects": [
|
|
9
9
|
"*.css",
|
|
10
10
|
"*.woff",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"@snack-uikit/scroll": "0.6.0",
|
|
43
43
|
"@snack-uikit/skeleton": "0.3.4",
|
|
44
44
|
"@snack-uikit/toggles": "0.10.0",
|
|
45
|
-
"@snack-uikit/toolbar": "0.7.
|
|
45
|
+
"@snack-uikit/toolbar": "0.7.46",
|
|
46
46
|
"@snack-uikit/truncate-string": "0.4.19",
|
|
47
47
|
"@snack-uikit/typography": "0.6.2",
|
|
48
48
|
"@snack-uikit/utils": "3.3.0",
|
|
@@ -57,5 +57,5 @@
|
|
|
57
57
|
"peerDependencies": {
|
|
58
58
|
"@snack-uikit/locale": "*"
|
|
59
59
|
},
|
|
60
|
-
"gitHead": "
|
|
60
|
+
"gitHead": "680e16bb363296e1b4a0a35ce8efd2b4f23c4ee2"
|
|
61
61
|
}
|
|
@@ -51,7 +51,6 @@ export function Table<TData extends object>({
|
|
|
51
51
|
},
|
|
52
52
|
columnDefinitions,
|
|
53
53
|
keepPinnedRows = false,
|
|
54
|
-
copyPinnedRows = false,
|
|
55
54
|
enableSelectPinned = false,
|
|
56
55
|
rowSelection: rowSelectionProp,
|
|
57
56
|
search,
|
|
@@ -67,7 +66,7 @@ export function Table<TData extends object>({
|
|
|
67
66
|
loading = false,
|
|
68
67
|
outline = false,
|
|
69
68
|
moreActions,
|
|
70
|
-
|
|
69
|
+
exportFileName,
|
|
71
70
|
dataFiltered,
|
|
72
71
|
dataError,
|
|
73
72
|
noDataState,
|
|
@@ -80,7 +79,6 @@ export function Table<TData extends object>({
|
|
|
80
79
|
manualSorting = false,
|
|
81
80
|
manualPagination = false,
|
|
82
81
|
manualFiltering = false,
|
|
83
|
-
autoResetPageIndex = false,
|
|
84
82
|
scrollRef,
|
|
85
83
|
scrollContainerRef,
|
|
86
84
|
getRowId,
|
|
@@ -166,18 +164,14 @@ export function Table<TData extends object>({
|
|
|
166
164
|
onSortingChange,
|
|
167
165
|
getSortedRowModel: getSortedRowModel(),
|
|
168
166
|
onPaginationChange,
|
|
169
|
-
autoResetPageIndex,
|
|
167
|
+
autoResetPageIndex: false,
|
|
170
168
|
getPaginationRowModel: getPaginationRowModel(),
|
|
171
169
|
getCoreRowModel: getCoreRowModel(),
|
|
172
170
|
columnResizeMode: 'onEnd',
|
|
173
171
|
keepPinnedRows,
|
|
174
172
|
});
|
|
175
173
|
|
|
176
|
-
const { loadingTable } = useLoadingTable({
|
|
177
|
-
pageSize: Math.min(Math.max(pageSize, 5), DEFAULT_PAGE_SIZE),
|
|
178
|
-
columnDefinitions: tableColumns,
|
|
179
|
-
columnPinning,
|
|
180
|
-
});
|
|
174
|
+
const { loadingTable } = useLoadingTable({ pageSize, columnDefinitions: tableColumns, columnPinning });
|
|
181
175
|
|
|
182
176
|
const handleOnRefresh = useCallback(() => {
|
|
183
177
|
table.resetRowSelection();
|
|
@@ -195,25 +189,16 @@ export function Table<TData extends object>({
|
|
|
195
189
|
}, [loading, onDelete, table]);
|
|
196
190
|
|
|
197
191
|
const handleOnCheck = useCallback(() => {
|
|
198
|
-
if (!loading &&
|
|
199
|
-
|
|
200
|
-
const isSomeRowsSelected = table.getIsSomePageRowsSelected();
|
|
201
|
-
const isAllCenterRowsSelected = centerRows.every(row => row.getIsSelected());
|
|
202
|
-
|
|
203
|
-
if (isAllCenterRowsSelected) {
|
|
204
|
-
table.resetRowSelection();
|
|
205
|
-
return;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
centerRows.forEach(row => row.toggleSelected(isSomeRowsSelected ? true : undefined));
|
|
192
|
+
if (!loading && rowSelectionProp?.multiRow) {
|
|
193
|
+
table.toggleAllPageRowsSelected();
|
|
209
194
|
return;
|
|
210
195
|
}
|
|
211
196
|
|
|
212
|
-
if (!loading &&
|
|
213
|
-
table.
|
|
197
|
+
if (!loading && table.getIsSomePageRowsSelected()) {
|
|
198
|
+
table.resetRowSelection();
|
|
214
199
|
return;
|
|
215
200
|
}
|
|
216
|
-
}, [loading, rowSelectionProp?.multiRow, table
|
|
201
|
+
}, [loading, rowSelectionProp?.multiRow, table]);
|
|
217
202
|
|
|
218
203
|
const columnSizeVarsRef = useRef<Record<string, string>>();
|
|
219
204
|
const headers = table.getFlatHeaders();
|
|
@@ -277,23 +262,21 @@ export function Table<TData extends object>({
|
|
|
277
262
|
const filteredTopRows = table.getState().globalFilter
|
|
278
263
|
? topRows.filter(tr => tableFilteredRowsIds.includes(tr.id))
|
|
279
264
|
: topRows;
|
|
280
|
-
const centerRows = copyPinnedRows ? tableRows : tableCenterRows;
|
|
281
265
|
|
|
282
266
|
const { t } = useLocale('Table');
|
|
283
267
|
const emptyStates = useEmptyState({ noDataState, noResultsState, errorDataState });
|
|
284
268
|
|
|
285
269
|
const cssPageSize = useMemo(() => {
|
|
286
|
-
const tempPageSize =
|
|
270
|
+
const tempPageSize = !suppressPagination ? tablePagination?.pageSize : pageSize;
|
|
287
271
|
|
|
288
272
|
return !tableRows.length ? Math.min(Math.max(tempPageSize, 5), DEFAULT_PAGE_SIZE) : tempPageSize;
|
|
289
|
-
}, [
|
|
273
|
+
}, [pageSize, suppressPagination, tablePagination?.pageSize, tableRows.length]);
|
|
290
274
|
|
|
291
275
|
usePageReset({
|
|
292
276
|
manualPagination,
|
|
293
277
|
maximumAvailablePage: pageCount || data.length / pagination.pageSize,
|
|
294
278
|
pagination,
|
|
295
279
|
onPaginationChange,
|
|
296
|
-
autoResetPageIndex,
|
|
297
280
|
});
|
|
298
281
|
|
|
299
282
|
return (
|
|
@@ -324,17 +307,11 @@ export function Table<TData extends object>({
|
|
|
324
307
|
selectionMode={rowSelectionProp?.multiRow ? 'multiple' : 'single'}
|
|
325
308
|
before={toolbarBefore}
|
|
326
309
|
after={
|
|
327
|
-
toolbarAfter ||
|
|
310
|
+
toolbarAfter || exportFileName ? (
|
|
328
311
|
<>
|
|
329
312
|
{toolbarAfter}
|
|
330
|
-
{
|
|
331
|
-
<ExportButton
|
|
332
|
-
settings={exportSettings}
|
|
333
|
-
columnDefinitions={columnDefinitions}
|
|
334
|
-
data={data}
|
|
335
|
-
topRows={filteredTopRows}
|
|
336
|
-
centerRows={centerRows}
|
|
337
|
-
/>
|
|
313
|
+
{exportFileName && (
|
|
314
|
+
<ExportButton fileName={exportFileName} columnDefinitions={columnDefinitions} data={data} />
|
|
338
315
|
)}
|
|
339
316
|
</>
|
|
340
317
|
) : undefined
|
|
@@ -359,7 +336,7 @@ export function Table<TData extends object>({
|
|
|
359
336
|
</SkeletonContextProvider>
|
|
360
337
|
) : (
|
|
361
338
|
<>
|
|
362
|
-
{
|
|
339
|
+
{tableCenterRows.length || filteredTopRows.length ? <HeaderRow /> : null}
|
|
363
340
|
{filteredTopRows.length ? (
|
|
364
341
|
<div className={styles.topRowWrapper}>
|
|
365
342
|
{filteredTopRows.map(row => (
|
|
@@ -368,7 +345,7 @@ export function Table<TData extends object>({
|
|
|
368
345
|
</div>
|
|
369
346
|
) : null}
|
|
370
347
|
|
|
371
|
-
{
|
|
348
|
+
{tableCenterRows.map(row => (
|
|
372
349
|
<BodyRow key={row.id} row={row} onRowClick={onRowClick} />
|
|
373
350
|
))}
|
|
374
351
|
|
|
@@ -376,7 +353,7 @@ export function Table<TData extends object>({
|
|
|
376
353
|
emptyStates={emptyStates}
|
|
377
354
|
dataError={dataError}
|
|
378
355
|
dataFiltered={dataFiltered || Boolean(table.getState().globalFilter)}
|
|
379
|
-
tableRowsLength={tableRows.length
|
|
356
|
+
tableRowsLength={tableRows.length}
|
|
380
357
|
/>
|
|
381
358
|
</>
|
|
382
359
|
)}
|
|
@@ -392,7 +369,6 @@ export function Table<TData extends object>({
|
|
|
392
369
|
options={paginationProp?.options}
|
|
393
370
|
optionsLabel={paginationProp?.optionsLabel}
|
|
394
371
|
pageCount={pageCount}
|
|
395
|
-
optionsRender={paginationProp?.optionsRender}
|
|
396
372
|
/>
|
|
397
373
|
)}
|
|
398
374
|
</div>
|
|
@@ -6,7 +6,6 @@ type UsePageResetProps = {
|
|
|
6
6
|
maximumAvailablePage: number;
|
|
7
7
|
pagination: PaginationState;
|
|
8
8
|
onPaginationChange(state: PaginationState): void;
|
|
9
|
-
autoResetPageIndex: boolean;
|
|
10
9
|
};
|
|
11
10
|
|
|
12
11
|
export function usePageReset({
|
|
@@ -14,15 +13,12 @@ export function usePageReset({
|
|
|
14
13
|
pagination,
|
|
15
14
|
maximumAvailablePage,
|
|
16
15
|
onPaginationChange,
|
|
17
|
-
autoResetPageIndex,
|
|
18
16
|
}: UsePageResetProps) {
|
|
19
17
|
useEffect(() => {
|
|
20
|
-
if (autoResetPageIndex) return;
|
|
21
|
-
|
|
22
18
|
const { pageIndex } = pagination;
|
|
23
19
|
|
|
24
20
|
if (!manualPagination && pageIndex > 0 && pageIndex >= maximumAvailablePage) {
|
|
25
21
|
onPaginationChange({ ...pagination, pageIndex: 0 });
|
|
26
22
|
}
|
|
27
|
-
}, [maximumAvailablePage, manualPagination, onPaginationChange, pagination
|
|
23
|
+
}, [maximumAvailablePage, manualPagination, onPaginationChange, pagination]);
|
|
28
24
|
}
|
package/src/components/types.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { ReactNode, RefObject } from 'react';
|
|
|
11
11
|
import { ToolbarProps } from '@snack-uikit/toolbar';
|
|
12
12
|
import { WithSupportProps } from '@snack-uikit/utils';
|
|
13
13
|
|
|
14
|
-
import { EmptyStateProps,
|
|
14
|
+
import { EmptyStateProps, RowClickHandler } from '../helperComponents';
|
|
15
15
|
import { ColumnDefinition } from '../types';
|
|
16
16
|
|
|
17
17
|
export type TableProps<TData extends object> = WithSupportProps<{
|
|
@@ -19,11 +19,9 @@ export type TableProps<TData extends object> = WithSupportProps<{
|
|
|
19
19
|
data: TData[];
|
|
20
20
|
/** Определение внешнего вида и функционала колонок */
|
|
21
21
|
columnDefinitions: ColumnDefinition<TData>[];
|
|
22
|
-
/** Параметр
|
|
22
|
+
/** Параметр овтечает за сохранение закрепленных строк на всех страницах таблицы */
|
|
23
23
|
keepPinnedRows?: boolean;
|
|
24
|
-
/** Параметр
|
|
25
|
-
copyPinnedRows?: boolean;
|
|
26
|
-
/** Параметр отвечает за чекбокс выбора закрепленных строк */
|
|
24
|
+
/** Параметр овтечает за чекбокс выбора закрепленных строк */
|
|
27
25
|
enableSelectPinned?: boolean;
|
|
28
26
|
/** Параметры отвечают за возможность сортировки, их стоит использовать если нужно отслеживать состояние <br>
|
|
29
27
|
* <strong>initialState</strong>: Начальное состояние сортировки <br>
|
|
@@ -81,14 +79,8 @@ export type TableProps<TData extends object> = WithSupportProps<{
|
|
|
81
79
|
options?: number[];
|
|
82
80
|
optionsLabel?: string;
|
|
83
81
|
onChange?(state: PaginationState): void;
|
|
84
|
-
optionsRender?(value: string | number, idx: number): string | number;
|
|
85
82
|
};
|
|
86
83
|
|
|
87
|
-
/** Автоматический сброс пагинации к первой странице при изменении данных или состояния
|
|
88
|
-
* (e.g фильтры, сортировки, и т.д)
|
|
89
|
-
* */
|
|
90
|
-
autoResetPageIndex?: boolean;
|
|
91
|
-
|
|
92
84
|
/** Кол-во страниц (используется для внешнего управления) */
|
|
93
85
|
pageCount?: number;
|
|
94
86
|
|
|
@@ -115,8 +107,8 @@ export type TableProps<TData extends object> = WithSupportProps<{
|
|
|
115
107
|
dataFiltered?: boolean;
|
|
116
108
|
dataError?: boolean;
|
|
117
109
|
|
|
118
|
-
/**
|
|
119
|
-
|
|
110
|
+
/** Название файла при экспорте CSV/XLSX */
|
|
111
|
+
exportFileName?: string;
|
|
120
112
|
|
|
121
113
|
/** Элементы выпадающего списка кнопки с действиями */
|
|
122
114
|
moreActions?: ToolbarProps['moreActions'];
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { useMemo, useState } from 'react';
|
|
1
|
+
import { useState } from 'react';
|
|
3
2
|
|
|
4
3
|
import { ButtonFunction } from '@snack-uikit/button';
|
|
5
4
|
import { DownloadSVG } from '@snack-uikit/icons';
|
|
@@ -9,55 +8,19 @@ import { useLocale } from '@snack-uikit/locale';
|
|
|
9
8
|
import { exportToCSV, exportToXLSX } from '../../exportTable';
|
|
10
9
|
import { ColumnDefinition } from '../../types';
|
|
11
10
|
|
|
12
|
-
type
|
|
13
|
-
csv?: boolean;
|
|
14
|
-
xslx?: boolean;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
export type ExportButtonProps<TData extends object> = {
|
|
11
|
+
type ExportButtonProps<TData extends object> = {
|
|
18
12
|
/** Данные для отрисовки */
|
|
19
13
|
data: TData[];
|
|
20
14
|
/** Определение внешнего вида и функционала колонок */
|
|
21
15
|
columnDefinitions: ColumnDefinition<TData>[];
|
|
22
16
|
|
|
23
|
-
|
|
24
|
-
/** Название файла при экспорте */
|
|
25
|
-
fileName: string;
|
|
26
|
-
|
|
27
|
-
/** Доступные форматы экспорта */
|
|
28
|
-
format?: Format;
|
|
29
|
-
|
|
30
|
-
/** Настройка фильтрации данных */
|
|
31
|
-
filterData?: boolean;
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
topRows: Row<TData>[];
|
|
35
|
-
centerRows: Row<TData>[];
|
|
17
|
+
fileName?: string;
|
|
36
18
|
};
|
|
37
19
|
|
|
38
|
-
export function ExportButton<TData extends object>({
|
|
39
|
-
settings,
|
|
40
|
-
data,
|
|
41
|
-
columnDefinitions,
|
|
42
|
-
topRows,
|
|
43
|
-
centerRows,
|
|
44
|
-
}: ExportButtonProps<TData>) {
|
|
20
|
+
export function ExportButton<TData extends object>({ fileName, data, columnDefinitions }: ExportButtonProps<TData>) {
|
|
45
21
|
const [isOpen, setIsOpen] = useState<boolean>(false);
|
|
46
22
|
const { t } = useLocale('Table');
|
|
47
23
|
|
|
48
|
-
const { fileName, filterData = true } = settings;
|
|
49
|
-
const format: Format = Object.assign({ csv: true, xslx: true }, settings.format);
|
|
50
|
-
|
|
51
|
-
const filteredData = useMemo(() => {
|
|
52
|
-
let newData = data;
|
|
53
|
-
|
|
54
|
-
if (filterData) {
|
|
55
|
-
newData = [...topRows, ...centerRows].map(row => row.original);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return newData;
|
|
59
|
-
}, [centerRows, data, filterData, topRows]);
|
|
60
|
-
|
|
61
24
|
return (
|
|
62
25
|
<Droplist
|
|
63
26
|
trigger='clickAndFocusVisible'
|
|
@@ -69,18 +32,16 @@ export function ExportButton<TData extends object>({
|
|
|
69
32
|
{
|
|
70
33
|
content: { option: t('export') + 'CSV' },
|
|
71
34
|
onClick: () => {
|
|
72
|
-
exportToCSV<TData>({ fileName, columnDefinitions, data
|
|
35
|
+
exportToCSV<TData>({ fileName, columnDefinitions, data });
|
|
73
36
|
setIsOpen(false);
|
|
74
37
|
},
|
|
75
|
-
hidden: !format.csv,
|
|
76
38
|
},
|
|
77
39
|
{
|
|
78
40
|
content: { option: t('export') + 'XLSX' },
|
|
79
41
|
onClick: () => {
|
|
80
|
-
exportToXLSX<TData>({ fileName, columnDefinitions, data
|
|
42
|
+
exportToXLSX<TData>({ fileName, columnDefinitions, data });
|
|
81
43
|
setIsOpen(false);
|
|
82
44
|
},
|
|
83
|
-
hidden: !format.xslx,
|
|
84
45
|
},
|
|
85
46
|
]}
|
|
86
47
|
>
|
|
@@ -11,7 +11,6 @@ export type TablePaginationProps<TData> = {
|
|
|
11
11
|
table: Table<TData>;
|
|
12
12
|
options?: number[];
|
|
13
13
|
optionsLabel?: string;
|
|
14
|
-
optionsRender?(value: number, idx: number): string | number;
|
|
15
14
|
pageCount?: number;
|
|
16
15
|
};
|
|
17
16
|
|
|
@@ -19,7 +18,6 @@ export function TablePagination<TData>({
|
|
|
19
18
|
table,
|
|
20
19
|
options: optionsProp,
|
|
21
20
|
optionsLabel: optionsLabelProp,
|
|
22
|
-
optionsRender,
|
|
23
21
|
}: TablePaginationProps<TData>) {
|
|
24
22
|
const { t } = useLocale('Table');
|
|
25
23
|
const optionsLabel = optionsLabelProp ?? t('rowsOptionsLabel');
|
|
@@ -39,14 +37,8 @@ export function TablePagination<TData>({
|
|
|
39
37
|
);
|
|
40
38
|
|
|
41
39
|
const options = useMemo(
|
|
42
|
-
() =>
|
|
43
|
-
|
|
44
|
-
?.sort((a, b) => a - b)
|
|
45
|
-
.map((value, idx) => ({
|
|
46
|
-
label: String(optionsRender ? optionsRender(value, idx) : value),
|
|
47
|
-
value: String(value),
|
|
48
|
-
})),
|
|
49
|
-
[optionsProp, optionsRender],
|
|
40
|
+
() => optionsProp?.sort((a, b) => a - b).map(value => ({ label: String(value), value: String(value) })),
|
|
41
|
+
[optionsProp],
|
|
50
42
|
);
|
|
51
43
|
|
|
52
44
|
const tablePaginationState = table.getState().pagination;
|