@snack-uikit/table 0.36.23 → 0.36.24
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 +11 -0
- package/README.md +1 -1
- package/dist/cjs/components/ServerTable/ServerTable.d.ts +12 -1
- package/dist/cjs/components/Table/Table.d.ts +12 -1
- package/dist/cjs/components/Table/Table.js +1 -1
- package/dist/cjs/components/Table/utils/getTableColumnsDefinitions.js +3 -1
- package/dist/cjs/helperComponents/Cells/StatusCell/constants.d.ts +12 -1
- package/dist/cjs/helperComponents/Cells/TreeCell/TreeCell.d.ts +7 -3
- package/dist/cjs/helperComponents/Cells/TreeCell/TreeCell.js +134 -129
- package/dist/cjs/helperComponents/Cells/TreeCell/styles.module.css +1 -0
- package/dist/esm/components/ServerTable/ServerTable.d.ts +12 -1
- package/dist/esm/components/Table/Table.d.ts +12 -1
- package/dist/esm/components/Table/Table.js +1 -1
- package/dist/esm/components/Table/utils/getTableColumnsDefinitions.js +1 -1
- package/dist/esm/helperComponents/Cells/StatusCell/constants.d.ts +12 -1
- package/dist/esm/helperComponents/Cells/TreeCell/TreeCell.d.ts +7 -3
- package/dist/esm/helperComponents/Cells/TreeCell/TreeCell.js +75 -71
- package/dist/esm/helperComponents/Cells/TreeCell/styles.module.css +1 -0
- package/package.json +2 -2
- package/src/components/Table/Table.tsx +1 -1
- package/src/components/Table/utils/getTableColumnsDefinitions.ts +1 -1
- package/src/helperComponents/Cells/StatusCell/constants.ts +1 -1
- package/src/helperComponents/Cells/TreeCell/TreeCell.tsx +170 -158
- package/src/helperComponents/Cells/TreeCell/styles.module.scss +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
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.36.24 (2025-07-24)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* **FF-6453:** cell render for TreeCell, fix click on tree cell when selection is disabled ([d26c1ba](https://github.com/cloud-ru-tech/snack-uikit/commit/d26c1ba66819c80fd545539fc63e2a46477a0c0f))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
## 0.36.23 (2025-07-23)
|
|
7
18
|
|
|
8
19
|
### Only dependencies have been changed
|
package/README.md
CHANGED
|
@@ -179,6 +179,7 @@ const columnDefinitions: ColumnDefinition<TableData>[] = [
|
|
|
179
179
|
|------|------|---------------|-------------|
|
|
180
180
|
| onChangePage* | `(offset: number, limit: number) => void` | - | |
|
|
181
181
|
| columnDefinitions* | `ColumnDefinition<TData>[]` | - | Определение внешнего вида и функционала колонок |
|
|
182
|
+
| loading | `boolean` | - | Состояние загрузки |
|
|
182
183
|
| className | `string` | - | CSS-класс |
|
|
183
184
|
| onRefresh | `() => void` | - | Колбек обновления данных |
|
|
184
185
|
| moreActions | `Action[]` | - | Элементы выпадающего списка кнопки с действиями |
|
|
@@ -193,7 +194,6 @@ const columnDefinitions: ColumnDefinition<TableData>[] = [
|
|
|
193
194
|
| enableFuzzySearch | `boolean` | - | Включить нечеткий поиск |
|
|
194
195
|
| rowAutoHeight | `boolean` | - | |
|
|
195
196
|
| onRowClick | `RowClickHandler<TData>` | - | Колбэк клика по строке |
|
|
196
|
-
| loading | `boolean` | - | Состояние загрузки |
|
|
197
197
|
| outline | `boolean` | - | Внешний бордер для тулбара и таблицы |
|
|
198
198
|
| columnFilters | `Omit<ChipChoiceRowProps<TFilters>, "size" \| "data-test-id"> & { open?: boolean; onOpenChange?(isOpen: boolean): void; } & { initialOpen?: boolean; }` | - | Фильтры |
|
|
199
199
|
| dataFiltered | `boolean` | - | Флаг, показывающий что данные были отфильтрованы при пустых данных |
|
|
@@ -3,6 +3,17 @@ import { ServerTableProps } from '../types';
|
|
|
3
3
|
export declare function ServerTable<TData extends object, TFilters extends FiltersState = Record<string, unknown>>({ items, total, limit, offset, onChangePage, search: searchProp, pagination, columnFilters, manualSorting, manualPagination, manualFiltering, ...rest }: ServerTableProps<TData, TFilters>): import("react/jsx-runtime").JSX.Element;
|
|
4
4
|
export declare namespace ServerTable {
|
|
5
5
|
var getRowActionsColumnDef: typeof import("../../helperComponents").getRowActionsColumnDef;
|
|
6
|
-
var statusAppearances:
|
|
6
|
+
var statusAppearances: {
|
|
7
|
+
readonly Primary: "primary";
|
|
8
|
+
readonly Neutral: "neutral";
|
|
9
|
+
readonly Red: "red";
|
|
10
|
+
readonly Orange: "orange";
|
|
11
|
+
readonly Yellow: "yellow";
|
|
12
|
+
readonly Green: "green";
|
|
13
|
+
readonly Blue: "blue";
|
|
14
|
+
readonly Violet: "violet";
|
|
15
|
+
readonly Pink: "pink";
|
|
16
|
+
readonly Loading: "loading";
|
|
17
|
+
};
|
|
7
18
|
var getStatusColumnDef: typeof import("../../helperComponents").getStatusColumnDef;
|
|
8
19
|
}
|
|
@@ -4,6 +4,17 @@ import { TableProps } from '../types';
|
|
|
4
4
|
export declare function Table<TData extends object, TFilters extends FiltersState = Record<string, unknown>>({ data, rowPinning, columnDefinitions, keepPinnedRows, copyPinnedRows, enableSelectPinned, rowSelection: rowSelectionProp, search, sorting: sortingProp, columnFilters, pagination: paginationProp, className, onRowClick, onRefresh, pageSize, pageCount, loading, infiniteLoading, outline, moreActions, exportSettings, dataFiltered, dataError, noDataState, noResultsState, errorDataState, suppressToolbar, suppressSearch, toolbarAfter, suppressPagination, manualSorting, manualPagination: manualPaginationProp, manualFiltering, autoResetPageIndex, scrollRef, scrollContainerRef, getRowId, enableFuzzySearch, savedState, expanding, bulkActions: bulkActionsProp, rowAutoHeight, columnsSettings: columnsSettingsProp, ...rest }: TableProps<TData, TFilters>): import("react/jsx-runtime").JSX.Element;
|
|
5
5
|
export declare namespace Table {
|
|
6
6
|
var getStatusColumnDef: typeof import("../../helperComponents").getStatusColumnDef;
|
|
7
|
-
var statusAppearances:
|
|
7
|
+
var statusAppearances: {
|
|
8
|
+
readonly Primary: "primary";
|
|
9
|
+
readonly Neutral: "neutral";
|
|
10
|
+
readonly Red: "red";
|
|
11
|
+
readonly Orange: "orange";
|
|
12
|
+
readonly Yellow: "yellow";
|
|
13
|
+
readonly Green: "green";
|
|
14
|
+
readonly Blue: "blue";
|
|
15
|
+
readonly Violet: "violet";
|
|
16
|
+
readonly Pink: "pink";
|
|
17
|
+
readonly Loading: "loading";
|
|
18
|
+
};
|
|
8
19
|
var getRowActionsColumnDef: typeof import("../../helperComponents").getRowActionsColumnDef;
|
|
9
20
|
}
|
|
@@ -227,7 +227,7 @@ function Table(_a) {
|
|
|
227
227
|
onRowSelectionChange,
|
|
228
228
|
enableGrouping: true,
|
|
229
229
|
enableRowSelection,
|
|
230
|
-
enableMultiRowSelection: rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.multiRow,
|
|
230
|
+
enableMultiRowSelection: (rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.enable) && (rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.multiRow),
|
|
231
231
|
enableFilters: true,
|
|
232
232
|
getSubRows: expanding === null || expanding === void 0 ? void 0 : expanding.getSubRows,
|
|
233
233
|
filterFromLeafRows: Boolean(expanding),
|
|
@@ -17,7 +17,9 @@ function getTableColumnsDefinitions(_ref) {
|
|
|
17
17
|
cols = [(0, helperComponents_1.getSelectionCellColumnDef)(enableSelectPinned), ...cols];
|
|
18
18
|
}
|
|
19
19
|
if (expanding) {
|
|
20
|
-
cols = [(0, helperComponents_1.getTreeColumnDef)(expanding.expandingColumnDefinition),
|
|
20
|
+
cols = [(0, helperComponents_1.getTreeColumnDef)(Object.assign(Object.assign({}, expanding.expandingColumnDefinition), {
|
|
21
|
+
enableSelection
|
|
22
|
+
})), ...cols];
|
|
21
23
|
}
|
|
22
24
|
return cols;
|
|
23
25
|
}
|
|
@@ -1,2 +1,13 @@
|
|
|
1
|
-
export declare const STATUS_APPEARANCE:
|
|
1
|
+
export declare const STATUS_APPEARANCE: {
|
|
2
|
+
readonly Primary: "primary";
|
|
3
|
+
readonly Neutral: "neutral";
|
|
4
|
+
readonly Red: "red";
|
|
5
|
+
readonly Orange: "orange";
|
|
6
|
+
readonly Yellow: "yellow";
|
|
7
|
+
readonly Green: "green";
|
|
8
|
+
readonly Blue: "blue";
|
|
9
|
+
readonly Violet: "violet";
|
|
10
|
+
readonly Pink: "pink";
|
|
11
|
+
readonly Loading: "loading";
|
|
12
|
+
};
|
|
2
13
|
export declare const MIN_STATUS_CELL_SIZE = 16;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CellContext } from '@tanstack/react-table';
|
|
1
2
|
import { ReactNode } from 'react';
|
|
2
3
|
import { ColumnDefinition } from '../../../types';
|
|
3
4
|
type BaseTreeColumnDef = {
|
|
@@ -14,15 +15,18 @@ type BaseTreeColumnDef = {
|
|
|
14
15
|
};
|
|
15
16
|
type TreeColumnDef = BaseTreeColumnDef & {
|
|
16
17
|
header?: never;
|
|
17
|
-
|
|
18
|
+
cell?: never;
|
|
18
19
|
};
|
|
19
20
|
type TreeColumnDefWithDescription<TData> = BaseTreeColumnDef & {
|
|
20
21
|
/** Заголовок колонки */
|
|
21
|
-
|
|
22
|
+
cell?(ctx: CellContext<TData, unknown>): ReactNode;
|
|
22
23
|
/** Рендер функция заголовка колонки */
|
|
23
24
|
header?: ColumnDefinition<TData>['header'];
|
|
24
25
|
};
|
|
25
26
|
export type TreeColumnDefinitionProps<TData> = TreeColumnDef | TreeColumnDefWithDescription<TData>;
|
|
27
|
+
type TreeColDefProps<TData> = TreeColumnDefinitionProps<TData> & {
|
|
28
|
+
enableSelection?: boolean;
|
|
29
|
+
};
|
|
26
30
|
/** Вспомогательная функция для создания ячейки со статусом */
|
|
27
|
-
export declare function getTreeColumnDef<TData>({ showToggle, icon, expandedIcon, collapsedIcon, header, accessorKey, }:
|
|
31
|
+
export declare function getTreeColumnDef<TData>({ showToggle, icon, expandedIcon, collapsedIcon, header, accessorKey, cell: renderCell, enableSelection, }: TreeColDefProps<TData>): ColumnDefinition<TData>;
|
|
28
32
|
export {};
|
|
@@ -34,80 +34,69 @@ function getTreeColumnDef(_ref) {
|
|
|
34
34
|
size: 24
|
|
35
35
|
}),
|
|
36
36
|
header,
|
|
37
|
-
accessorKey
|
|
38
|
-
} = _ref;
|
|
39
|
-
return {
|
|
40
|
-
id: constants_2.TREE_CELL_ID,
|
|
41
|
-
pinned: constants_1.COLUMN_PIN_POSITION.Left,
|
|
42
37
|
accessorKey,
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
38
|
+
cell: renderCell,
|
|
39
|
+
enableSelection
|
|
40
|
+
} = _ref;
|
|
41
|
+
const cell = function TreeCell(ctx) {
|
|
42
|
+
var _a;
|
|
43
|
+
const {
|
|
44
|
+
row,
|
|
45
|
+
cell
|
|
46
|
+
} = ctx;
|
|
47
|
+
const isExpanded = row.getIsExpanded();
|
|
48
|
+
const isExpandable = row.getCanExpand();
|
|
49
|
+
const isMultiSelect = row.getCanMultiSelect();
|
|
50
|
+
const parent = row.getParentRow();
|
|
51
|
+
const isRowsSelectionEnabled = row.getCanSelect();
|
|
52
|
+
const isAllSubRowsSelected = row.getIsAllSubRowsSelected();
|
|
53
|
+
const isSomeSubRowSelected = row.getIsSomeSelected();
|
|
54
|
+
const isRowSelected = row.getIsSelected();
|
|
55
|
+
const isLastChildRow = ((_a = parent === null || parent === void 0 ? void 0 : parent.subRows.at(-1)) === null || _a === void 0 ? void 0 : _a.id) === row.id;
|
|
56
|
+
const depth = row.depth;
|
|
57
|
+
const {
|
|
58
|
+
ref
|
|
59
|
+
} = (0, contexts_1.useCellResize)(constants_2.TREE_CELL_ID, cell);
|
|
60
|
+
const linesVisibilityByIndex = (0, react_1.useMemo)(() => {
|
|
58
61
|
var _a;
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const isAllSubRowsSelected = row.getIsAllSubRowsSelected();
|
|
65
|
-
const isSomeSubRowSelected = row.getIsSomeSelected();
|
|
66
|
-
const isRowSelected = row.getIsSelected();
|
|
67
|
-
const isLastChildRow = ((_a = parent === null || parent === void 0 ? void 0 : parent.subRows.at(-1)) === null || _a === void 0 ? void 0 : _a.id) === row.id;
|
|
68
|
-
const depth = row.depth;
|
|
69
|
-
const {
|
|
70
|
-
ref
|
|
71
|
-
} = (0, contexts_1.useCellResize)(constants_2.TREE_CELL_ID, cell);
|
|
72
|
-
const linesVisibilityByIndex = (0, react_1.useMemo)(() => {
|
|
62
|
+
const parents = [];
|
|
63
|
+
for (let i = depth; i >= 0; i--) {
|
|
64
|
+
parents[i] = i === depth ? row : (_a = parents.at(i + 1)) === null || _a === void 0 ? void 0 : _a.getParentRow();
|
|
65
|
+
}
|
|
66
|
+
return parents.map((parent, index) => {
|
|
73
67
|
var _a;
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
68
|
+
if (!parent || parents.length === index + 1) return true;
|
|
69
|
+
const child = parents[index + 1];
|
|
70
|
+
return (child === null || child === void 0 ? void 0 : child.id) !== ((_a = parent.subRows.at(-1)) === null || _a === void 0 ? void 0 : _a.id) || (row === null || row === void 0 ? void 0 : row.id) === (child === null || child === void 0 ? void 0 : child.id);
|
|
71
|
+
});
|
|
72
|
+
}, [row, depth]);
|
|
73
|
+
const lines = (0, react_1.useMemo)(() => Array.from({
|
|
74
|
+
length: depth
|
|
75
|
+
}, (_, index) => (0, jsx_runtime_1.jsx)(TreeLine_1.TreeLine, {
|
|
76
|
+
visible: linesVisibilityByIndex.at(index),
|
|
77
|
+
className: index !== 0 ? styles_module_scss_1.default.line : styles_module_scss_1.default.firstLine,
|
|
78
|
+
halfHeight: index === depth - 1 && isLastChildRow
|
|
79
|
+
}, index)), [depth, linesVisibilityByIndex, isLastChildRow]);
|
|
80
|
+
(0, react_1.useEffect)(() => {
|
|
81
|
+
if (!isMultiSelect || !isExpandable || !isRowsSelectionEnabled) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (isAllSubRowsSelected && !isRowSelected) {
|
|
85
|
+
row.toggleSelected(true, {
|
|
86
|
+
selectChildren: false
|
|
83
87
|
});
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
if (isAllSubRowsSelected && !isRowSelected) {
|
|
97
|
-
row.toggleSelected(true, {
|
|
98
|
-
selectChildren: false
|
|
99
|
-
});
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
if (isRowSelected && !isAllSubRowsSelected && isSomeSubRowSelected) {
|
|
103
|
-
row.toggleSelected(false, {
|
|
104
|
-
selectChildren: false
|
|
105
|
-
});
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
}, [isAllSubRowsSelected, isSomeSubRowSelected, row, isRowSelected, isMultiSelect, isExpandable, isRowsSelectionEnabled]);
|
|
109
|
-
const toggleClickHandler = (0, react_1.useCallback)(event => {
|
|
110
|
-
event.stopPropagation();
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (isRowSelected && !isAllSubRowsSelected && isSomeSubRowSelected) {
|
|
91
|
+
row.toggleSelected(false, {
|
|
92
|
+
selectChildren: false
|
|
93
|
+
});
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
}, [isAllSubRowsSelected, isSomeSubRowSelected, row, isRowSelected, isMultiSelect, isExpandable, isRowsSelectionEnabled]);
|
|
97
|
+
const toggleClickHandler = (0, react_1.useCallback)(event => {
|
|
98
|
+
event.stopPropagation();
|
|
99
|
+
if (enableSelection) {
|
|
111
100
|
if (isMultiSelect) {
|
|
112
101
|
const shouldToggleOn = !isAllSubRowsSelected && !isRowSelected;
|
|
113
102
|
const selectChildren = isAllSubRowsSelected || isSomeSubRowSelected || shouldToggleOn;
|
|
@@ -119,68 +108,84 @@ function getTreeColumnDef(_ref) {
|
|
|
119
108
|
row.toggleSelected(!isRowSelected, {
|
|
120
109
|
selectChildren: false
|
|
121
110
|
});
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
111
|
+
}
|
|
112
|
+
}, [isMultiSelect, row, isAllSubRowsSelected, isSomeSubRowSelected, isRowSelected]);
|
|
113
|
+
const chevronClickHandler = (0, react_1.useCallback)(event => {
|
|
114
|
+
event.stopPropagation();
|
|
115
|
+
row.toggleExpanded();
|
|
116
|
+
}, [row]);
|
|
117
|
+
const value = typeof cell.row.original === 'object' && Object.hasOwn(cell.row.original, accessorKey) ?
|
|
118
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
119
|
+
// @ts-ignore
|
|
120
|
+
cell.row.original[accessorKey] : cell.getValue();
|
|
121
|
+
return (0, jsx_runtime_1.jsx)("div", {
|
|
122
|
+
role: 'presentation',
|
|
123
|
+
"data-test-id": constants_1.TEST_IDS.tree.node,
|
|
124
|
+
className: styles_module_scss_1.default.treeCellContainer,
|
|
125
|
+
onClick: toggleClickHandler,
|
|
126
|
+
children: (0, jsx_runtime_1.jsxs)("div", {
|
|
127
|
+
className: styles_module_scss_1.default.treeCell,
|
|
128
|
+
ref: ref,
|
|
129
|
+
children: [lines, Boolean(parent) && (0, jsx_runtime_1.jsx)(TreeLine_1.TreeLine, {
|
|
130
|
+
horizontal: true,
|
|
131
|
+
visible: true
|
|
132
|
+
}), isExpandable && (0, jsx_runtime_1.jsx)(button_1.ButtonFunction, {
|
|
133
|
+
size: 'xs',
|
|
134
|
+
"data-test-id": constants_1.TEST_IDS.tree.chevron,
|
|
135
|
+
icon: (0, jsx_runtime_1.jsx)(icons_1.ChevronRightSVG, {}),
|
|
136
|
+
onClick: chevronClickHandler,
|
|
137
|
+
className: styles_module_scss_1.default.cellExpandButton,
|
|
138
|
+
"data-expanded": isExpanded || undefined
|
|
139
|
+
}), (0, jsx_runtime_1.jsxs)("div", {
|
|
140
|
+
className: styles_module_scss_1.default.treeNodeContent,
|
|
141
|
+
"data-disabled": !isRowsSelectionEnabled || undefined,
|
|
142
|
+
"data-selected": isRowSelected || undefined,
|
|
143
|
+
"data-multiselect": isMultiSelect || undefined,
|
|
144
|
+
children: [showToggle && (0, jsx_runtime_1.jsx)("div", {
|
|
145
|
+
tabIndex: -1,
|
|
146
|
+
className: styles_module_scss_1.default.treeCheckboxWrap,
|
|
147
|
+
children: isMultiSelect ? (0, jsx_runtime_1.jsx)(toggles_1.Checkbox, {
|
|
148
|
+
size: 's',
|
|
149
|
+
disabled: !isRowsSelectionEnabled,
|
|
150
|
+
checked: isRowSelected,
|
|
151
|
+
"data-test-id": constants_1.TEST_IDS.tree.checkbox,
|
|
152
|
+
indeterminate: isSomeSubRowSelected && !isAllSubRowsSelected
|
|
153
|
+
}) : (0, jsx_runtime_1.jsx)(toggles_1.Radio, {
|
|
154
|
+
size: 's',
|
|
155
|
+
disabled: !isRowsSelectionEnabled,
|
|
156
|
+
"data-test-id": constants_1.TEST_IDS.tree.radio,
|
|
157
|
+
checked: isRowSelected
|
|
158
|
+
})
|
|
159
|
+
}), (0, jsx_runtime_1.jsxs)("div", {
|
|
160
|
+
role: 'presentation',
|
|
146
161
|
onClick: chevronClickHandler,
|
|
147
|
-
className: styles_module_scss_1.default.
|
|
148
|
-
|
|
162
|
+
className: styles_module_scss_1.default.cellUserToggleIcon,
|
|
163
|
+
children: [isExpandable && isExpanded && expandedIcon, isExpandable && !isExpanded && collapsedIcon]
|
|
149
164
|
}), (0, jsx_runtime_1.jsxs)("div", {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
children: [showToggle && (0, jsx_runtime_1.jsx)("div", {
|
|
155
|
-
tabIndex: -1,
|
|
156
|
-
className: styles_module_scss_1.default.treeCheckboxWrap,
|
|
157
|
-
children: isMultiSelect ? (0, jsx_runtime_1.jsx)(toggles_1.Checkbox, {
|
|
158
|
-
size: 's',
|
|
159
|
-
disabled: !isRowsSelectionEnabled,
|
|
160
|
-
checked: isRowSelected,
|
|
161
|
-
"data-test-id": constants_1.TEST_IDS.tree.checkbox,
|
|
162
|
-
indeterminate: isSomeSubRowSelected && !isAllSubRowsSelected
|
|
163
|
-
}) : (0, jsx_runtime_1.jsx)(toggles_1.Radio, {
|
|
164
|
-
size: 's',
|
|
165
|
-
disabled: !isRowsSelectionEnabled,
|
|
166
|
-
"data-test-id": constants_1.TEST_IDS.tree.radio,
|
|
167
|
-
checked: isRowSelected
|
|
168
|
-
})
|
|
169
|
-
}), (0, jsx_runtime_1.jsxs)("div", {
|
|
170
|
-
role: 'presentation',
|
|
171
|
-
onClick: chevronClickHandler,
|
|
172
|
-
className: styles_module_scss_1.default.cellUserToggleIcon,
|
|
173
|
-
children: [isExpandable && isExpanded && expandedIcon, isExpandable && !isExpanded && collapsedIcon]
|
|
174
|
-
}), (0, jsx_runtime_1.jsxs)("div", {
|
|
175
|
-
role: 'presentation',
|
|
176
|
-
className: styles_module_scss_1.default.userContent,
|
|
177
|
-
children: [!isExpandable && icon, (0, jsx_runtime_1.jsx)(truncate_string_1.TruncateString, {
|
|
178
|
-
text: value
|
|
179
|
-
})]
|
|
165
|
+
role: 'presentation',
|
|
166
|
+
className: styles_module_scss_1.default.userContent,
|
|
167
|
+
children: [!isExpandable && icon, renderCell ? renderCell(ctx) : (0, jsx_runtime_1.jsx)(truncate_string_1.TruncateString, {
|
|
168
|
+
text: value
|
|
180
169
|
})]
|
|
181
170
|
})]
|
|
182
|
-
})
|
|
183
|
-
})
|
|
184
|
-
}
|
|
171
|
+
})]
|
|
172
|
+
})
|
|
173
|
+
});
|
|
174
|
+
};
|
|
175
|
+
return {
|
|
176
|
+
id: constants_2.TREE_CELL_ID,
|
|
177
|
+
pinned: constants_1.COLUMN_PIN_POSITION.Left,
|
|
178
|
+
accessorKey,
|
|
179
|
+
noBodyCellPadding: true,
|
|
180
|
+
noHeaderCellPadding: false,
|
|
181
|
+
enableResizing: true,
|
|
182
|
+
size: 150,
|
|
183
|
+
maxSize: Number.MAX_SAFE_INTEGER,
|
|
184
|
+
meta: {
|
|
185
|
+
skipOnExport: false
|
|
186
|
+
},
|
|
187
|
+
enableSorting: false,
|
|
188
|
+
header,
|
|
189
|
+
cell
|
|
185
190
|
};
|
|
186
191
|
}
|
|
@@ -3,6 +3,17 @@ import { ServerTableProps } from '../types';
|
|
|
3
3
|
export declare function ServerTable<TData extends object, TFilters extends FiltersState = Record<string, unknown>>({ items, total, limit, offset, onChangePage, search: searchProp, pagination, columnFilters, manualSorting, manualPagination, manualFiltering, ...rest }: ServerTableProps<TData, TFilters>): import("react/jsx-runtime").JSX.Element;
|
|
4
4
|
export declare namespace ServerTable {
|
|
5
5
|
var getRowActionsColumnDef: typeof import("../../helperComponents").getRowActionsColumnDef;
|
|
6
|
-
var statusAppearances:
|
|
6
|
+
var statusAppearances: {
|
|
7
|
+
readonly Primary: "primary";
|
|
8
|
+
readonly Neutral: "neutral";
|
|
9
|
+
readonly Red: "red";
|
|
10
|
+
readonly Orange: "orange";
|
|
11
|
+
readonly Yellow: "yellow";
|
|
12
|
+
readonly Green: "green";
|
|
13
|
+
readonly Blue: "blue";
|
|
14
|
+
readonly Violet: "violet";
|
|
15
|
+
readonly Pink: "pink";
|
|
16
|
+
readonly Loading: "loading";
|
|
17
|
+
};
|
|
7
18
|
var getStatusColumnDef: typeof import("../../helperComponents").getStatusColumnDef;
|
|
8
19
|
}
|
|
@@ -4,6 +4,17 @@ import { TableProps } from '../types';
|
|
|
4
4
|
export declare function Table<TData extends object, TFilters extends FiltersState = Record<string, unknown>>({ data, rowPinning, columnDefinitions, keepPinnedRows, copyPinnedRows, enableSelectPinned, rowSelection: rowSelectionProp, search, sorting: sortingProp, columnFilters, pagination: paginationProp, className, onRowClick, onRefresh, pageSize, pageCount, loading, infiniteLoading, outline, moreActions, exportSettings, dataFiltered, dataError, noDataState, noResultsState, errorDataState, suppressToolbar, suppressSearch, toolbarAfter, suppressPagination, manualSorting, manualPagination: manualPaginationProp, manualFiltering, autoResetPageIndex, scrollRef, scrollContainerRef, getRowId, enableFuzzySearch, savedState, expanding, bulkActions: bulkActionsProp, rowAutoHeight, columnsSettings: columnsSettingsProp, ...rest }: TableProps<TData, TFilters>): import("react/jsx-runtime").JSX.Element;
|
|
5
5
|
export declare namespace Table {
|
|
6
6
|
var getStatusColumnDef: typeof import("../../helperComponents").getStatusColumnDef;
|
|
7
|
-
var statusAppearances:
|
|
7
|
+
var statusAppearances: {
|
|
8
|
+
readonly Primary: "primary";
|
|
9
|
+
readonly Neutral: "neutral";
|
|
10
|
+
readonly Red: "red";
|
|
11
|
+
readonly Orange: "orange";
|
|
12
|
+
readonly Yellow: "yellow";
|
|
13
|
+
readonly Green: "green";
|
|
14
|
+
readonly Blue: "blue";
|
|
15
|
+
readonly Violet: "violet";
|
|
16
|
+
readonly Pink: "pink";
|
|
17
|
+
readonly Loading: "loading";
|
|
18
|
+
};
|
|
8
19
|
var getRowActionsColumnDef: typeof import("../../helperComponents").getRowActionsColumnDef;
|
|
9
20
|
}
|
|
@@ -141,7 +141,7 @@ export function Table(_a) {
|
|
|
141
141
|
onRowSelectionChange,
|
|
142
142
|
enableGrouping: true,
|
|
143
143
|
enableRowSelection,
|
|
144
|
-
enableMultiRowSelection: rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.multiRow,
|
|
144
|
+
enableMultiRowSelection: (rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.enable) && (rowSelectionProp === null || rowSelectionProp === void 0 ? void 0 : rowSelectionProp.multiRow),
|
|
145
145
|
enableFilters: true,
|
|
146
146
|
getSubRows: expanding === null || expanding === void 0 ? void 0 : expanding.getSubRows,
|
|
147
147
|
filterFromLeafRows: Boolean(expanding),
|
|
@@ -5,7 +5,7 @@ export function getTableColumnsDefinitions({ columnDefinitions, enableSelection,
|
|
|
5
5
|
cols = [getSelectionCellColumnDef(enableSelectPinned), ...cols];
|
|
6
6
|
}
|
|
7
7
|
if (expanding) {
|
|
8
|
-
cols = [getTreeColumnDef(expanding.expandingColumnDefinition), ...cols];
|
|
8
|
+
cols = [getTreeColumnDef(Object.assign(Object.assign({}, expanding.expandingColumnDefinition), { enableSelection })), ...cols];
|
|
9
9
|
}
|
|
10
10
|
return cols;
|
|
11
11
|
}
|
|
@@ -1,2 +1,13 @@
|
|
|
1
|
-
export declare const STATUS_APPEARANCE:
|
|
1
|
+
export declare const STATUS_APPEARANCE: {
|
|
2
|
+
readonly Primary: "primary";
|
|
3
|
+
readonly Neutral: "neutral";
|
|
4
|
+
readonly Red: "red";
|
|
5
|
+
readonly Orange: "orange";
|
|
6
|
+
readonly Yellow: "yellow";
|
|
7
|
+
readonly Green: "green";
|
|
8
|
+
readonly Blue: "blue";
|
|
9
|
+
readonly Violet: "violet";
|
|
10
|
+
readonly Pink: "pink";
|
|
11
|
+
readonly Loading: "loading";
|
|
12
|
+
};
|
|
2
13
|
export declare const MIN_STATUS_CELL_SIZE = 16;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CellContext } from '@tanstack/react-table';
|
|
1
2
|
import { ReactNode } from 'react';
|
|
2
3
|
import { ColumnDefinition } from '../../../types';
|
|
3
4
|
type BaseTreeColumnDef = {
|
|
@@ -14,15 +15,18 @@ type BaseTreeColumnDef = {
|
|
|
14
15
|
};
|
|
15
16
|
type TreeColumnDef = BaseTreeColumnDef & {
|
|
16
17
|
header?: never;
|
|
17
|
-
|
|
18
|
+
cell?: never;
|
|
18
19
|
};
|
|
19
20
|
type TreeColumnDefWithDescription<TData> = BaseTreeColumnDef & {
|
|
20
21
|
/** Заголовок колонки */
|
|
21
|
-
|
|
22
|
+
cell?(ctx: CellContext<TData, unknown>): ReactNode;
|
|
22
23
|
/** Рендер функция заголовка колонки */
|
|
23
24
|
header?: ColumnDefinition<TData>['header'];
|
|
24
25
|
};
|
|
25
26
|
export type TreeColumnDefinitionProps<TData> = TreeColumnDef | TreeColumnDefWithDescription<TData>;
|
|
27
|
+
type TreeColDefProps<TData> = TreeColumnDefinitionProps<TData> & {
|
|
28
|
+
enableSelection?: boolean;
|
|
29
|
+
};
|
|
26
30
|
/** Вспомогательная функция для создания ячейки со статусом */
|
|
27
|
-
export declare function getTreeColumnDef<TData>({ showToggle, icon, expandedIcon, collapsedIcon, header, accessorKey, }:
|
|
31
|
+
export declare function getTreeColumnDef<TData>({ showToggle, icon, expandedIcon, collapsedIcon, header, accessorKey, cell: renderCell, enableSelection, }: TreeColDefProps<TData>): ColumnDefinition<TData>;
|
|
28
32
|
export {};
|
|
@@ -10,7 +10,80 @@ import { TREE_CELL_ID } from './constants';
|
|
|
10
10
|
import styles from './styles.module.css';
|
|
11
11
|
import { TreeLine } from './TreeLine';
|
|
12
12
|
/** Вспомогательная функция для создания ячейки со статусом */
|
|
13
|
-
export function getTreeColumnDef({ showToggle = false, icon = _jsx(FileSVG, { size: 24 }), expandedIcon = _jsx(FolderOpenSVG, { size: 24 }), collapsedIcon = _jsx(FolderSVG, { size: 24 }), header, accessorKey, }) {
|
|
13
|
+
export function getTreeColumnDef({ showToggle = false, icon = _jsx(FileSVG, { size: 24 }), expandedIcon = _jsx(FolderOpenSVG, { size: 24 }), collapsedIcon = _jsx(FolderSVG, { size: 24 }), header, accessorKey, cell: renderCell, enableSelection, }) {
|
|
14
|
+
const cell = function TreeCell(ctx) {
|
|
15
|
+
var _a;
|
|
16
|
+
const { row, cell } = ctx;
|
|
17
|
+
const isExpanded = row.getIsExpanded();
|
|
18
|
+
const isExpandable = row.getCanExpand();
|
|
19
|
+
const isMultiSelect = row.getCanMultiSelect();
|
|
20
|
+
const parent = row.getParentRow();
|
|
21
|
+
const isRowsSelectionEnabled = row.getCanSelect();
|
|
22
|
+
const isAllSubRowsSelected = row.getIsAllSubRowsSelected();
|
|
23
|
+
const isSomeSubRowSelected = row.getIsSomeSelected();
|
|
24
|
+
const isRowSelected = row.getIsSelected();
|
|
25
|
+
const isLastChildRow = ((_a = parent === null || parent === void 0 ? void 0 : parent.subRows.at(-1)) === null || _a === void 0 ? void 0 : _a.id) === row.id;
|
|
26
|
+
const depth = row.depth;
|
|
27
|
+
const { ref } = useCellResize(TREE_CELL_ID, cell);
|
|
28
|
+
const linesVisibilityByIndex = useMemo(() => {
|
|
29
|
+
var _a;
|
|
30
|
+
const parents = [];
|
|
31
|
+
for (let i = depth; i >= 0; i--) {
|
|
32
|
+
parents[i] = i === depth ? row : (_a = parents.at(i + 1)) === null || _a === void 0 ? void 0 : _a.getParentRow();
|
|
33
|
+
}
|
|
34
|
+
return parents.map((parent, index) => {
|
|
35
|
+
var _a;
|
|
36
|
+
if (!parent || parents.length === index + 1)
|
|
37
|
+
return true;
|
|
38
|
+
const child = parents[index + 1];
|
|
39
|
+
return (child === null || child === void 0 ? void 0 : child.id) !== ((_a = parent.subRows.at(-1)) === null || _a === void 0 ? void 0 : _a.id) || (row === null || row === void 0 ? void 0 : row.id) === (child === null || child === void 0 ? void 0 : child.id);
|
|
40
|
+
});
|
|
41
|
+
}, [row, depth]);
|
|
42
|
+
const lines = useMemo(() => Array.from({ length: depth }, (_, index) => (_jsx(TreeLine, { visible: linesVisibilityByIndex.at(index), className: index !== 0 ? styles.line : styles.firstLine, halfHeight: index === depth - 1 && isLastChildRow }, index))), [depth, linesVisibilityByIndex, isLastChildRow]);
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
if (!isMultiSelect || !isExpandable || !isRowsSelectionEnabled) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (isAllSubRowsSelected && !isRowSelected) {
|
|
48
|
+
row.toggleSelected(true, { selectChildren: false });
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (isRowSelected && !isAllSubRowsSelected && isSomeSubRowSelected) {
|
|
52
|
+
row.toggleSelected(false, { selectChildren: false });
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
}, [
|
|
56
|
+
isAllSubRowsSelected,
|
|
57
|
+
isSomeSubRowSelected,
|
|
58
|
+
row,
|
|
59
|
+
isRowSelected,
|
|
60
|
+
isMultiSelect,
|
|
61
|
+
isExpandable,
|
|
62
|
+
isRowsSelectionEnabled,
|
|
63
|
+
]);
|
|
64
|
+
const toggleClickHandler = useCallback(event => {
|
|
65
|
+
event.stopPropagation();
|
|
66
|
+
if (enableSelection) {
|
|
67
|
+
if (isMultiSelect) {
|
|
68
|
+
const shouldToggleOn = !isAllSubRowsSelected && !isRowSelected;
|
|
69
|
+
const selectChildren = isAllSubRowsSelected || isSomeSubRowSelected || shouldToggleOn;
|
|
70
|
+
row.toggleSelected(shouldToggleOn, { selectChildren });
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
row.toggleSelected(!isRowSelected, { selectChildren: false });
|
|
74
|
+
}
|
|
75
|
+
}, [isMultiSelect, row, isAllSubRowsSelected, isSomeSubRowSelected, isRowSelected]);
|
|
76
|
+
const chevronClickHandler = useCallback(event => {
|
|
77
|
+
event.stopPropagation();
|
|
78
|
+
row.toggleExpanded();
|
|
79
|
+
}, [row]);
|
|
80
|
+
const value = typeof cell.row.original === 'object' && Object.hasOwn(cell.row.original, accessorKey)
|
|
81
|
+
? // eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
82
|
+
// @ts-ignore
|
|
83
|
+
cell.row.original[accessorKey]
|
|
84
|
+
: cell.getValue();
|
|
85
|
+
return (_jsx("div", { role: 'presentation', "data-test-id": TEST_IDS.tree.node, className: styles.treeCellContainer, onClick: toggleClickHandler, children: _jsxs("div", { className: styles.treeCell, ref: ref, children: [lines, Boolean(parent) && _jsx(TreeLine, { horizontal: true, visible: true }), isExpandable && (_jsx(ButtonFunction, { size: 'xs', "data-test-id": TEST_IDS.tree.chevron, icon: _jsx(ChevronRightSVG, {}), onClick: chevronClickHandler, className: styles.cellExpandButton, "data-expanded": isExpanded || undefined })), _jsxs("div", { className: styles.treeNodeContent, "data-disabled": !isRowsSelectionEnabled || undefined, "data-selected": isRowSelected || undefined, "data-multiselect": isMultiSelect || undefined, children: [showToggle && (_jsx("div", { tabIndex: -1, className: styles.treeCheckboxWrap, children: isMultiSelect ? (_jsx(Checkbox, { size: 's', disabled: !isRowsSelectionEnabled, checked: isRowSelected, "data-test-id": TEST_IDS.tree.checkbox, indeterminate: isSomeSubRowSelected && !isAllSubRowsSelected })) : (_jsx(Radio, { size: 's', disabled: !isRowsSelectionEnabled, "data-test-id": TEST_IDS.tree.radio, checked: isRowSelected })) })), _jsxs("div", { role: 'presentation', onClick: chevronClickHandler, className: styles.cellUserToggleIcon, children: [isExpandable && isExpanded && expandedIcon, isExpandable && !isExpanded && collapsedIcon] }), _jsxs("div", { role: 'presentation', className: styles.userContent, children: [!isExpandable && icon, renderCell ? renderCell(ctx) : _jsx(TruncateString, { text: value })] })] })] }) }));
|
|
86
|
+
};
|
|
14
87
|
return {
|
|
15
88
|
id: TREE_CELL_ID,
|
|
16
89
|
pinned: COLUMN_PIN_POSITION.Left,
|
|
@@ -25,75 +98,6 @@ export function getTreeColumnDef({ showToggle = false, icon = _jsx(FileSVG, { si
|
|
|
25
98
|
},
|
|
26
99
|
enableSorting: false,
|
|
27
100
|
header,
|
|
28
|
-
cell
|
|
29
|
-
var _a;
|
|
30
|
-
const isExpanded = row.getIsExpanded();
|
|
31
|
-
const isExpandable = row.getCanExpand();
|
|
32
|
-
const isMultiSelect = row.getCanMultiSelect();
|
|
33
|
-
const parent = row.getParentRow();
|
|
34
|
-
const isRowsSelectionEnabled = row.getCanSelect();
|
|
35
|
-
const isAllSubRowsSelected = row.getIsAllSubRowsSelected();
|
|
36
|
-
const isSomeSubRowSelected = row.getIsSomeSelected();
|
|
37
|
-
const isRowSelected = row.getIsSelected();
|
|
38
|
-
const isLastChildRow = ((_a = parent === null || parent === void 0 ? void 0 : parent.subRows.at(-1)) === null || _a === void 0 ? void 0 : _a.id) === row.id;
|
|
39
|
-
const depth = row.depth;
|
|
40
|
-
const { ref } = useCellResize(TREE_CELL_ID, cell);
|
|
41
|
-
const linesVisibilityByIndex = useMemo(() => {
|
|
42
|
-
var _a;
|
|
43
|
-
const parents = [];
|
|
44
|
-
for (let i = depth; i >= 0; i--) {
|
|
45
|
-
parents[i] = i === depth ? row : (_a = parents.at(i + 1)) === null || _a === void 0 ? void 0 : _a.getParentRow();
|
|
46
|
-
}
|
|
47
|
-
return parents.map((parent, index) => {
|
|
48
|
-
var _a;
|
|
49
|
-
if (!parent || parents.length === index + 1)
|
|
50
|
-
return true;
|
|
51
|
-
const child = parents[index + 1];
|
|
52
|
-
return (child === null || child === void 0 ? void 0 : child.id) !== ((_a = parent.subRows.at(-1)) === null || _a === void 0 ? void 0 : _a.id) || (row === null || row === void 0 ? void 0 : row.id) === (child === null || child === void 0 ? void 0 : child.id);
|
|
53
|
-
});
|
|
54
|
-
}, [row, depth]);
|
|
55
|
-
const lines = useMemo(() => Array.from({ length: depth }, (_, index) => (_jsx(TreeLine, { visible: linesVisibilityByIndex.at(index), className: index !== 0 ? styles.line : styles.firstLine, halfHeight: index === depth - 1 && isLastChildRow }, index))), [depth, linesVisibilityByIndex, isLastChildRow]);
|
|
56
|
-
useEffect(() => {
|
|
57
|
-
if (!isMultiSelect || !isExpandable || !isRowsSelectionEnabled) {
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
if (isAllSubRowsSelected && !isRowSelected) {
|
|
61
|
-
row.toggleSelected(true, { selectChildren: false });
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
if (isRowSelected && !isAllSubRowsSelected && isSomeSubRowSelected) {
|
|
65
|
-
row.toggleSelected(false, { selectChildren: false });
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
}, [
|
|
69
|
-
isAllSubRowsSelected,
|
|
70
|
-
isSomeSubRowSelected,
|
|
71
|
-
row,
|
|
72
|
-
isRowSelected,
|
|
73
|
-
isMultiSelect,
|
|
74
|
-
isExpandable,
|
|
75
|
-
isRowsSelectionEnabled,
|
|
76
|
-
]);
|
|
77
|
-
const toggleClickHandler = useCallback(event => {
|
|
78
|
-
event.stopPropagation();
|
|
79
|
-
if (isMultiSelect) {
|
|
80
|
-
const shouldToggleOn = !isAllSubRowsSelected && !isRowSelected;
|
|
81
|
-
const selectChildren = isAllSubRowsSelected || isSomeSubRowSelected || shouldToggleOn;
|
|
82
|
-
row.toggleSelected(shouldToggleOn, { selectChildren });
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
row.toggleSelected(!isRowSelected, { selectChildren: false });
|
|
86
|
-
}, [isMultiSelect, row, isAllSubRowsSelected, isSomeSubRowSelected, isRowSelected]);
|
|
87
|
-
const chevronClickHandler = useCallback(event => {
|
|
88
|
-
event.stopPropagation();
|
|
89
|
-
row.toggleExpanded();
|
|
90
|
-
}, [row]);
|
|
91
|
-
const value = typeof cell.row.original === 'object' && Object.hasOwn(cell.row.original, accessorKey)
|
|
92
|
-
? // eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
93
|
-
// @ts-ignore
|
|
94
|
-
cell.row.original[accessorKey]
|
|
95
|
-
: cell.getValue();
|
|
96
|
-
return (_jsx("div", { role: 'presentation', "data-test-id": TEST_IDS.tree.node, className: styles.treeCellContainer, onClick: toggleClickHandler, children: _jsxs("div", { className: styles.treeCell, ref: ref, children: [lines, Boolean(parent) && _jsx(TreeLine, { horizontal: true, visible: true }), isExpandable && (_jsx(ButtonFunction, { size: 'xs', "data-test-id": TEST_IDS.tree.chevron, icon: _jsx(ChevronRightSVG, {}), onClick: chevronClickHandler, className: styles.cellExpandButton, "data-expanded": isExpanded || undefined })), _jsxs("div", { className: styles.treeNodeContent, "data-disabled": !isRowsSelectionEnabled || undefined, "data-selected": isRowSelected || undefined, "data-multiselect": isMultiSelect || undefined, children: [showToggle && (_jsx("div", { tabIndex: -1, className: styles.treeCheckboxWrap, children: isMultiSelect ? (_jsx(Checkbox, { size: 's', disabled: !isRowsSelectionEnabled, checked: isRowSelected, "data-test-id": TEST_IDS.tree.checkbox, indeterminate: isSomeSubRowSelected && !isAllSubRowsSelected })) : (_jsx(Radio, { size: 's', disabled: !isRowsSelectionEnabled, "data-test-id": TEST_IDS.tree.radio, checked: isRowSelected })) })), _jsxs("div", { role: 'presentation', onClick: chevronClickHandler, className: styles.cellUserToggleIcon, children: [isExpandable && isExpanded && expandedIcon, isExpandable && !isExpanded && collapsedIcon] }), _jsxs("div", { role: 'presentation', className: styles.userContent, children: [!isExpandable && icon, _jsx(TruncateString, { text: value })] })] })] }) }));
|
|
97
|
-
},
|
|
101
|
+
cell,
|
|
98
102
|
};
|
|
99
103
|
}
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
6
|
"title": "Table",
|
|
7
|
-
"version": "0.36.
|
|
7
|
+
"version": "0.36.24",
|
|
8
8
|
"sideEffects": [
|
|
9
9
|
"*.css",
|
|
10
10
|
"*.woff",
|
|
@@ -66,5 +66,5 @@
|
|
|
66
66
|
"peerDependencies": {
|
|
67
67
|
"@snack-uikit/locale": "*"
|
|
68
68
|
},
|
|
69
|
-
"gitHead": "
|
|
69
|
+
"gitHead": "bb2179dfa0dd290a2942170857c5b190630a2ee0"
|
|
70
70
|
}
|
|
@@ -260,7 +260,7 @@ export function Table<TData extends object, TFilters extends FiltersState = Reco
|
|
|
260
260
|
onRowSelectionChange,
|
|
261
261
|
enableGrouping: true,
|
|
262
262
|
enableRowSelection,
|
|
263
|
-
enableMultiRowSelection: rowSelectionProp?.multiRow,
|
|
263
|
+
enableMultiRowSelection: rowSelectionProp?.enable && rowSelectionProp?.multiRow,
|
|
264
264
|
enableFilters: true,
|
|
265
265
|
getSubRows: expanding?.getSubRows,
|
|
266
266
|
filterFromLeafRows: Boolean(expanding),
|
|
@@ -20,7 +20,7 @@ export function getTableColumnsDefinitions<TData extends object>({
|
|
|
20
20
|
cols = [getSelectionCellColumnDef(enableSelectPinned), ...cols];
|
|
21
21
|
}
|
|
22
22
|
if (expanding) {
|
|
23
|
-
cols = [getTreeColumnDef(expanding.expandingColumnDefinition), ...cols];
|
|
23
|
+
cols = [getTreeColumnDef({ ...expanding.expandingColumnDefinition, enableSelection }), ...cols];
|
|
24
24
|
}
|
|
25
25
|
return cols;
|
|
26
26
|
}
|
|
@@ -28,18 +28,22 @@ type BaseTreeColumnDef = {
|
|
|
28
28
|
|
|
29
29
|
type TreeColumnDef = BaseTreeColumnDef & {
|
|
30
30
|
header?: never;
|
|
31
|
-
|
|
31
|
+
cell?: never;
|
|
32
32
|
};
|
|
33
33
|
|
|
34
34
|
type TreeColumnDefWithDescription<TData> = BaseTreeColumnDef & {
|
|
35
35
|
/** Заголовок колонки */
|
|
36
|
-
|
|
36
|
+
cell?(ctx: CellContext<TData, unknown>): ReactNode;
|
|
37
37
|
/** Рендер функция заголовка колонки */
|
|
38
38
|
header?: ColumnDefinition<TData>['header'];
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
export type TreeColumnDefinitionProps<TData> = TreeColumnDef | TreeColumnDefWithDescription<TData>;
|
|
42
42
|
|
|
43
|
+
type TreeColDefProps<TData> = TreeColumnDefinitionProps<TData> & {
|
|
44
|
+
enableSelection?: boolean;
|
|
45
|
+
};
|
|
46
|
+
|
|
43
47
|
/** Вспомогательная функция для создания ячейки со статусом */
|
|
44
48
|
export function getTreeColumnDef<TData>({
|
|
45
49
|
showToggle = false,
|
|
@@ -48,89 +52,79 @@ export function getTreeColumnDef<TData>({
|
|
|
48
52
|
collapsedIcon = <FolderSVG size={24} />,
|
|
49
53
|
header,
|
|
50
54
|
accessorKey,
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
isRowSelected,
|
|
125
|
-
isMultiSelect,
|
|
126
|
-
isExpandable,
|
|
127
|
-
isRowsSelectionEnabled,
|
|
128
|
-
]);
|
|
129
|
-
|
|
130
|
-
const toggleClickHandler: MouseEventHandler<HTMLElement> = useCallback(
|
|
131
|
-
event => {
|
|
132
|
-
event.stopPropagation();
|
|
133
|
-
|
|
55
|
+
cell: renderCell,
|
|
56
|
+
enableSelection,
|
|
57
|
+
}: TreeColDefProps<TData>): ColumnDefinition<TData> {
|
|
58
|
+
const cell: ColumnDefinition<TData>['cell'] = function TreeCell(ctx) {
|
|
59
|
+
const { row, cell } = ctx;
|
|
60
|
+
const isExpanded = row.getIsExpanded();
|
|
61
|
+
const isExpandable = row.getCanExpand();
|
|
62
|
+
const isMultiSelect = row.getCanMultiSelect();
|
|
63
|
+
const parent = row.getParentRow();
|
|
64
|
+
const isRowsSelectionEnabled = row.getCanSelect();
|
|
65
|
+
const isAllSubRowsSelected = row.getIsAllSubRowsSelected();
|
|
66
|
+
const isSomeSubRowSelected = row.getIsSomeSelected();
|
|
67
|
+
const isRowSelected = row.getIsSelected();
|
|
68
|
+
const isLastChildRow = parent?.subRows.at(-1)?.id === row.id;
|
|
69
|
+
const depth = row.depth;
|
|
70
|
+
const { ref } = useCellResize(TREE_CELL_ID, cell);
|
|
71
|
+
|
|
72
|
+
const linesVisibilityByIndex = useMemo(() => {
|
|
73
|
+
const parents: (Row<TData> | undefined)[] = [];
|
|
74
|
+
for (let i = depth; i >= 0; i--) {
|
|
75
|
+
parents[i] = i === depth ? row : parents.at(i + 1)?.getParentRow();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return parents.map((parent, index) => {
|
|
79
|
+
if (!parent || parents.length === index + 1) return true;
|
|
80
|
+
const child = parents[index + 1];
|
|
81
|
+
|
|
82
|
+
return child?.id !== parent.subRows.at(-1)?.id || row?.id === child?.id;
|
|
83
|
+
});
|
|
84
|
+
}, [row, depth]);
|
|
85
|
+
|
|
86
|
+
const lines = useMemo(
|
|
87
|
+
() =>
|
|
88
|
+
Array.from({ length: depth }, (_, index) => (
|
|
89
|
+
<TreeLine
|
|
90
|
+
key={index}
|
|
91
|
+
visible={linesVisibilityByIndex.at(index)}
|
|
92
|
+
className={index !== 0 ? styles.line : styles.firstLine}
|
|
93
|
+
halfHeight={index === depth - 1 && isLastChildRow}
|
|
94
|
+
/>
|
|
95
|
+
)),
|
|
96
|
+
[depth, linesVisibilityByIndex, isLastChildRow],
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
useEffect(() => {
|
|
100
|
+
if (!isMultiSelect || !isExpandable || !isRowsSelectionEnabled) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (isAllSubRowsSelected && !isRowSelected) {
|
|
105
|
+
row.toggleSelected(true, { selectChildren: false });
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (isRowSelected && !isAllSubRowsSelected && isSomeSubRowSelected) {
|
|
110
|
+
row.toggleSelected(false, { selectChildren: false });
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
}, [
|
|
114
|
+
isAllSubRowsSelected,
|
|
115
|
+
isSomeSubRowSelected,
|
|
116
|
+
row,
|
|
117
|
+
isRowSelected,
|
|
118
|
+
isMultiSelect,
|
|
119
|
+
isExpandable,
|
|
120
|
+
isRowsSelectionEnabled,
|
|
121
|
+
]);
|
|
122
|
+
|
|
123
|
+
const toggleClickHandler: MouseEventHandler<HTMLElement> = useCallback(
|
|
124
|
+
event => {
|
|
125
|
+
event.stopPropagation();
|
|
126
|
+
|
|
127
|
+
if (enableSelection) {
|
|
134
128
|
if (isMultiSelect) {
|
|
135
129
|
const shouldToggleOn = !isAllSubRowsSelected && !isRowSelected;
|
|
136
130
|
const selectChildren = isAllSubRowsSelected || isSomeSubRowSelected || shouldToggleOn;
|
|
@@ -141,83 +135,101 @@ export function getTreeColumnDef<TData>({
|
|
|
141
135
|
}
|
|
142
136
|
|
|
143
137
|
row.toggleSelected(!isRowSelected, { selectChildren: false });
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
)}
|
|
209
|
-
<div role='presentation' onClick={chevronClickHandler} className={styles.cellUserToggleIcon}>
|
|
210
|
-
{isExpandable && isExpanded && expandedIcon}
|
|
211
|
-
{isExpandable && !isExpanded && collapsedIcon}
|
|
212
|
-
</div>
|
|
213
|
-
<div role='presentation' className={styles.userContent}>
|
|
214
|
-
{!isExpandable && icon}
|
|
215
|
-
<TruncateString text={value} />
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
[isMultiSelect, row, isAllSubRowsSelected, isSomeSubRowSelected, isRowSelected],
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
const chevronClickHandler: MouseEventHandler<HTMLElement> = useCallback(
|
|
144
|
+
event => {
|
|
145
|
+
event.stopPropagation();
|
|
146
|
+
row.toggleExpanded();
|
|
147
|
+
},
|
|
148
|
+
[row],
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
const value =
|
|
152
|
+
typeof cell.row.original === 'object' && Object.hasOwn(cell.row.original as object, accessorKey)
|
|
153
|
+
? // eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
154
|
+
// @ts-ignore
|
|
155
|
+
cell.row.original[accessorKey]
|
|
156
|
+
: cell.getValue<string>();
|
|
157
|
+
|
|
158
|
+
return (
|
|
159
|
+
<div
|
|
160
|
+
role={'presentation'}
|
|
161
|
+
data-test-id={TEST_IDS.tree.node}
|
|
162
|
+
className={styles.treeCellContainer}
|
|
163
|
+
onClick={toggleClickHandler}
|
|
164
|
+
>
|
|
165
|
+
<div className={styles.treeCell} ref={ref}>
|
|
166
|
+
{lines}
|
|
167
|
+
{Boolean(parent) && <TreeLine horizontal visible />}
|
|
168
|
+
{isExpandable && (
|
|
169
|
+
<ButtonFunction
|
|
170
|
+
size='xs'
|
|
171
|
+
data-test-id={TEST_IDS.tree.chevron}
|
|
172
|
+
icon={<ChevronRightSVG />}
|
|
173
|
+
onClick={chevronClickHandler}
|
|
174
|
+
className={styles.cellExpandButton}
|
|
175
|
+
data-expanded={isExpanded || undefined}
|
|
176
|
+
/>
|
|
177
|
+
)}
|
|
178
|
+
<div
|
|
179
|
+
className={styles.treeNodeContent}
|
|
180
|
+
data-disabled={!isRowsSelectionEnabled || undefined}
|
|
181
|
+
data-selected={isRowSelected || undefined}
|
|
182
|
+
data-multiselect={isMultiSelect || undefined}
|
|
183
|
+
>
|
|
184
|
+
{showToggle && (
|
|
185
|
+
<div tabIndex={-1} className={styles.treeCheckboxWrap}>
|
|
186
|
+
{isMultiSelect ? (
|
|
187
|
+
<Checkbox
|
|
188
|
+
size='s'
|
|
189
|
+
disabled={!isRowsSelectionEnabled}
|
|
190
|
+
checked={isRowSelected}
|
|
191
|
+
data-test-id={TEST_IDS.tree.checkbox}
|
|
192
|
+
indeterminate={isSomeSubRowSelected && !isAllSubRowsSelected}
|
|
193
|
+
/>
|
|
194
|
+
) : (
|
|
195
|
+
<Radio
|
|
196
|
+
size='s'
|
|
197
|
+
disabled={!isRowsSelectionEnabled}
|
|
198
|
+
data-test-id={TEST_IDS.tree.radio}
|
|
199
|
+
checked={isRowSelected}
|
|
200
|
+
/>
|
|
201
|
+
)}
|
|
216
202
|
</div>
|
|
203
|
+
)}
|
|
204
|
+
<div role='presentation' onClick={chevronClickHandler} className={styles.cellUserToggleIcon}>
|
|
205
|
+
{isExpandable && isExpanded && expandedIcon}
|
|
206
|
+
{isExpandable && !isExpanded && collapsedIcon}
|
|
207
|
+
</div>
|
|
208
|
+
<div role='presentation' className={styles.userContent}>
|
|
209
|
+
{!isExpandable && icon}
|
|
210
|
+
|
|
211
|
+
{renderCell ? renderCell(ctx) : <TruncateString text={value} />}
|
|
217
212
|
</div>
|
|
218
213
|
</div>
|
|
219
214
|
</div>
|
|
220
|
-
|
|
215
|
+
</div>
|
|
216
|
+
);
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
return {
|
|
220
|
+
id: TREE_CELL_ID,
|
|
221
|
+
pinned: COLUMN_PIN_POSITION.Left,
|
|
222
|
+
accessorKey,
|
|
223
|
+
noBodyCellPadding: true,
|
|
224
|
+
noHeaderCellPadding: false,
|
|
225
|
+
enableResizing: true,
|
|
226
|
+
size: 150,
|
|
227
|
+
maxSize: Number.MAX_SAFE_INTEGER,
|
|
228
|
+
meta: {
|
|
229
|
+
skipOnExport: false,
|
|
221
230
|
},
|
|
231
|
+
enableSorting: false,
|
|
232
|
+
header,
|
|
233
|
+
cell,
|
|
222
234
|
};
|
|
223
235
|
}
|