@buerokratt-ria/common-gui-components 0.0.59 → 0.0.61
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 +12 -0
- package/package.json +1 -1
- package/templates/history-page/src/History.scss +29 -1
- package/templates/history-page/src/components/HeaderCombobox/index.tsx +6 -0
- package/templates/history-page/src/constants.ts +1 -0
- package/templates/history-page/src/index.tsx +112 -106
- package/translations/en/common.json +1 -0
- package/translations/et/common.json +1 -0
- package/ui-components/DataTable/DataTable.scss +8 -0
- package/ui-components/DataTable/index.tsx +61 -56
- package/ui-components/FormElements/FormCombobox/FormCombobox.scss +44 -2
- package/ui-components/FormElements/FormCombobox/index.tsx +204 -58
- package/ui-components/FormElements/FormSelect/FormMultiselect.tsx +108 -36
- package/ui-components/FormElements/FormSelect/FormSelect.scss +32 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,18 @@ All changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## Template [MajorVersion.MediterraneanVersion.MinorVersion] - DD-MM-YYYY
|
|
6
6
|
|
|
7
|
+
|
|
8
|
+
## [0.0.61] - 11.06.2026
|
|
9
|
+
|
|
10
|
+
- Removed redundant scroll from the History table
|
|
11
|
+
- Added Apply action to the History table header multi-option filter
|
|
12
|
+
- Made the History table header sticky
|
|
13
|
+
|
|
14
|
+
## [0.0.60] - 09.06.2026
|
|
15
|
+
|
|
16
|
+
- History table: theme, follow up, quality sorting
|
|
17
|
+
- History table: header filter positioning
|
|
18
|
+
|
|
7
19
|
## [0.0.59] - 05.06.2026
|
|
8
20
|
|
|
9
21
|
- Quality measurements in chat history view
|
package/package.json
CHANGED
|
@@ -69,9 +69,37 @@
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
.card-wrapper {
|
|
72
|
+
display: flex;
|
|
73
|
+
flex-direction: column;
|
|
72
74
|
flex: 1;
|
|
73
|
-
|
|
75
|
+
min-height: 0;
|
|
76
|
+
overflow: hidden;
|
|
74
77
|
transition: flex 0.3s ease;
|
|
78
|
+
|
|
79
|
+
.card {
|
|
80
|
+
box-sizing: border-box;
|
|
81
|
+
display: flex;
|
|
82
|
+
flex: 1;
|
|
83
|
+
flex-direction: column;
|
|
84
|
+
max-height: none;
|
|
85
|
+
min-height: 0;
|
|
86
|
+
overflow: hidden;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.card__body {
|
|
90
|
+
display: flex;
|
|
91
|
+
flex: 1;
|
|
92
|
+
flex-direction: column;
|
|
93
|
+
min-height: 0;
|
|
94
|
+
overflow: hidden;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.data-table__scrollWrapper {
|
|
98
|
+
flex: 1;
|
|
99
|
+
max-height: none;
|
|
100
|
+
min-height: 0;
|
|
101
|
+
overflow: auto;
|
|
102
|
+
}
|
|
75
103
|
}
|
|
76
104
|
|
|
77
105
|
.drawer-container {
|
|
@@ -6,6 +6,7 @@ type HeaderComboboxBaseProps = {
|
|
|
6
6
|
readonly label: string;
|
|
7
7
|
readonly options?: ComponentProps<typeof FormCombobox>['options'];
|
|
8
8
|
readonly isSearchEnabled?: ComponentProps<typeof FormCombobox>['isSearchEnabled'];
|
|
9
|
+
readonly allOptionValue?: ComponentProps<typeof FormCombobox>['allOptionValue'];
|
|
9
10
|
};
|
|
10
11
|
|
|
11
12
|
type HeaderComboboxSingleProps = HeaderComboboxBaseProps & {
|
|
@@ -18,6 +19,7 @@ type HeaderComboboxMultipleProps = HeaderComboboxBaseProps & {
|
|
|
18
19
|
readonly multiple?: true;
|
|
19
20
|
readonly value?: string[];
|
|
20
21
|
readonly onChange: (value: string[]) => void;
|
|
22
|
+
readonly isApplyBtnVisible?: boolean;
|
|
21
23
|
};
|
|
22
24
|
|
|
23
25
|
type HeaderComboboxProps = HeaderComboboxSingleProps | HeaderComboboxMultipleProps;
|
|
@@ -27,6 +29,7 @@ const HeaderCombobox: FC<HeaderComboboxProps> = (props) => {
|
|
|
27
29
|
label,
|
|
28
30
|
options = [],
|
|
29
31
|
isSearchEnabled = true,
|
|
32
|
+
allOptionValue,
|
|
30
33
|
} = props;
|
|
31
34
|
const sharedProps = {
|
|
32
35
|
hideInputStyle: true,
|
|
@@ -36,6 +39,8 @@ const HeaderCombobox: FC<HeaderComboboxProps> = (props) => {
|
|
|
36
39
|
searchPlaceholder: label,
|
|
37
40
|
options,
|
|
38
41
|
isSearchEnabled,
|
|
42
|
+
isMenuPortaled: true,
|
|
43
|
+
allOptionValue,
|
|
39
44
|
};
|
|
40
45
|
|
|
41
46
|
return (
|
|
@@ -57,6 +62,7 @@ const HeaderCombobox: FC<HeaderComboboxProps> = (props) => {
|
|
|
57
62
|
multiple={true}
|
|
58
63
|
value={props.value}
|
|
59
64
|
onChange={props.onChange}
|
|
65
|
+
isApplyBtnVisible={props.isApplyBtnVisible}
|
|
60
66
|
/>
|
|
61
67
|
)}
|
|
62
68
|
</span>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const ALL_COLUMNS_VALUE = '__all__';
|
|
@@ -16,9 +16,9 @@ import {
|
|
|
16
16
|
Dialog,
|
|
17
17
|
Drawer,
|
|
18
18
|
FormCheckbox,
|
|
19
|
+
FormCombobox,
|
|
19
20
|
FormDatepicker,
|
|
20
21
|
FormInput,
|
|
21
|
-
FormMultiselect,
|
|
22
22
|
HistoricalChat,
|
|
23
23
|
Icon,
|
|
24
24
|
Tooltip,
|
|
@@ -40,6 +40,7 @@ import {StoreState} from "../../../store";
|
|
|
40
40
|
import {saveFile} from "../../../services/file";
|
|
41
41
|
import {ChatMetadataPanel, HeaderCombobox, QualitySettings, SelectedFilterTags} from './components';
|
|
42
42
|
import { CharMeasurementType } from './types';
|
|
43
|
+
import { ALL_COLUMNS_VALUE } from './constants';
|
|
43
44
|
|
|
44
45
|
type HistoryProps = {
|
|
45
46
|
user: UserInfo | null;
|
|
@@ -162,11 +163,15 @@ const formatChatAnalysisCell = (
|
|
|
162
163
|
return value.join(', ');
|
|
163
164
|
};
|
|
164
165
|
|
|
165
|
-
|
|
166
|
-
|
|
166
|
+
// Boolean -> truthy values before falsy
|
|
167
|
+
// For other columns -> desc before asc - populated before empty
|
|
168
|
+
const NON_EMPTY_FIRST_SORT_COLUMN_IDS = new Set([
|
|
167
169
|
'authenticatedPerson',
|
|
168
170
|
'istest',
|
|
169
171
|
'isPreserve',
|
|
172
|
+
'followUpStatus',
|
|
173
|
+
'responseQuality',
|
|
174
|
+
'theme',
|
|
170
175
|
]);
|
|
171
176
|
const CHAT_STATUSES = [
|
|
172
177
|
CHAT_EVENTS.ACCEPTED,
|
|
@@ -184,7 +189,7 @@ const getEndedChatsSortBy = (sorting: SortingState) => {
|
|
|
184
189
|
}
|
|
185
190
|
|
|
186
191
|
const [sortingObject] = sorting;
|
|
187
|
-
const sortType =
|
|
192
|
+
const sortType = NON_EMPTY_FIRST_SORT_COLUMN_IDS.has(sortingObject.id)
|
|
188
193
|
? sortingObject.desc ? 'asc' : 'desc'
|
|
189
194
|
: sortingObject.desc ? 'desc' : 'asc';
|
|
190
195
|
|
|
@@ -431,7 +436,6 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
|
|
|
431
436
|
const isChatAnalysisEnabled = useMemo(() => {
|
|
432
437
|
return qualitySettingsConfigQuery.data?.chatAnalysisEnabled ?? false;
|
|
433
438
|
}, [qualitySettingsConfigQuery.data]);
|
|
434
|
-
console.log("IS CHAT ANALYSIS ENABLED", isChatAnalysisEnabled);
|
|
435
439
|
|
|
436
440
|
const getAllEndedChats = useMutation({
|
|
437
441
|
mutationFn: (data: {
|
|
@@ -575,21 +579,6 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
|
|
|
575
579
|
return realSelectedColumns;
|
|
576
580
|
};
|
|
577
581
|
|
|
578
|
-
const normalizeSelectedColumns = (selection: string[]) => {
|
|
579
|
-
const currentAllSelected = selectedColumns.includes(ALL_COLUMNS_VALUE) || areAllColumnsSelected(selectedColumns);
|
|
580
|
-
const nextAllSelected = selection.includes(ALL_COLUMNS_VALUE);
|
|
581
|
-
|
|
582
|
-
if (nextAllSelected && !currentAllSelected) {
|
|
583
|
-
return [ALL_COLUMNS_VALUE, ...getAllColumnValues()];
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
if (!nextAllSelected && currentAllSelected) {
|
|
587
|
-
return [];
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
return getUiSelectedColumns(selection);
|
|
591
|
-
};
|
|
592
|
-
|
|
593
582
|
const chatStatusChangeMutation = useMutation({
|
|
594
583
|
mutationFn: async (data: { chatId: string | number; event: string }) => {
|
|
595
584
|
const changeableTo = [
|
|
@@ -1263,10 +1252,12 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
|
|
|
1263
1252
|
label={t('chat.history.csaName')}
|
|
1264
1253
|
options={customerSupportAgentsQuery.data ?? []}
|
|
1265
1254
|
value={csaIdCodesFilter}
|
|
1255
|
+
allOptionValue={ALL_COLUMNS_VALUE}
|
|
1266
1256
|
onChange={(value) => {
|
|
1267
1257
|
const normalizedValue = normalizeCsaFilterValues(value);
|
|
1268
1258
|
tableHeaderForm.setValue('csaIdCodesFilter', normalizedValue);
|
|
1269
1259
|
}}
|
|
1260
|
+
isApplyBtnVisible
|
|
1270
1261
|
/>
|
|
1271
1262
|
);
|
|
1272
1263
|
},
|
|
@@ -1360,6 +1351,7 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
|
|
|
1360
1351
|
label={t('chat.history.rating') ?? ''}
|
|
1361
1352
|
options={ratingOptions}
|
|
1362
1353
|
value={feedbackRatings}
|
|
1354
|
+
allOptionValue={ALL_COLUMNS_VALUE}
|
|
1363
1355
|
onChange={(value) => {
|
|
1364
1356
|
setTableHeaderValue(
|
|
1365
1357
|
'feedbackRatings',
|
|
@@ -1370,6 +1362,7 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
|
|
|
1370
1362
|
)
|
|
1371
1363
|
);
|
|
1372
1364
|
}}
|
|
1365
|
+
isApplyBtnVisible
|
|
1373
1366
|
/>
|
|
1374
1367
|
);
|
|
1375
1368
|
},
|
|
@@ -1394,6 +1387,7 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
|
|
|
1394
1387
|
label={t('global.status') ?? ''}
|
|
1395
1388
|
options={statusOptions}
|
|
1396
1389
|
value={status}
|
|
1390
|
+
allOptionValue={ALL_COLUMNS_VALUE}
|
|
1397
1391
|
onChange={(value) => {
|
|
1398
1392
|
setTableHeaderValue(
|
|
1399
1393
|
'status',
|
|
@@ -1404,6 +1398,7 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
|
|
|
1404
1398
|
)
|
|
1405
1399
|
);
|
|
1406
1400
|
}}
|
|
1401
|
+
isApplyBtnVisible
|
|
1407
1402
|
isSearchEnabled={true}
|
|
1408
1403
|
/>
|
|
1409
1404
|
);
|
|
@@ -1442,12 +1437,14 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
|
|
|
1442
1437
|
label={t('chat.history.www') ?? ''}
|
|
1443
1438
|
value={domains}
|
|
1444
1439
|
options={domainOptions}
|
|
1440
|
+
allOptionValue={ALL_COLUMNS_VALUE}
|
|
1445
1441
|
onChange={(value) => {
|
|
1446
1442
|
setTableHeaderValue(
|
|
1447
1443
|
'domains',
|
|
1448
1444
|
normalizeAllOptionFilterValues(value, domains, currentDomains)
|
|
1449
1445
|
);
|
|
1450
1446
|
}}
|
|
1447
|
+
isApplyBtnVisible
|
|
1451
1448
|
/>
|
|
1452
1449
|
);
|
|
1453
1450
|
},
|
|
@@ -1455,87 +1452,93 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
|
|
|
1455
1452
|
sortDescFirst: false,
|
|
1456
1453
|
}),
|
|
1457
1454
|
...isChatAnalysisEnabled ? [
|
|
1458
|
-
columnHelper.
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
label={t('chat.history.theme')}
|
|
1463
|
-
options={themeOptions}
|
|
1464
|
-
value={theme}
|
|
1465
|
-
onChange={(value) => {
|
|
1466
|
-
setTableHeaderValue(
|
|
1467
|
-
'theme',
|
|
1468
|
-
normalizeAllOptionFilterValues(
|
|
1469
|
-
value,
|
|
1470
|
-
theme,
|
|
1471
|
-
getAllStringFilterValues(realThemeOptions)
|
|
1472
|
-
)
|
|
1473
|
-
);
|
|
1474
|
-
}}
|
|
1475
|
-
/>
|
|
1455
|
+
columnHelper.accessor(
|
|
1456
|
+
(row) => formatChatAnalysisCell(
|
|
1457
|
+
row.theme,
|
|
1458
|
+
t('chat.quality.selectionEmptied')
|
|
1476
1459
|
),
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1460
|
+
{
|
|
1461
|
+
id: 'theme',
|
|
1462
|
+
header: () => (
|
|
1463
|
+
<HeaderCombobox
|
|
1464
|
+
label={t('chat.history.theme')}
|
|
1465
|
+
options={themeOptions}
|
|
1466
|
+
value={theme}
|
|
1467
|
+
allOptionValue={ALL_COLUMNS_VALUE}
|
|
1468
|
+
onChange={(value) => {
|
|
1469
|
+
setTableHeaderValue(
|
|
1470
|
+
'theme',
|
|
1471
|
+
normalizeAllOptionFilterValues(
|
|
1472
|
+
value,
|
|
1473
|
+
theme,
|
|
1474
|
+
getAllStringFilterValues(realThemeOptions)
|
|
1475
|
+
)
|
|
1476
|
+
);
|
|
1477
|
+
}}
|
|
1478
|
+
isApplyBtnVisible
|
|
1479
|
+
/>
|
|
1480
|
+
),
|
|
1481
|
+
enableSorting: true,
|
|
1482
|
+
}
|
|
1483
|
+
),
|
|
1484
|
+
columnHelper.accessor(
|
|
1485
|
+
(row) => formatChatAnalysisCell(
|
|
1486
|
+
row.responseQuality,
|
|
1487
|
+
t('chat.quality.selectionEmptied')
|
|
1503
1488
|
),
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1489
|
+
{
|
|
1490
|
+
id: 'responseQuality',
|
|
1491
|
+
header: () => (
|
|
1492
|
+
<HeaderCombobox
|
|
1493
|
+
label={t('chat.history.responseQuality')}
|
|
1494
|
+
options={responseQualityOptions}
|
|
1495
|
+
value={responseQuality}
|
|
1496
|
+
allOptionValue={ALL_COLUMNS_VALUE}
|
|
1497
|
+
onChange={(value) => {
|
|
1498
|
+
setTableHeaderValue(
|
|
1499
|
+
'responseQuality',
|
|
1500
|
+
normalizeAllOptionFilterValues(
|
|
1501
|
+
value,
|
|
1502
|
+
responseQuality,
|
|
1503
|
+
getAllStringFilterValues(realResponseQualityOptions)
|
|
1504
|
+
)
|
|
1505
|
+
);
|
|
1506
|
+
}}
|
|
1507
|
+
isApplyBtnVisible
|
|
1508
|
+
/>
|
|
1509
|
+
),
|
|
1510
|
+
enableSorting: true,
|
|
1511
|
+
}
|
|
1512
|
+
),
|
|
1513
|
+
columnHelper.accessor(
|
|
1514
|
+
(row) => formatChatAnalysisCell(
|
|
1515
|
+
row.followUpStatus,
|
|
1516
|
+
t('chat.quality.selectionEmptied')
|
|
1530
1517
|
),
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1518
|
+
{
|
|
1519
|
+
id: 'followUpStatus',
|
|
1520
|
+
header: () => (
|
|
1521
|
+
<HeaderCombobox
|
|
1522
|
+
label={t('chat.history.followUpStatus')}
|
|
1523
|
+
options={followUpStatusOptions}
|
|
1524
|
+
value={followUpStatus}
|
|
1525
|
+
allOptionValue={ALL_COLUMNS_VALUE}
|
|
1526
|
+
onChange={(value) => {
|
|
1527
|
+
setTableHeaderValue(
|
|
1528
|
+
'followUpStatus',
|
|
1529
|
+
normalizeAllOptionFilterValues(
|
|
1530
|
+
value,
|
|
1531
|
+
followUpStatus,
|
|
1532
|
+
getAllStringFilterValues(realFollowUpStatusOptions)
|
|
1533
|
+
)
|
|
1534
|
+
);
|
|
1535
|
+
}}
|
|
1536
|
+
isApplyBtnVisible
|
|
1537
|
+
/>
|
|
1538
|
+
),
|
|
1539
|
+
enableSorting: true,
|
|
1540
|
+
}
|
|
1541
|
+
),
|
|
1539
1542
|
] : [],
|
|
1540
1543
|
columnHelper.display({
|
|
1541
1544
|
id: 'detail',
|
|
@@ -2052,25 +2055,27 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
|
|
|
2052
2055
|
</>
|
|
2053
2056
|
)}
|
|
2054
2057
|
<Track style={{width: '240px'}}>
|
|
2055
|
-
<
|
|
2058
|
+
<FormCombobox
|
|
2056
2059
|
key={counterKey}
|
|
2057
2060
|
name="visibleColumns"
|
|
2058
2061
|
label={t('')}
|
|
2059
2062
|
placeholder={t('chat.history.chosenColumn')}
|
|
2060
2063
|
options={visibleColumnOptions}
|
|
2061
|
-
|
|
2062
|
-
selectedColumns.includes(o.value)
|
|
2063
|
-
)}
|
|
2064
|
+
value={selectedColumns}
|
|
2064
2065
|
selectedOptionsCount={getRealSelectedColumns(selectedColumns).length}
|
|
2065
|
-
|
|
2066
|
-
|
|
2066
|
+
multiple={true}
|
|
2067
|
+
allOptionValue={ALL_COLUMNS_VALUE}
|
|
2068
|
+
direction="down"
|
|
2069
|
+
onChange={(selection) => {
|
|
2070
|
+
const columns = getUiSelectedColumns(selection);
|
|
2067
2071
|
setSelectedColumns(columns);
|
|
2068
2072
|
setCounterKey(prev => prev + 1);
|
|
2069
2073
|
updatePagePreferences.mutate({
|
|
2070
2074
|
page_results: pagination.pageSize,
|
|
2071
|
-
selected_columns: getRealSelectedColumns(columns)
|
|
2075
|
+
selected_columns: getRealSelectedColumns(columns),
|
|
2072
2076
|
})
|
|
2073
2077
|
}}
|
|
2078
|
+
isApplyBtnVisible
|
|
2074
2079
|
/>
|
|
2075
2080
|
</Track>
|
|
2076
2081
|
</Track>
|
|
@@ -2100,12 +2105,13 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
|
|
|
2100
2105
|
onRemove={removeSelectedFilterTag}
|
|
2101
2106
|
onClearFiltersClick={onClearFilersClick}
|
|
2102
2107
|
/>
|
|
2103
|
-
<div className="card-drawer-container"
|
|
2108
|
+
<div className="card-drawer-container">
|
|
2104
2109
|
<div className="card-wrapper">
|
|
2105
2110
|
<Card>
|
|
2106
2111
|
<DataTable
|
|
2107
2112
|
data={filteredEndedChatsList}
|
|
2108
2113
|
sortable
|
|
2114
|
+
stickyHeader
|
|
2109
2115
|
columns={getFilteredColumns()}
|
|
2110
2116
|
selectedRow={(row) => row.original.id === selectedChat?.id}
|
|
2111
2117
|
pagination={pagination}
|
|
@@ -30,6 +30,14 @@
|
|
|
30
30
|
position: relative;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
&--sticky-header {
|
|
34
|
+
th {
|
|
35
|
+
background-color: get-color(white);
|
|
36
|
+
border-bottom-color: transparent;
|
|
37
|
+
box-shadow: inset 0 -1px 0 get-color(black-coral-10);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
33
41
|
td {
|
|
34
42
|
padding: 12px 24px 12px 16px;
|
|
35
43
|
border-bottom: 1px solid get-color(black-coral-2);
|
|
@@ -55,6 +55,7 @@ type DataTableProps = {
|
|
|
55
55
|
pagesCount?: number;
|
|
56
56
|
meta?: TableMeta<any>;
|
|
57
57
|
selectedRow?: (row: Row<any>) => boolean;
|
|
58
|
+
stickyHeader?: boolean;
|
|
58
59
|
totalCountLabel?: string | null;
|
|
59
60
|
};
|
|
60
61
|
|
|
@@ -116,6 +117,7 @@ const DataTable: FC<DataTableProps> = ({
|
|
|
116
117
|
pagesCount,
|
|
117
118
|
meta,
|
|
118
119
|
selectedRow,
|
|
120
|
+
stickyHeader,
|
|
119
121
|
totalCountLabel,
|
|
120
122
|
}) => {
|
|
121
123
|
const id = useId();
|
|
@@ -189,69 +191,72 @@ const DataTable: FC<DataTableProps> = ({
|
|
|
189
191
|
return (
|
|
190
192
|
<>
|
|
191
193
|
<div className="data-table__scrollWrapper">
|
|
192
|
-
<table className=
|
|
194
|
+
<table className={clsx('data-table', stickyHeader && 'data-table--sticky-header')}>
|
|
193
195
|
{!disableHead && (
|
|
194
196
|
<thead>
|
|
195
197
|
{table.getHeaderGroups().map((headerGroup) => (
|
|
196
198
|
<tr key={headerGroup.id}>
|
|
197
|
-
{headerGroup.headers.map((header) =>
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
:
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
199
|
+
{headerGroup.headers.map((header) => {
|
|
200
|
+
const stickyColumn = header.column.columnDef.meta?.sticky;
|
|
201
|
+
|
|
202
|
+
return (
|
|
203
|
+
<th
|
|
204
|
+
key={header.id}
|
|
205
|
+
style={{
|
|
206
|
+
width: header.column.columnDef.meta?.size,
|
|
207
|
+
position:
|
|
208
|
+
stickyHeader || stickyColumn ? 'sticky' : undefined,
|
|
209
|
+
top: stickyHeader ? 0 : undefined,
|
|
210
|
+
left:
|
|
211
|
+
stickyColumn === 'left'
|
|
212
|
+
? `${header.column.getAfter('left') * 0.675}px`
|
|
213
|
+
: undefined,
|
|
214
|
+
right:
|
|
215
|
+
stickyColumn === 'right'
|
|
216
|
+
? `${header.column.getAfter('right') * 0.675}px`
|
|
217
|
+
: undefined,
|
|
218
|
+
zIndex: stickyHeader ? (stickyColumn ? 3 : 1) : stickyColumn ? 1 : 0,
|
|
219
|
+
}}
|
|
220
|
+
>
|
|
221
|
+
{header.isPlaceholder ? null : (
|
|
222
|
+
<Track gap={8}>
|
|
223
|
+
{sortable && header.column.getCanSort() && (
|
|
224
|
+
<button
|
|
225
|
+
onClick={header.column.getToggleSortingHandler()}
|
|
226
|
+
>
|
|
227
|
+
{{
|
|
228
|
+
asc: (
|
|
229
|
+
<Icon
|
|
230
|
+
icon={<MdExpandMore fontSize={20} />}
|
|
231
|
+
size="medium"
|
|
232
|
+
/>
|
|
233
|
+
),
|
|
234
|
+
desc: (
|
|
235
|
+
<Icon
|
|
236
|
+
icon={<MdExpandLess fontSize={20} />}
|
|
237
|
+
size="medium"
|
|
238
|
+
/>
|
|
239
|
+
),
|
|
240
|
+
}[header.column.getIsSorted() as string] ?? (
|
|
231
241
|
<Icon
|
|
232
|
-
icon={<
|
|
242
|
+
icon={<MdUnfoldMore fontSize={22} />}
|
|
233
243
|
size="medium"
|
|
234
244
|
/>
|
|
235
|
-
)
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
)}
|
|
251
|
-
</Track>
|
|
252
|
-
)}
|
|
253
|
-
</th>
|
|
254
|
-
))}
|
|
245
|
+
)}
|
|
246
|
+
</button>
|
|
247
|
+
)}
|
|
248
|
+
{flexRender(
|
|
249
|
+
header.column.columnDef.header,
|
|
250
|
+
header.getContext()
|
|
251
|
+
)}
|
|
252
|
+
{filterable && header.column.getCanFilter() && (
|
|
253
|
+
<Filter column={header.column} table={table} />
|
|
254
|
+
)}
|
|
255
|
+
</Track>
|
|
256
|
+
)}
|
|
257
|
+
</th>
|
|
258
|
+
);
|
|
259
|
+
})}
|
|
255
260
|
</tr>
|
|
256
261
|
))}
|
|
257
262
|
</thead>
|