@qoretechnologies/reqore 0.35.0 → 0.35.2
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/__tests__/helpers/table.test.tsx +20 -0
- package/__tests__/table.test.tsx +199 -2
- package/dist/components/ControlGroup/index.d.ts.map +1 -1
- package/dist/components/ControlGroup/index.js +1 -1
- package/dist/components/ControlGroup/index.js.map +1 -1
- package/dist/components/Dropdown/list.d.ts +1 -0
- package/dist/components/Dropdown/list.d.ts.map +1 -1
- package/dist/components/Dropdown/list.js.map +1 -1
- package/dist/components/Menu/divider.d.ts +1 -0
- package/dist/components/Menu/divider.d.ts.map +1 -1
- package/dist/components/Menu/divider.js +3 -2
- package/dist/components/Menu/divider.js.map +1 -1
- package/dist/components/Spacer/index.d.ts.map +1 -1
- package/dist/components/Spacer/index.js +1 -1
- package/dist/components/Spacer/index.js.map +1 -1
- package/dist/components/Table/body.d.ts +10 -3
- package/dist/components/Table/body.d.ts.map +1 -1
- package/dist/components/Table/body.js +40 -9
- package/dist/components/Table/body.js.map +1 -1
- package/dist/components/Table/cell.d.ts +1 -0
- package/dist/components/Table/cell.d.ts.map +1 -1
- package/dist/components/Table/cell.js +4 -4
- package/dist/components/Table/cell.js.map +1 -1
- package/dist/components/Table/header.d.ts +8 -7
- package/dist/components/Table/header.d.ts.map +1 -1
- package/dist/components/Table/header.js +34 -37
- package/dist/components/Table/header.js.map +1 -1
- package/dist/components/Table/headerCell.d.ts +3 -2
- package/dist/components/Table/headerCell.d.ts.map +1 -1
- package/dist/components/Table/headerCell.js +39 -8
- package/dist/components/Table/headerCell.js.map +1 -1
- package/dist/components/Table/helpers.d.ts +7 -1
- package/dist/components/Table/helpers.d.ts.map +1 -1
- package/dist/components/Table/helpers.js +30 -4
- package/dist/components/Table/helpers.js.map +1 -1
- package/dist/components/Table/index.d.ts +13 -2
- package/dist/components/Table/index.d.ts.map +1 -1
- package/dist/components/Table/index.js +203 -23
- package/dist/components/Table/index.js.map +1 -1
- package/dist/components/Table/row.d.ts +2 -1
- package/dist/components/Table/row.d.ts.map +1 -1
- package/dist/components/Table/row.js +19 -29
- package/dist/components/Table/row.js.map +1 -1
- package/dist/constants/sizes.d.ts +15 -0
- package/dist/constants/sizes.d.ts.map +1 -1
- package/dist/constants/sizes.js +16 -1
- package/dist/constants/sizes.js.map +1 -1
- package/package.json +1 -1
- package/src/components/ControlGroup/index.tsx +1 -0
- package/src/components/Dropdown/list.tsx +1 -0
- package/src/components/Menu/divider.tsx +31 -21
- package/src/components/Spacer/index.tsx +2 -2
- package/src/components/Table/body.tsx +81 -35
- package/src/components/Table/cell.tsx +8 -2
- package/src/components/Table/header.tsx +133 -124
- package/src/components/Table/headerCell.tsx +45 -9
- package/src/components/Table/helpers.ts +48 -3
- package/src/components/Table/index.tsx +266 -53
- package/src/components/Table/row.tsx +38 -55
- package/src/constants/sizes.ts +17 -0
- package/src/stories/Breadcrumbs/Breadcrumbs.stories.tsx +0 -3
- package/src/stories/Table/Table.stories.tsx +99 -1
- package/tests.json +1 -1
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
/* @flow */
|
|
2
2
|
import { size as count, isArray } from 'lodash';
|
|
3
|
-
import React, { useCallback, useMemo, useState } from 'react';
|
|
3
|
+
import React, { useCallback, useMemo, useRef, useState } from 'react';
|
|
4
4
|
import { useMeasure, useUpdateEffect } from 'react-use';
|
|
5
|
+
import styled, { css } from 'styled-components';
|
|
5
6
|
import { ReqoreMessage, ReqorePanel, ReqoreVerticalSpacer } from '../..';
|
|
6
7
|
import { TABLE_SIZE_TO_PX, TSizes } from '../../constants/sizes';
|
|
7
8
|
import { IReqoreTheme, TReqoreIntent } from '../../constants/theme';
|
|
8
9
|
import { useQueryWithDelay } from '../../hooks/useQueryWithDelay';
|
|
9
10
|
import { IReqoreIntent, IReqoreTooltip } from '../../types/global';
|
|
10
11
|
import { IReqoreButtonProps, TReqoreBadge } from '../Button';
|
|
12
|
+
import { IReqoreDropdownItem } from '../Dropdown/list';
|
|
11
13
|
import ReqoreInput, { IReqoreInputProps } from '../Input';
|
|
12
14
|
import { IReqorePanelAction, IReqorePanelProps, IReqorePanelSubAction } from '../Panel';
|
|
13
15
|
import ReqoreTableBody from './body';
|
|
@@ -16,20 +18,21 @@ import { IReqoreTableHeaderCellProps } from './headerCell';
|
|
|
16
18
|
import {
|
|
17
19
|
fixSort,
|
|
18
20
|
flipSortDirection,
|
|
21
|
+
getColumnsByPinType,
|
|
19
22
|
getColumnsCount,
|
|
20
23
|
getOnlyShownColumns,
|
|
21
24
|
getZoomActions,
|
|
25
|
+
hasGroupedColumns,
|
|
22
26
|
hasHiddenColumns,
|
|
23
27
|
prepareColumns,
|
|
24
28
|
sizeToZoom,
|
|
25
29
|
sortTableData,
|
|
26
|
-
updateColumnData,
|
|
27
30
|
zoomToSize,
|
|
28
31
|
} from './helpers';
|
|
29
32
|
import { IReqoreTableRowOptions } from './row';
|
|
30
33
|
|
|
31
34
|
export type TReqoreTableColumnContent =
|
|
32
|
-
| React.FC<{ [key: string]: any; _selectId?: string | number }>
|
|
35
|
+
| React.FC<{ [key: string]: any; _selectId?: string | number; _size: TSizes; _dataId: string }>
|
|
33
36
|
| 'time-ago'
|
|
34
37
|
| 'tag'
|
|
35
38
|
| `tag:${TReqoreIntent}`
|
|
@@ -44,12 +47,16 @@ export interface IReqoreTableColumn extends IReqoreIntent {
|
|
|
44
47
|
show?: boolean;
|
|
45
48
|
grow?: 1 | 2 | 3 | 4;
|
|
46
49
|
width?: number;
|
|
50
|
+
minWidth?: number;
|
|
51
|
+
maxWidth?: number;
|
|
47
52
|
resizedWidth?: number;
|
|
48
53
|
align?: 'center' | 'left' | 'right';
|
|
54
|
+
pin?: 'left' | 'right';
|
|
49
55
|
|
|
50
56
|
resizable?: boolean;
|
|
51
57
|
sortable?: boolean;
|
|
52
58
|
hideable?: boolean;
|
|
59
|
+
pinnable?: boolean;
|
|
53
60
|
|
|
54
61
|
filterable?: boolean;
|
|
55
62
|
filterPlaceholder?: string;
|
|
@@ -58,13 +65,16 @@ export interface IReqoreTableColumn extends IReqoreIntent {
|
|
|
58
65
|
header?: {
|
|
59
66
|
columns?: IReqoreTableColumn[];
|
|
60
67
|
component?: React.FC<IReqoreTableHeaderCellProps>;
|
|
61
|
-
|
|
68
|
+
actions?: IReqoreDropdownItem[];
|
|
69
|
+
} & Omit<IReqoreButtonProps, 'maxWidth'>;
|
|
62
70
|
|
|
63
71
|
cell?: {
|
|
64
72
|
onClick?: (cellValue: any) => void;
|
|
65
73
|
tooltip?: (cellValue: any) => string | IReqoreTooltip;
|
|
66
74
|
content?: TReqoreTableColumnContent;
|
|
75
|
+
actions?: (data: IReqoreTableRowData) => IReqoreButtonProps[];
|
|
67
76
|
intent?: TReqoreIntent;
|
|
77
|
+
padded?: 'both' | 'horizontal' | 'vertical' | 'none';
|
|
68
78
|
};
|
|
69
79
|
}
|
|
70
80
|
|
|
@@ -101,6 +111,7 @@ export interface IReqoreTableProps extends IReqorePanelProps {
|
|
|
101
111
|
selected?: string[];
|
|
102
112
|
selectedRowIntent?: TReqoreIntent;
|
|
103
113
|
onSelectedChange?: (selected?: any[]) => void;
|
|
114
|
+
onSelectClick?: (dataId: string | number) => void;
|
|
104
115
|
selectToggleTooltip?: string;
|
|
105
116
|
|
|
106
117
|
striped?: boolean;
|
|
@@ -128,6 +139,28 @@ export interface IReqoreTableSort {
|
|
|
128
139
|
direction?: 'asc' | 'desc';
|
|
129
140
|
}
|
|
130
141
|
|
|
142
|
+
const StyledTableWrapper = styled.div`
|
|
143
|
+
overflow: hidden;
|
|
144
|
+
|
|
145
|
+
${({ isPinned }) =>
|
|
146
|
+
isPinned
|
|
147
|
+
? css`
|
|
148
|
+
flex-shrink: 0;
|
|
149
|
+
`
|
|
150
|
+
: css`
|
|
151
|
+
width: 100%;
|
|
152
|
+
display: flex;
|
|
153
|
+
flex-flow: column;
|
|
154
|
+
flex: 1;
|
|
155
|
+
`};
|
|
156
|
+
`;
|
|
157
|
+
|
|
158
|
+
const StyledTablesWrapper = styled.div`
|
|
159
|
+
display: flex;
|
|
160
|
+
flex-flow: row;
|
|
161
|
+
overflow: hidden;
|
|
162
|
+
`;
|
|
163
|
+
|
|
131
164
|
const ReqoreTable = ({
|
|
132
165
|
className,
|
|
133
166
|
height = 300,
|
|
@@ -143,7 +176,7 @@ const ReqoreTable = ({
|
|
|
143
176
|
customTheme,
|
|
144
177
|
onRowClick,
|
|
145
178
|
striped,
|
|
146
|
-
selectedRowIntent,
|
|
179
|
+
selectedRowIntent = 'info',
|
|
147
180
|
size = 'normal',
|
|
148
181
|
wrapperSize = 'normal',
|
|
149
182
|
intent,
|
|
@@ -158,19 +191,97 @@ const ReqoreTable = ({
|
|
|
158
191
|
headerCellComponent,
|
|
159
192
|
rowComponent,
|
|
160
193
|
bodyCellComponent,
|
|
194
|
+
onSelectClick,
|
|
161
195
|
...rest
|
|
162
196
|
}: IReqoreTableProps) => {
|
|
163
|
-
const
|
|
197
|
+
const leftTableRef = useRef<HTMLDivElement>(undefined);
|
|
198
|
+
const rightTableRef = useRef<HTMLDivElement>(undefined);
|
|
199
|
+
const mainTableRef = useRef<HTMLDivElement>(undefined);
|
|
200
|
+
const mainHeaderRef = useRef<HTMLDivElement>(undefined);
|
|
201
|
+
|
|
202
|
+
const [isScrolled, setIsScrolled] = useState<boolean>(false);
|
|
164
203
|
const [_data, setData] = useState<IReqoreTableData>(data || []);
|
|
165
204
|
const [_sort, setSort] = useState<IReqoreTableSort>(fixSort(sort));
|
|
166
|
-
const [_selected, setSelected] = useState<(string | number)[]>([]);
|
|
205
|
+
const [_selected, setSelected] = useState<(string | number)[]>(selected || []);
|
|
167
206
|
const [_selectedQuant, setSelectedQuant] = useState<'all' | 'none' | 'some'>('none');
|
|
168
|
-
const [
|
|
207
|
+
const [columnModifiers, setColumnModifiers] = useState<{
|
|
208
|
+
[dataId: string]: { [modifier: string]: any };
|
|
209
|
+
}>({});
|
|
210
|
+
const [_internalColumns, setColumns] = useState<IReqoreTableColumn[]>(columns);
|
|
169
211
|
const [zoom, setZoom] = useState<number>(sizeToZoom[size]);
|
|
170
212
|
|
|
171
213
|
const [wrapperRef, sizes] = useMeasure();
|
|
172
214
|
const { query, preQuery, setQuery, setPreQuery } = useQueryWithDelay(filter, 300, onFilterChange);
|
|
173
215
|
|
|
216
|
+
const selectedIcon = useMemo(() => {
|
|
217
|
+
switch (_selectedQuant) {
|
|
218
|
+
case 'all':
|
|
219
|
+
return 'CheckboxCircleLine';
|
|
220
|
+
case 'some':
|
|
221
|
+
return 'IndeterminateCircleLine';
|
|
222
|
+
default:
|
|
223
|
+
return 'CheckboxBlankCircleLine';
|
|
224
|
+
}
|
|
225
|
+
}, [_selectedQuant]);
|
|
226
|
+
|
|
227
|
+
const finalColumns = useMemo(() => {
|
|
228
|
+
let fullColumns = [..._internalColumns];
|
|
229
|
+
|
|
230
|
+
if (selectable) {
|
|
231
|
+
fullColumns.unshift({
|
|
232
|
+
dataId: 'selectbox',
|
|
233
|
+
width: 50,
|
|
234
|
+
sortable: false,
|
|
235
|
+
hideable: false,
|
|
236
|
+
filterable: false,
|
|
237
|
+
resizable: false,
|
|
238
|
+
pin: 'left',
|
|
239
|
+
pinnable: false,
|
|
240
|
+
align: 'center',
|
|
241
|
+
|
|
242
|
+
header: {
|
|
243
|
+
icon: selectedIcon,
|
|
244
|
+
tooltip: 'Toggle selection on all data',
|
|
245
|
+
onClick: () => {
|
|
246
|
+
handleToggleSelectClick();
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
|
|
250
|
+
cell: {
|
|
251
|
+
padded: 'none',
|
|
252
|
+
actions: ({ _selectId }) => [
|
|
253
|
+
{
|
|
254
|
+
tooltip: selectToggleTooltip,
|
|
255
|
+
icon: !_selectId
|
|
256
|
+
? 'Forbid2Line'
|
|
257
|
+
: _selected?.find((s) => s === _selectId)
|
|
258
|
+
? 'CheckboxCircleLine'
|
|
259
|
+
: 'CheckboxBlankCircleLine',
|
|
260
|
+
intent: !_selectId
|
|
261
|
+
? 'muted'
|
|
262
|
+
: _selected?.find((s) => s === _selectId)
|
|
263
|
+
? selectedRowIntent
|
|
264
|
+
: undefined,
|
|
265
|
+
onClick: () => handleSelectClick(_selectId),
|
|
266
|
+
},
|
|
267
|
+
],
|
|
268
|
+
},
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return prepareColumns(fullColumns, columnModifiers, zoomToSize[zoom]);
|
|
273
|
+
}, [
|
|
274
|
+
_internalColumns,
|
|
275
|
+
columnModifiers,
|
|
276
|
+
zoom,
|
|
277
|
+
selectable,
|
|
278
|
+
_selectedQuant,
|
|
279
|
+
selectedIcon,
|
|
280
|
+
selectToggleTooltip,
|
|
281
|
+
_selected,
|
|
282
|
+
selectedRowIntent,
|
|
283
|
+
]);
|
|
284
|
+
|
|
174
285
|
const filters: { [key: string]: string } = useMemo(() => {
|
|
175
286
|
const getFilters = (columnsToTransform: IReqoreTableColumn[]) =>
|
|
176
287
|
columnsToTransform.reduce((filterObject, column) => {
|
|
@@ -191,8 +302,8 @@ const ReqoreTable = ({
|
|
|
191
302
|
return filterObject;
|
|
192
303
|
}, {});
|
|
193
304
|
|
|
194
|
-
return getFilters(
|
|
195
|
-
}, [
|
|
305
|
+
return getFilters(finalColumns);
|
|
306
|
+
}, [finalColumns]);
|
|
196
307
|
|
|
197
308
|
const transformedData = useMemo(() => {
|
|
198
309
|
// Filter by global query
|
|
@@ -220,7 +331,7 @@ const ReqoreTable = ({
|
|
|
220
331
|
}, [_sort]);
|
|
221
332
|
|
|
222
333
|
useUpdateEffect(() => {
|
|
223
|
-
setColumns(
|
|
334
|
+
setColumns(columns);
|
|
224
335
|
}, [columns]);
|
|
225
336
|
|
|
226
337
|
useUpdateEffect(() => {
|
|
@@ -266,6 +377,11 @@ const ReqoreTable = ({
|
|
|
266
377
|
};
|
|
267
378
|
|
|
268
379
|
const handleSelectClick = (selectId: string | number) => {
|
|
380
|
+
if (onSelectClick) {
|
|
381
|
+
onSelectClick(selectId);
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
|
|
269
385
|
setSelected((current) => {
|
|
270
386
|
let newSelected = [...current];
|
|
271
387
|
const isSelected = newSelected.find((selected) => selectId === selected);
|
|
@@ -300,9 +416,17 @@ const ReqoreTable = ({
|
|
|
300
416
|
|
|
301
417
|
const handleColumnsUpdate = useCallback(
|
|
302
418
|
<T extends keyof IReqoreTableColumn>(id: string, key: T, value: IReqoreTableColumn[T]) => {
|
|
303
|
-
|
|
419
|
+
setColumnModifiers((current) => {
|
|
420
|
+
return {
|
|
421
|
+
...current,
|
|
422
|
+
[id]: {
|
|
423
|
+
...current[id],
|
|
424
|
+
[key]: value,
|
|
425
|
+
},
|
|
426
|
+
};
|
|
427
|
+
});
|
|
304
428
|
},
|
|
305
|
-
[
|
|
429
|
+
[columnModifiers]
|
|
306
430
|
);
|
|
307
431
|
|
|
308
432
|
const handlePreQueryChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
|
|
@@ -327,7 +451,11 @@ const ReqoreTable = ({
|
|
|
327
451
|
});
|
|
328
452
|
};
|
|
329
453
|
|
|
330
|
-
|
|
454
|
+
finalColumns.forEach((column) => {
|
|
455
|
+
if (column.hideable === false) {
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
|
|
331
459
|
if (column.header?.columns) {
|
|
332
460
|
column.header?.columns.forEach((subColumn) => {
|
|
333
461
|
addColumn(subColumn);
|
|
@@ -338,7 +466,7 @@ const ReqoreTable = ({
|
|
|
338
466
|
});
|
|
339
467
|
|
|
340
468
|
return _columnsList;
|
|
341
|
-
}, [
|
|
469
|
+
}, [finalColumns]);
|
|
342
470
|
|
|
343
471
|
const tableActions = useMemo<IReqorePanelAction[]>(() => {
|
|
344
472
|
const finalActions: IReqorePanelAction[] = [...actions];
|
|
@@ -347,8 +475,8 @@ const ReqoreTable = ({
|
|
|
347
475
|
label: 'Columns',
|
|
348
476
|
icon: 'LayoutColumnLine',
|
|
349
477
|
className: 'reqore-table-columns-options',
|
|
350
|
-
badge: getColumnsCount(getOnlyShownColumns(
|
|
351
|
-
intent: hasHiddenColumns(
|
|
478
|
+
badge: getColumnsCount(getOnlyShownColumns(finalColumns)),
|
|
479
|
+
intent: hasHiddenColumns(finalColumns) ? 'info' : undefined,
|
|
352
480
|
multiSelect: true,
|
|
353
481
|
actions: columnsList,
|
|
354
482
|
});
|
|
@@ -381,6 +509,51 @@ const ReqoreTable = ({
|
|
|
381
509
|
});
|
|
382
510
|
}
|
|
383
511
|
|
|
512
|
+
if (isScrolled) {
|
|
513
|
+
finalActions.push({
|
|
514
|
+
icon: 'ArrowUpSFill',
|
|
515
|
+
tooltip: 'Scroll to top',
|
|
516
|
+
className: 'reqore-table-columns-scroll-top',
|
|
517
|
+
responsive: true,
|
|
518
|
+
onClick: () => {
|
|
519
|
+
mainTableRef.current?.scrollTo({
|
|
520
|
+
top: 0,
|
|
521
|
+
behavior: 'smooth',
|
|
522
|
+
});
|
|
523
|
+
leftTableRef.current?.scrollTo({
|
|
524
|
+
top: 0,
|
|
525
|
+
behavior: 'smooth',
|
|
526
|
+
});
|
|
527
|
+
rightTableRef.current?.scrollTo({
|
|
528
|
+
top: 0,
|
|
529
|
+
behavior: 'smooth',
|
|
530
|
+
});
|
|
531
|
+
|
|
532
|
+
setIsScrolled(false);
|
|
533
|
+
},
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
if (count(columnModifiers) || zoomable || filterable) {
|
|
538
|
+
finalActions.push({
|
|
539
|
+
icon: 'MoreLine',
|
|
540
|
+
className: 'reqore-table-more',
|
|
541
|
+
actions: [
|
|
542
|
+
{
|
|
543
|
+
label: 'Reset table',
|
|
544
|
+
icon: 'RestartLine',
|
|
545
|
+
className: 'reqore-table-reset',
|
|
546
|
+
onClick: () => {
|
|
547
|
+
setZoom(1);
|
|
548
|
+
setPreQuery('');
|
|
549
|
+
setQuery('');
|
|
550
|
+
setColumnModifiers({});
|
|
551
|
+
},
|
|
552
|
+
},
|
|
553
|
+
],
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
|
|
384
557
|
return finalActions;
|
|
385
558
|
}, [
|
|
386
559
|
preQuery,
|
|
@@ -388,10 +561,11 @@ const ReqoreTable = ({
|
|
|
388
561
|
actions,
|
|
389
562
|
filterable,
|
|
390
563
|
filterProps,
|
|
391
|
-
|
|
564
|
+
finalColumns,
|
|
392
565
|
zoomable,
|
|
393
566
|
zoom,
|
|
394
567
|
columnsList,
|
|
568
|
+
isScrolled,
|
|
395
569
|
]);
|
|
396
570
|
|
|
397
571
|
const badge = useMemo(() => {
|
|
@@ -408,12 +582,80 @@ const ReqoreTable = ({
|
|
|
408
582
|
return badgeList;
|
|
409
583
|
}, [transformedData, rest.badge]);
|
|
410
584
|
|
|
585
|
+
const refs = {
|
|
586
|
+
left: leftTableRef,
|
|
587
|
+
right: rightTableRef,
|
|
588
|
+
main: mainTableRef,
|
|
589
|
+
header: mainHeaderRef,
|
|
590
|
+
};
|
|
591
|
+
|
|
592
|
+
const columnsByType = useMemo(
|
|
593
|
+
() => ({
|
|
594
|
+
left: getColumnsByPinType(finalColumns, 'left'),
|
|
595
|
+
right: getColumnsByPinType(finalColumns, 'right'),
|
|
596
|
+
main: getColumnsByPinType(finalColumns, 'main'),
|
|
597
|
+
}),
|
|
598
|
+
[finalColumns]
|
|
599
|
+
);
|
|
600
|
+
|
|
601
|
+
const renderTable = (type: 'left' | 'main' | 'right' = 'main') => {
|
|
602
|
+
const tableColumns = columnsByType[type];
|
|
603
|
+
const isPinned = type === 'left' || type === 'right';
|
|
604
|
+
|
|
605
|
+
if (count(tableColumns) === 0) {
|
|
606
|
+
return null;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
return (
|
|
610
|
+
<StyledTableWrapper isPinned={isPinned}>
|
|
611
|
+
<ReqoreTableHeader
|
|
612
|
+
size={zoomToSize[zoom]}
|
|
613
|
+
columns={tableColumns}
|
|
614
|
+
scrollable={type === 'main'}
|
|
615
|
+
ref={type === 'main' ? mainHeaderRef : undefined}
|
|
616
|
+
bodyRef={mainTableRef}
|
|
617
|
+
onSortChange={handleSortChange}
|
|
618
|
+
heightAsGroup={hasGroupedColumns(finalColumns)}
|
|
619
|
+
sortData={_sort}
|
|
620
|
+
hasVerticalScroll={count(transformedData) * TABLE_SIZE_TO_PX[size] > height}
|
|
621
|
+
onColumnsUpdate={handleColumnsUpdate}
|
|
622
|
+
onFilterChange={(dataId: string, value: any) => {
|
|
623
|
+
handleColumnsUpdate(dataId, 'filter', value);
|
|
624
|
+
}}
|
|
625
|
+
component={headerCellComponent}
|
|
626
|
+
/>
|
|
627
|
+
{count(transformedData) === 0 ? null : (
|
|
628
|
+
<ReqoreTableBody
|
|
629
|
+
ref={refs[type]}
|
|
630
|
+
refs={refs}
|
|
631
|
+
type={type}
|
|
632
|
+
data={transformedData}
|
|
633
|
+
columns={tableColumns}
|
|
634
|
+
height={fill ? sizes.height : height}
|
|
635
|
+
selectable={selectable}
|
|
636
|
+
onSelectClick={handleSelectClick}
|
|
637
|
+
onRowClick={onRowClick}
|
|
638
|
+
onScrollChange={(isScrolled) => setIsScrolled(isScrolled)}
|
|
639
|
+
selected={_selected}
|
|
640
|
+
selectedRowIntent={selectedRowIntent}
|
|
641
|
+
size={zoomToSize[zoom]}
|
|
642
|
+
striped={striped}
|
|
643
|
+
flat={rest.flat}
|
|
644
|
+
rowComponent={rowComponent}
|
|
645
|
+
cellComponent={bodyCellComponent}
|
|
646
|
+
/>
|
|
647
|
+
)}
|
|
648
|
+
</StyledTableWrapper>
|
|
649
|
+
);
|
|
650
|
+
};
|
|
651
|
+
|
|
411
652
|
return (
|
|
412
653
|
<ReqorePanel
|
|
413
654
|
transparent
|
|
414
655
|
flat
|
|
415
656
|
padded={false}
|
|
416
657
|
contentStyle={{ display: 'flex', flexFlow: 'column', overflow: 'hidden' }}
|
|
658
|
+
responsiveActions={false}
|
|
417
659
|
{...rest}
|
|
418
660
|
size={wrapperSize}
|
|
419
661
|
actions={tableActions}
|
|
@@ -423,23 +665,11 @@ const ReqoreTable = ({
|
|
|
423
665
|
getContentRef={wrapperRef}
|
|
424
666
|
badge={badge}
|
|
425
667
|
>
|
|
426
|
-
<
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
sortData={_sort}
|
|
432
|
-
selectable={selectable}
|
|
433
|
-
selectedQuant={_selectedQuant}
|
|
434
|
-
onToggleSelectClick={handleToggleSelectClick}
|
|
435
|
-
hasVerticalScroll={count(transformedData) * TABLE_SIZE_TO_PX[size] > height}
|
|
436
|
-
selectToggleTooltip={selectToggleTooltip}
|
|
437
|
-
onColumnsUpdate={handleColumnsUpdate}
|
|
438
|
-
onFilterChange={(dataId: string, value: any) => {
|
|
439
|
-
handleColumnsUpdate(dataId, 'filter', value);
|
|
440
|
-
}}
|
|
441
|
-
component={headerCellComponent}
|
|
442
|
-
/>
|
|
668
|
+
<StyledTablesWrapper className='reqore-table-wrapper'>
|
|
669
|
+
{renderTable('left')}
|
|
670
|
+
{renderTable()}
|
|
671
|
+
{renderTable('right')}
|
|
672
|
+
</StyledTablesWrapper>
|
|
443
673
|
{count(transformedData) === 0 ? (
|
|
444
674
|
<>
|
|
445
675
|
<ReqoreVerticalSpacer height={10} />
|
|
@@ -447,24 +677,7 @@ const ReqoreTable = ({
|
|
|
447
677
|
{emptyMessage}
|
|
448
678
|
</ReqoreMessage>
|
|
449
679
|
</>
|
|
450
|
-
) :
|
|
451
|
-
<ReqoreTableBody
|
|
452
|
-
data={transformedData}
|
|
453
|
-
columns={internalColumns}
|
|
454
|
-
setLeftScroll={setLeftScroll}
|
|
455
|
-
height={fill ? sizes.height : height}
|
|
456
|
-
selectable={selectable}
|
|
457
|
-
onSelectClick={handleSelectClick}
|
|
458
|
-
onRowClick={onRowClick}
|
|
459
|
-
selected={_selected}
|
|
460
|
-
selectedRowIntent={selectedRowIntent}
|
|
461
|
-
size={zoomToSize[zoom]}
|
|
462
|
-
striped={striped}
|
|
463
|
-
flat={rest.flat}
|
|
464
|
-
rowComponent={rowComponent}
|
|
465
|
-
cellComponent={bodyCellComponent}
|
|
466
|
-
/>
|
|
467
|
-
)}
|
|
680
|
+
) : null}
|
|
468
681
|
</ReqorePanel>
|
|
469
682
|
);
|
|
470
683
|
};
|
|
@@ -2,24 +2,18 @@
|
|
|
2
2
|
import { isFunction, isString } from 'lodash';
|
|
3
3
|
import React, { ReactElement, useState } from 'react';
|
|
4
4
|
import styled, { css } from 'styled-components';
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
IReqoreTableData,
|
|
8
|
-
IReqoreTableRowClick,
|
|
9
|
-
TReqoreTableColumnContent,
|
|
10
|
-
} from '.';
|
|
11
|
-
import { ReqorePopover } from '../..';
|
|
5
|
+
import { IReqoreTableColumn, IReqoreTableData, IReqoreTableRowClick } from '.';
|
|
6
|
+
import { ReqoreButton, ReqoreControlGroup, ReqorePopover } from '../..';
|
|
12
7
|
import { SIZE_TO_PX, TSizes } from '../../constants/sizes';
|
|
13
8
|
import { IReqoreTheme, TReqoreIntent } from '../../constants/theme';
|
|
14
9
|
import { IReqoreTooltip } from '../../types/global';
|
|
15
10
|
import { TReqoreHexColor } from '../Effect';
|
|
16
11
|
import { ReqoreH4 } from '../Header';
|
|
17
|
-
import ReqoreIcon from '../Icon';
|
|
18
12
|
import { ReqoreP } from '../Paragraph';
|
|
19
13
|
import ReqoreTag from '../Tag';
|
|
20
14
|
import { TimeAgo } from '../TimeAgo';
|
|
21
15
|
import { IReqoreCustomTableBodyCell, ReqoreTableBodyCell } from './cell';
|
|
22
|
-
import {
|
|
16
|
+
import { getOnlyShownColumns } from './helpers';
|
|
23
17
|
|
|
24
18
|
export interface IReqoreTableRowOptions {
|
|
25
19
|
columns: IReqoreTableColumn[];
|
|
@@ -62,8 +56,8 @@ export const StyledTableRow = styled.div<IReqoreTableRowStyle>`
|
|
|
62
56
|
|
|
63
57
|
export interface IReqoreTableCellStyle {
|
|
64
58
|
width?: number;
|
|
65
|
-
grow?: number;
|
|
66
59
|
theme?: IReqoreTheme;
|
|
60
|
+
grow: 1 | 2 | 3 | 4;
|
|
67
61
|
align?: 'center' | 'left' | 'right';
|
|
68
62
|
intent?: TReqoreIntent;
|
|
69
63
|
interactive?: boolean;
|
|
@@ -76,6 +70,7 @@ export interface IReqoreTableCellStyle {
|
|
|
76
70
|
selectedIntent?: TReqoreIntent;
|
|
77
71
|
even?: boolean;
|
|
78
72
|
striped?: boolean;
|
|
73
|
+
padded?: IReqoreTableColumn['cell']['padded'];
|
|
79
74
|
}
|
|
80
75
|
|
|
81
76
|
const ReqoreTableRow = ({
|
|
@@ -88,7 +83,7 @@ const ReqoreTableRow = ({
|
|
|
88
83
|
onRowClick,
|
|
89
84
|
striped,
|
|
90
85
|
size,
|
|
91
|
-
selectedRowIntent
|
|
86
|
+
selectedRowIntent,
|
|
92
87
|
flat,
|
|
93
88
|
cellComponent,
|
|
94
89
|
rowComponent,
|
|
@@ -103,14 +98,38 @@ const ReqoreTableRow = ({
|
|
|
103
98
|
const RowComponent = rowComponent || StyledTableRow;
|
|
104
99
|
|
|
105
100
|
const renderContent = (
|
|
106
|
-
|
|
101
|
+
cell: IReqoreTableColumn['cell'],
|
|
107
102
|
data: any,
|
|
108
|
-
dataId: string
|
|
103
|
+
dataId: string,
|
|
104
|
+
align?: 'center' | 'left' | 'right'
|
|
109
105
|
): ReactElement<any, any> => {
|
|
106
|
+
if (cell?.actions) {
|
|
107
|
+
return (
|
|
108
|
+
<ReqoreControlGroup size={size} stack fill fluid style={{ height: '100%' }} rounded={false}>
|
|
109
|
+
{cell.actions(data).map((action, index) => (
|
|
110
|
+
<ReqoreButton
|
|
111
|
+
key={index}
|
|
112
|
+
rounded={false}
|
|
113
|
+
iconsAlign={align === 'center' ? 'center' : 'sides'}
|
|
114
|
+
textAlign={align}
|
|
115
|
+
{...action}
|
|
116
|
+
onClick={(e) => {
|
|
117
|
+
e.stopPropagation();
|
|
118
|
+
|
|
119
|
+
action.onClick?.(e);
|
|
120
|
+
}}
|
|
121
|
+
/>
|
|
122
|
+
))}
|
|
123
|
+
</ReqoreControlGroup>
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const content = cell?.content;
|
|
128
|
+
|
|
110
129
|
if (isFunction(content)) {
|
|
111
130
|
const Content = content;
|
|
112
131
|
|
|
113
|
-
return <Content {...data} />;
|
|
132
|
+
return <Content {...data} _size={size} _dataId={dataId} />;
|
|
114
133
|
}
|
|
115
134
|
|
|
116
135
|
if (isString(content)) {
|
|
@@ -155,7 +174,7 @@ const ReqoreTableRow = ({
|
|
|
155
174
|
|
|
156
175
|
const renderCells = (columns: IReqoreTableColumn[], data: IReqoreTableData) =>
|
|
157
176
|
getOnlyShownColumns(columns).map(
|
|
158
|
-
({ width, resizedWidth, grow, dataId, cell, header, align, intent }) => {
|
|
177
|
+
({ width, minWidth, maxWidth, resizedWidth, grow, dataId, cell, header, align, intent }) => {
|
|
159
178
|
if (header.columns) {
|
|
160
179
|
return renderCells(header.columns, data);
|
|
161
180
|
}
|
|
@@ -177,10 +196,13 @@ const ReqoreTableRow = ({
|
|
|
177
196
|
componentProps={
|
|
178
197
|
{
|
|
179
198
|
width: resizedWidth || width,
|
|
199
|
+
minWidth,
|
|
200
|
+
maxWidth,
|
|
180
201
|
grow,
|
|
181
202
|
align,
|
|
182
203
|
size,
|
|
183
204
|
striped,
|
|
205
|
+
padded: cell?.padded,
|
|
184
206
|
disabled: data[index]._disabled,
|
|
185
207
|
selected: !!isSelected,
|
|
186
208
|
selectedIntent: selectedRowIntent,
|
|
@@ -207,7 +229,7 @@ const ReqoreTableRow = ({
|
|
|
207
229
|
}
|
|
208
230
|
{...tooltip}
|
|
209
231
|
>
|
|
210
|
-
{renderContent(cell
|
|
232
|
+
{renderContent(cell, data[index], dataId, align)}
|
|
211
233
|
</ReqorePopover>
|
|
212
234
|
);
|
|
213
235
|
}
|
|
@@ -228,45 +250,6 @@ const ReqoreTableRow = ({
|
|
|
228
250
|
setIsHovered(false);
|
|
229
251
|
}}
|
|
230
252
|
>
|
|
231
|
-
{selectable && (
|
|
232
|
-
<CellComponent
|
|
233
|
-
align='center'
|
|
234
|
-
width={calculateMinimumCellWidth(50, size)}
|
|
235
|
-
className='reqore-table-cell'
|
|
236
|
-
{...{
|
|
237
|
-
size,
|
|
238
|
-
striped,
|
|
239
|
-
disabled: data[index]._disabled,
|
|
240
|
-
selected: !!isSelected,
|
|
241
|
-
selectedIntent: selectedRowIntent,
|
|
242
|
-
flat,
|
|
243
|
-
even: index % 2 === 0 ? true : false,
|
|
244
|
-
intent: data[index]._intent,
|
|
245
|
-
hovered: isHovered,
|
|
246
|
-
interactiveCell: data[index]._selectId,
|
|
247
|
-
}}
|
|
248
|
-
onClick={
|
|
249
|
-
data[index]._selectId
|
|
250
|
-
? (e: React.MouseEvent<HTMLDivElement>) => {
|
|
251
|
-
e.stopPropagation();
|
|
252
|
-
onSelectClick(data[index]._selectId);
|
|
253
|
-
}
|
|
254
|
-
: undefined
|
|
255
|
-
}
|
|
256
|
-
>
|
|
257
|
-
<ReqoreIcon
|
|
258
|
-
icon={
|
|
259
|
-
!data[index]._selectId
|
|
260
|
-
? 'Forbid2Line'
|
|
261
|
-
: isSelected
|
|
262
|
-
? 'CheckboxCircleLine'
|
|
263
|
-
: 'CheckboxBlankCircleLine'
|
|
264
|
-
}
|
|
265
|
-
size={size}
|
|
266
|
-
style={{ opacity: !data[index]._selectId || !isSelected ? 0.4 : 1 }}
|
|
267
|
-
/>
|
|
268
|
-
</CellComponent>
|
|
269
|
-
)}
|
|
270
253
|
{renderCells(columns, data)}
|
|
271
254
|
</RowComponent>
|
|
272
255
|
);
|
package/src/constants/sizes.ts
CHANGED
|
@@ -11,6 +11,23 @@ export const ReqoreSizes = {
|
|
|
11
11
|
|
|
12
12
|
export const SIZES = ['tiny', 'small', 'normal', 'big', 'huge'] as const;
|
|
13
13
|
|
|
14
|
+
export const SIZE_TO_MODIFIER = {
|
|
15
|
+
tiny: 0.6,
|
|
16
|
+
small: 0.8,
|
|
17
|
+
normal: 1,
|
|
18
|
+
big: 1.2,
|
|
19
|
+
huge: 1.4,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const LINE_SIZE_TO_NUMBER = {
|
|
23
|
+
none: 0,
|
|
24
|
+
tiny: 1,
|
|
25
|
+
small: 1,
|
|
26
|
+
normal: 1.5,
|
|
27
|
+
big: 2,
|
|
28
|
+
huge: 3,
|
|
29
|
+
};
|
|
30
|
+
|
|
14
31
|
export const SIZE_TO_NUMBER = {
|
|
15
32
|
none: 0,
|
|
16
33
|
tiny: 1,
|
|
@@ -16,9 +16,6 @@ export default {
|
|
|
16
16
|
},
|
|
17
17
|
...SizeArg,
|
|
18
18
|
},
|
|
19
|
-
parameters: {
|
|
20
|
-
jest: ['breadcrumbs.test.tsx'],
|
|
21
|
-
},
|
|
22
19
|
} as ComponentMeta<typeof ReqoreBreadcrumbs & { withTabs?: boolean }>;
|
|
23
20
|
|
|
24
21
|
const Template: ComponentStory<typeof ReqoreBreadcrumbs & { withTabs?: boolean }> = (
|