@buerokratt-ria/common-gui-components 0.0.51 → 0.0.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,17 @@ 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
+ ## [0.0.53] - 06.05.2026
8
+
9
+ - Removed the Chosen CSA filter from chat history.
10
+ - Added Clear filters action for chat history filters.
11
+ - Added Choose all / Vali kõik option to the chosen columns filter.
12
+ - Persisted selected chat history columns in user preferences.
13
+
14
+ ## [0.0.52] - 05.05.2026
15
+
16
+ - Updated loading logic
17
+
7
18
  ## [0.0.51] - 05.05.2026
8
19
 
9
20
  - History page header alignment
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buerokratt-ria/common-gui-components",
3
- "version": "0.0.51",
3
+ "version": "0.0.53",
4
4
  "description": "Common GUI components and pre defined templates.",
5
5
  "main": "index.ts",
6
6
  "author": "ExiRai",
@@ -3,10 +3,6 @@
3
3
  @import 'src/styles/settings/variables/other';
4
4
  @import 'src/styles/settings/variables/typography';
5
5
 
6
- .input-wrapper {
7
- width: 40%;
8
- }
9
-
10
6
  .header-container {
11
7
  align-items: center;
12
8
  display: flex;
@@ -89,3 +85,11 @@
89
85
  .spinner {
90
86
  height: 24px;
91
87
  }
88
+
89
+ .history-content {
90
+ &--loading {
91
+ opacity: 0.5;
92
+ pointer-events: none;
93
+ user-select: none;
94
+ }
95
+ }
@@ -1,16 +1,17 @@
1
- import React, {FC, PropsWithChildren, useEffect, useMemo, useRef, useState} from 'react';
1
+ import {FC, PropsWithChildren, useEffect, useMemo, useRef, useState} from 'react';
2
2
  import {useTranslation} from 'react-i18next';
3
3
  import {useMutation} from '@tanstack/react-query';
4
4
  import {ColumnPinningState, createColumnHelper, PaginationState, SortingState,} from '@tanstack/react-table';
5
5
  import {endOfDay, format, formatISO, startOfDay} from "date-fns";
6
6
  import {AxiosError} from 'axios';
7
7
  import './History.scss';
8
- import {MdOutlineRemoveRedEye} from 'react-icons/md';
8
+ import {MdOutlineRemoveRedEye } from 'react-icons/md';
9
9
  import {CgSpinner} from 'react-icons/cg';
10
10
 
11
11
  import {
12
12
  Button,
13
13
  Card,
14
+ ClearFiltersButton,
14
15
  DataTable,
15
16
  Dialog,
16
17
  Drawer,
@@ -61,6 +62,8 @@ type ExportResult = {
61
62
  chatIds: string[];
62
63
  };
63
64
 
65
+ const ALL_COLUMNS_VALUE = '__all__';
66
+
64
67
  const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
65
68
  user,
66
69
  userDomains,
@@ -86,8 +89,6 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
86
89
  const passedStartDate = delegatedStartDate ?? params.get("start");
87
90
  const passedEndDate = delegatedEndDate ?? params.get("end");
88
91
  const skipNextSelectedColumnsEffect = useRef(false);
89
- const passedCustomerSupportIds = params.getAll('customerSupportIds');
90
- const [search, setSearch] = useState('');
91
92
  const [selectedChat, setSelectedChat] = useState<ChatType | null>(null);
92
93
  const [searchParams, setSearchParams] = useSearchParams();
93
94
  const [statusChangeModal, setStatusChangeModal] = useState<string | null>(
@@ -114,7 +115,6 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
114
115
 
115
116
  const [messagesTrigger, setMessagesTrigger] = useState(false);
116
117
  const [selectedColumns, setSelectedColumns] = useState<string[]>([]);
117
- const [customerSupportAgents, setCustomerSupportAgents] = useState<any[]>([]);
118
118
  const [counterKey, setCounterKey] = useState<number>(0)
119
119
 
120
120
  const useStore = userDomains;
@@ -126,6 +126,8 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
126
126
  const showTest = envVal === undefined ? true : envVal.toLowerCase() === 'true';
127
127
  const [loading, setLoading] = useState(false);
128
128
  const abortRef = useRef<AbortController | null>(null);
129
+ const loadingTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
130
+ const timeoutAbortRef = useRef(false);
129
131
 
130
132
  const parseDateParam = (dateString: string | null) => {
131
133
  if (!dateString) return new Date();
@@ -135,13 +137,16 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
135
137
  const { control, setValue, watch } = useForm<{
136
138
  startDate: Date | string;
137
139
  endDate: Date | string;
140
+ search: string;
138
141
  }>({
139
142
  defaultValues: {
140
143
  startDate: passedStartDate ? parseDateParam(passedStartDate) : startOfDay(new Date()),
141
144
  endDate: passedEndDate ? parseDateParam(passedEndDate) : endOfDay(new Date()),
145
+ search: '',
142
146
  },
143
147
  });
144
148
 
149
+ const search = watch('search');
145
150
  const startDate = watch('startDate');
146
151
  const endDate = watch('endDate');
147
152
 
@@ -149,7 +154,6 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
149
154
  getAllEndedChats.mutate({
150
155
  startDate: formatISO(startOfDay(new Date(startDate))),
151
156
  endDate: formatISO(endOfDay(new Date(endDate))),
152
- customerSupportIds: passedCustomerSupportIds,
153
157
  pagination,
154
158
  sorting,
155
159
  search,
@@ -196,7 +200,6 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
196
200
  getAllEndedChats.mutate({
197
201
  startDate: hasStart ? unifyDateFromat(delegatedStartDate) : formatISO(startOfDay(new Date(startDate))),
198
202
  endDate: hasEnd ? unifyDateFromat(delegatedEndDate) : formatISO(endOfDay(new Date(endDate))),
199
- customerSupportIds: passedCustomerSupportIds,
200
203
  pagination,
201
204
  sorting,
202
205
  search,
@@ -227,13 +230,12 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
227
230
  }
228
231
 
229
232
  skipNextSelectedColumnsEffect.current = true;
230
- setSelectedColumns(newSelectedColumns);
233
+ setSelectedColumns(getUiSelectedColumns(newSelectedColumns));
231
234
  setCounterKey(prev => prev + 1);
232
235
 
233
236
  getAllEndedChats.mutate({
234
237
  startDate: formatISO(startOfDay(new Date(startDate))),
235
238
  endDate: formatISO(endOfDay(new Date(endDate))),
236
- customerSupportIds: passedCustomerSupportIds,
237
239
  pagination: updatedPagination,
238
240
  sorting,
239
241
  search,
@@ -262,7 +264,6 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
262
264
  getAllEndedChats.mutate({
263
265
  startDate: formatISO(startOfDay(new Date(startDate))),
264
266
  endDate: formatISO(endOfDay(new Date(endDate))),
265
- customerSupportIds: passedCustomerSupportIds,
266
267
  pagination,
267
268
  sorting,
268
269
  search,
@@ -270,10 +271,6 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
270
271
  }
271
272
  }, [selectedColumns, currentDomains]);
272
273
 
273
- useEffect(() => {
274
- listCustomerSupportAgents.mutate();
275
- }, []);
276
-
277
274
  const updatePagePreferences = useMutation({
278
275
  mutationFn: (data: {
279
276
  page_results: number;
@@ -292,7 +289,6 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
292
289
  mutationFn: (data: {
293
290
  startDate: string;
294
291
  endDate: string;
295
- customerSupportIds: string[];
296
292
  pagination: PaginationState;
297
293
  sorting: SortingState;
298
294
  search: string;
@@ -307,7 +303,6 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
307
303
  }
308
304
 
309
305
  return apiDevEnded.post('agents/chats/ended', {
310
- customerSupportIds: data.customerSupportIds,
311
306
  startDate: formatISO(startOfDay(new Date(data.startDate))),
312
307
  endDate: formatISO(endOfDay(new Date(data.endDate))),
313
308
  urls: getDomainsArray(currentDomains),
@@ -334,8 +329,32 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
334
329
  setTotalPages(res?.data?.response[0]?.totalPages ?? 1);
335
330
  setTotalCount(res?.data?.response[0]?.totalCount ?? null);
336
331
  },
332
+ onError: (error: AxiosError) => {
333
+ if (error.code === 'ERR_CANCELED' && !timeoutAbortRef.current) return;
334
+ timeoutAbortRef.current = false;
335
+ toast?.open({
336
+ type: 'error',
337
+ title: t('global.notificationError'),
338
+ message: 'Veateade',
339
+ });
340
+ },
337
341
  });
338
342
 
343
+ useEffect(() => {
344
+ if (getAllEndedChats.isPending) {
345
+ loadingTimeoutRef.current = setTimeout(() => {
346
+ timeoutAbortRef.current = true;
347
+ abortRef.current?.abort();
348
+ }, 10000);
349
+ } else if (loadingTimeoutRef.current) {
350
+ clearTimeout(loadingTimeoutRef.current);
351
+ loadingTimeoutRef.current = null;
352
+ }
353
+ return () => {
354
+ if (loadingTimeoutRef.current) clearTimeout(loadingTimeoutRef.current);
355
+ };
356
+ }, [getAllEndedChats.isPending]);
357
+
339
358
  const getChatById = useMutation({
340
359
  mutationFn: () =>
341
360
  apiDev.post('chats/get', {
@@ -347,27 +366,7 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
347
366
  },
348
367
  });
349
368
 
350
- const listCustomerSupportAgents = useMutation({
351
- mutationFn: () =>
352
- apiDev.post('accounts/customer-support-agents', {
353
- page: 0,
354
- page_size: 99999,
355
- sorting: 'name asc',
356
- show_active_only: false,
357
- roles: ['ROLE_CUSTOMER_SUPPORT_AGENT'],
358
- }),
359
- onSuccess: (res: any) => {
360
- setCustomerSupportAgents([
361
- {label: 'Bürokratt', value: 'chatbot'},
362
- ...res.data.response.map((item) => ({
363
- label: [item.firstName, item.lastName].join(' ').trim(),
364
- value: item.idCode,
365
- })),
366
- ]);
367
- },
368
- });
369
-
370
- const visibleColumnOptions = useMemo(() => {
369
+ const realColumnOptions: {readonly label: string; readonly value: string}[] = useMemo(() => {
371
370
  const columns = [
372
371
  {label: t('chat.history.startTime'), value: 'created'},
373
372
  {label: t('chat.history.endTime'), value: 'ended'},
@@ -396,6 +395,49 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
396
395
  return columns;
397
396
  }, [t, showEmail, testMessageEnabled])
398
397
 
398
+ const visibleColumnOptions = useMemo(() => [
399
+ {label: t('chat.history.chooseAll'), value: ALL_COLUMNS_VALUE},
400
+ ...realColumnOptions,
401
+ ], [t, realColumnOptions]);
402
+
403
+ const getRealSelectedColumns = (columns: string[]) =>
404
+ columns.filter((column) => column !== ALL_COLUMNS_VALUE);
405
+
406
+ const getAllColumnValues = () => realColumnOptions.map((option) => option.value);
407
+
408
+ const areAllColumnsSelected = (columns: string[]) => {
409
+ const realSelectedColumns = getRealSelectedColumns(columns);
410
+ const allColumnValues = getAllColumnValues();
411
+
412
+ return allColumnValues.length > 0 &&
413
+ allColumnValues.every((column) => realSelectedColumns.includes(column));
414
+ };
415
+
416
+ const getUiSelectedColumns = (columns: string[]) => {
417
+ const realSelectedColumns = getRealSelectedColumns(columns);
418
+
419
+ if (areAllColumnsSelected(realSelectedColumns)) {
420
+ return [ALL_COLUMNS_VALUE, ...getAllColumnValues()];
421
+ }
422
+
423
+ return realSelectedColumns;
424
+ };
425
+
426
+ const normalizeSelectedColumns = (selection: string[]) => {
427
+ const currentAllSelected = selectedColumns.includes(ALL_COLUMNS_VALUE) || areAllColumnsSelected(selectedColumns);
428
+ const nextAllSelected = selection.includes(ALL_COLUMNS_VALUE);
429
+
430
+ if (nextAllSelected && !currentAllSelected) {
431
+ return [ALL_COLUMNS_VALUE, ...getAllColumnValues()];
432
+ }
433
+
434
+ if (!nextAllSelected && currentAllSelected) {
435
+ return [];
436
+ }
437
+
438
+ return getUiSelectedColumns(selection);
439
+ };
440
+
399
441
  const chatStatusChangeMutation = useMutation({
400
442
  mutationFn: async (data: { chatId: string | number; event: string }) => {
401
443
  const changeableTo = [
@@ -430,7 +472,6 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
430
472
  getAllEndedChats.mutate({
431
473
  startDate: formatISO(startOfDay(new Date(startDate))),
432
474
  endDate: formatISO(endOfDay(new Date(endDate))),
433
- customerSupportIds: passedCustomerSupportIds,
434
475
  pagination,
435
476
  sorting,
436
477
  search,
@@ -898,9 +939,11 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
898
939
  };
899
940
 
900
941
  const getFilteredColumns = () => {
901
- if (selectedColumns.length === 0) return endedChatsColumns;
942
+ const realSelectedColumns = getRealSelectedColumns(selectedColumns);
943
+
944
+ if (realSelectedColumns.length === 0) return endedChatsColumns;
902
945
  return endedChatsColumns.filter((c) =>
903
- ['detail', 'forward', ...selectedColumns].includes(c.id ?? '')
946
+ ['detail', 'forward', ...realSelectedColumns].includes(c.id ?? '')
904
947
  );
905
948
  };
906
949
 
@@ -927,10 +970,11 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
927
970
  selectedColumns: string[],
928
971
  t: (key: string) => string
929
972
  ): ExportResult => {
973
+ const realSelectedColumns = getRealSelectedColumns(selectedColumns);
930
974
  const activeColumns =
931
- selectedColumns.length > 0
975
+ realSelectedColumns.length > 0
932
976
  ? allColumns.filter(
933
- (col) => col.id && col.id !== 'detail' && selectedColumns.includes(col.id)
977
+ (col) => col.id && col.id !== 'detail' && realSelectedColumns.includes(col.id)
934
978
  )
935
979
  : allColumns.filter((col) => col.id && col.id !== 'detail');
936
980
 
@@ -1000,9 +1044,10 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
1000
1044
  sortBy = `${sorting[0].id} ${sortType}`;
1001
1045
  }
1002
1046
 
1003
- const { headers } = mapChatsToExportRows([], endedChatsColumns, selectedColumns, t);
1004
- const activeColumns = selectedColumns.length > 0
1005
- ? endedChatsColumns.filter((col) => col.id && col.id !== 'detail' && selectedColumns.includes(col.id))
1047
+ const realSelectedColumns = getRealSelectedColumns(selectedColumns);
1048
+ const { headers } = mapChatsToExportRows([], endedChatsColumns, realSelectedColumns, t);
1049
+ const activeColumns = realSelectedColumns.length > 0
1050
+ ? endedChatsColumns.filter((col) => col.id && col.id !== 'detail' && realSelectedColumns.includes(col.id))
1006
1051
  : endedChatsColumns.filter((col) => col.id && col.id !== 'detail');
1007
1052
  const columnIds = activeColumns.map((col) => col.id!);
1008
1053
 
@@ -1015,7 +1060,6 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
1015
1060
  urls: getDomainsArray(currentDomains),
1016
1061
  sorting: sortBy,
1017
1062
  search,
1018
- customerSupportIds: passedCustomerSupportIds,
1019
1063
  });
1020
1064
 
1021
1065
  const downloadData = response.data.data ?? response.data;
@@ -1034,6 +1078,21 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
1034
1078
 
1035
1079
  const endUserFullName = getUserName();
1036
1080
 
1081
+ const isClearFiltersVisible = useMemo(()=> {
1082
+ return search.length > 0 || selectedColumns.length > 0;
1083
+ }, [search, selectedColumns]);
1084
+
1085
+ const onClearFilersClick = () => {
1086
+ const clearedColumns: string[] = [];
1087
+ setSelectedColumns(clearedColumns);
1088
+ setCounterKey(0);
1089
+ setValue('search', '');
1090
+ updatePagePreferences.mutate({
1091
+ page_results: pagination.pageSize,
1092
+ selected_columns: clearedColumns
1093
+ });
1094
+ };
1095
+
1037
1096
  if (!filteredEndedChatsList) return <>Loading... {{filteredEndedChatsList}} something is wrong </>;
1038
1097
 
1039
1098
  return (
@@ -1059,27 +1118,30 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
1059
1118
  )}
1060
1119
  </div>
1061
1120
 
1062
- <Card>
1121
+ <div className={`history-content${getAllEndedChats.isPending ? ' history-content--loading' : ''}`}>
1122
+ <Card style={{marginBottom: '16px'}}>
1063
1123
  <Track gap={16}>
1064
1124
  {displaySearchBar && (
1065
- <FormInput
1066
- className="input-wrapper"
1067
- label={t('chat.history.searchChats')}
1068
- hideLabel
1069
- name="searchChats"
1070
- placeholder={t('chat.history.searchChats') + '...'}
1071
- onChange={(e) => {
1072
- setPagination({ pageIndex: 0, pageSize: pagination.pageSize });
1073
- setSearchParams((params) => {
1074
- params.set("page", "1");
1075
- return params;
1076
- });
1077
- setSearch(e.target.value);
1078
- debouncedGetAllEnded(e.target.value);
1079
- }}
1080
- />)}
1081
-
1082
- <Track style={{width: '100%'}} gap={16}>
1125
+ <Controller name="search" control={control} render={({ field }) => {
1126
+ return <FormInput
1127
+ label={t('chat.history.searchChats')}
1128
+ hideLabel
1129
+ name="searchChats"
1130
+ value={field.value}
1131
+ placeholder={t('chat.history.searchChats') + '...'}
1132
+ onChange={(e) => {
1133
+ setPagination({ pageIndex: 0, pageSize: pagination.pageSize });
1134
+ setSearchParams((params) => {
1135
+ params.set("page", "1");
1136
+ return params;
1137
+ });
1138
+ field.onChange(e.target.value);
1139
+ debouncedGetAllEnded(e.target.value);
1140
+ }}
1141
+ />
1142
+ }} />
1143
+ )}
1144
+ <Track gap={16}>
1083
1145
  {displayDateFilter && (
1084
1146
  <>
1085
1147
  <Track gap={10}>
@@ -1106,7 +1168,6 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
1106
1168
  getAllEndedChats.mutate({
1107
1169
  startDate: start,
1108
1170
  endDate: formatISO(endOfDay(new Date(endDate))),
1109
- customerSupportIds: passedCustomerSupportIds,
1110
1171
  pagination: resetPagination,
1111
1172
  sorting,
1112
1173
  search,
@@ -1141,7 +1202,6 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
1141
1202
  getAllEndedChats.mutate({
1142
1203
  startDate: formatISO(startOfDay(new Date(startDate))),
1143
1204
  endDate: end,
1144
- customerSupportIds: passedCustomerSupportIds,
1145
1205
  pagination: resetPagination,
1146
1206
  sorting,
1147
1207
  search,
@@ -1154,6 +1214,7 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
1154
1214
  </Track>
1155
1215
  </>
1156
1216
  )}
1217
+ <Track style={{width: '240px'}}>
1157
1218
  <FormMultiselect
1158
1219
  key={counterKey}
1159
1220
  name="visibleColumns"
@@ -1163,54 +1224,18 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
1163
1224
  selectedOptions={visibleColumnOptions.filter((o) =>
1164
1225
  selectedColumns.includes(o.value)
1165
1226
  )}
1227
+ selectedOptionsCount={getRealSelectedColumns(selectedColumns).length}
1166
1228
  onSelectionChange={(selection) => {
1167
- const columns = selection?.map((s) => s.value) ?? [];
1229
+ const columns = normalizeSelectedColumns(selection?.map((s) => s.value) ?? []);
1168
1230
  setSelectedColumns(columns);
1231
+ setCounterKey(prev => prev + 1);
1169
1232
  updatePagePreferences.mutate({
1170
1233
  page_results: pagination.pageSize,
1171
- selected_columns: columns
1234
+ selected_columns: getRealSelectedColumns(columns)
1172
1235
  })
1173
1236
  }}
1174
- />
1175
- <FormMultiselect
1176
- name="agent"
1177
- label={t('')}
1178
- placeholder={t('chat.history.chosenCsa')}
1179
- options={customerSupportAgents}
1180
- selectedOptions={customerSupportAgents.filter((item) =>
1181
- passedCustomerSupportIds.includes(item.value)
1182
- )}
1183
- onSelectionChange={(selection) => {
1184
- setSearchParams((params) => {
1185
- params.delete('customerSupportIds');
1186
- params.set('page', '1');
1187
- selection?.forEach((s) => {
1188
- params.append("customerSupportIds", s.value);
1189
- if (s.value === "chatbot") params.append("customerSupportIds", "-");
1190
- return params;
1191
- });
1192
- return params;
1193
- });
1194
-
1195
- setPagination({pageIndex: 0, pageSize: pagination.pageSize});
1196
-
1197
- const customerSupportIds =
1198
- selection?.reduce((acc, s) => {
1199
- acc.push(s.value);
1200
- if (s.value === "chatbot") acc.push("-");
1201
- return acc;
1202
- }, []) || [];
1203
-
1204
- getAllEndedChats.mutate({
1205
- startDate,
1206
- endDate,
1207
- customerSupportIds: customerSupportIds,
1208
- pagination: {pageIndex: 0, pageSize: pagination.pageSize},
1209
- sorting,
1210
- search,
1211
- });
1212
- }}
1213
- />
1237
+ />
1238
+ </Track>
1214
1239
  </Track>
1215
1240
  </Track>
1216
1241
  </Card>
@@ -1222,6 +1247,11 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
1222
1247
  </Button>
1223
1248
  </div>)
1224
1249
  }
1250
+ {isClearFiltersVisible && (
1251
+ <Track justify="between" style={{ marginBottom: '16px' }}>
1252
+ <ClearFiltersButton style={{ marginLeft: 'auto' }} onClick={onClearFilersClick} />
1253
+ </Track>
1254
+ )}
1225
1255
  <div className="card-drawer-container" style={{height: '100%', overflow: 'auto'}}>
1226
1256
  <div className="card-wrapper">
1227
1257
  <Card>
@@ -1242,12 +1272,11 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
1242
1272
  setPagination(state);
1243
1273
  updatePagePreferences.mutate({
1244
1274
  page_results: state.pageSize,
1245
- selected_columns: selectedColumns
1275
+ selected_columns: getRealSelectedColumns(selectedColumns)
1246
1276
  });
1247
1277
  getAllEndedChats.mutate({
1248
1278
  startDate: formatISO(startOfDay(new Date(startDate))),
1249
1279
  endDate: formatISO(endOfDay(new Date(endDate))),
1250
- customerSupportIds: passedCustomerSupportIds,
1251
1280
  pagination: state,
1252
1281
  sorting,
1253
1282
  search,
@@ -1258,7 +1287,6 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
1258
1287
  getAllEndedChats.mutate({
1259
1288
  startDate: formatISO(startOfDay(new Date(startDate))),
1260
1289
  endDate: formatISO(endOfDay(new Date(endDate))),
1261
- customerSupportIds: passedCustomerSupportIds,
1262
1290
  pagination,
1263
1291
  sorting: state,
1264
1292
  search,
@@ -1433,6 +1461,7 @@ const ChatHistory: FC<PropsWithChildren<HistoryProps>> = ({
1433
1461
  </>
1434
1462
  )}
1435
1463
  </div>
1464
+ </div>
1436
1465
 
1437
1466
  {statusChangeModal && (
1438
1467
  <Dialog
@@ -45,7 +45,8 @@
45
45
  "today": "Today",
46
46
  "forward": "Forward",
47
47
  "chosen": "Chosen",
48
- "read": "Read"
48
+ "read": "Read",
49
+ "clearFilters": "Clear filters"
49
50
  },
50
51
  "sorting": {
51
52
  "des": "descending",
@@ -175,7 +176,8 @@
175
176
  "statusAdder": "Status adder",
176
177
  "statusAddedDate": "Status added date",
177
178
  "chosenCsa": "Chosen csa(s)",
178
- "chosenColumn": "Chosen column(s)"
179
+ "chosenColumn": "Chosen column(s)",
180
+ "chooseAll": "Choose all"
179
181
  },
180
182
  "plainEvents": {
181
183
  "answered": "Answered",
@@ -45,7 +45,8 @@
45
45
  "today": "Täna",
46
46
  "forward": "Suuna",
47
47
  "chosen": "Valitud",
48
- "read": "Loetud"
48
+ "read": "Loetud",
49
+ "clearFilters": "Tühjenda filtrid"
49
50
  },
50
51
  "sorting": {
51
52
  "des": "kahanevalt",
@@ -175,7 +176,8 @@
175
176
  "statusAdder": "Staatuse lisaja",
176
177
  "statusAddedDate": "Staatuse lisamise kuupäev",
177
178
  "chosenCsa": "Valitud nõustaja(d)",
178
- "chosenColumn": "Valitud tulba(d)"
179
+ "chosenColumn": "Valitud tulba(d)",
180
+ "chooseAll": "Vali kõik"
179
181
  },
180
182
  "plainEvents": {
181
183
  "answered": "Vastatud",
@@ -10,6 +10,7 @@ type CardProps = {
10
10
  isHeaderLight?: boolean;
11
11
  isBodyDivided?: boolean;
12
12
  isScrollable?: boolean;
13
+ style?: React.CSSProperties;
13
14
  };
14
15
 
15
16
  const Card: FC<PropsWithChildren<CardProps>> = ({
@@ -19,10 +20,11 @@ const Card: FC<PropsWithChildren<CardProps>> = ({
19
20
  isHeaderLight,
20
21
  isBodyDivided,
21
22
  isScrollable = false,
23
+ style,
22
24
  children,
23
25
  }) => {
24
26
  return (
25
- <div className={clsx('card', { 'card--borderless': borderless, 'card--scrollable': isScrollable })}>
27
+ <div className={clsx('card', { 'card--borderless': borderless, 'card--scrollable': isScrollable })} style={style}>
26
28
  {header && (
27
29
  <div className={`card__header ${isHeaderLight ? 'white' : ''}`}>
28
30
  {header}
@@ -0,0 +1,24 @@
1
+ import { Button } from "@buerokratt-ria/header/src/components";
2
+ import { ComponentProps, FC } from "react";
3
+ import { useTranslation } from "react-i18next";
4
+ import { MdFilterListOff } from "react-icons/md";
5
+
6
+ type ClearFiltersButtonProps = {
7
+ readonly onClick: () => void;
8
+ readonly style?: Pick<ComponentProps<typeof Button>, 'style'>['style'];
9
+ }
10
+
11
+ const ClearFiltersButton: FC<ClearFiltersButtonProps> = ({ onClick, style }) => {
12
+ const { t } = useTranslation();
13
+
14
+ return <Button
15
+ appearance="primary"
16
+ size="s"
17
+ style={style}
18
+ onClick={onClick}>
19
+ {t('global.clearFilters')}
20
+ <MdFilterListOff style={{ height: '24px', width: '24px' }} />
21
+ </Button>
22
+ };
23
+
24
+ export default ClearFiltersButton;
@@ -16,6 +16,7 @@ type FormMultiselectProps = SelectHTMLAttributes<HTMLSelectElement> & {
16
16
  hideLabel?: boolean;
17
17
  options: SelectOption[];
18
18
  selectedOptions?: SelectOption[];
19
+ selectedOptionsCount?: number;
19
20
  onSelectionChange?: (selection: SelectOption[] | null) => void;
20
21
  };
21
22
 
@@ -28,6 +29,7 @@ const FormMultiselect: FC<FormMultiselectProps> = (
28
29
  placeholder,
29
30
  defaultValue,
30
31
  selectedOptions,
32
+ selectedOptionsCount,
31
33
  onSelectionChange,
32
34
  ...rest
33
35
  },
@@ -84,13 +86,14 @@ const FormMultiselect: FC<FormMultiselectProps> = (
84
86
  );
85
87
 
86
88
  const placeholderValue = placeholder || t('global.choose');
89
+ const displaySelectedCount = selectedOptionsCount ?? selectedItems.length;
87
90
 
88
91
  return (
89
92
  <div className={selectClasses} style={rest.style}>
90
93
  {label && !hideLabel && <label htmlFor={id} className='select__label' {...getLabelProps()}>{label}</label>}
91
94
  <div className='select__wrapper'>
92
95
  <div className='select__trigger' {...getToggleButtonProps()}>
93
- {selectedItems.length > 0 ? `${placeholder ?? t('global.chosen')} (${selectedItems.length})` : placeholderValue}
96
+ {selectedItems.length > 0 ? `${placeholder ?? t('global.chosen')} (${displaySelectedCount})` : placeholderValue}
94
97
  <Icon label='Dropdown icon' size='medium' icon={<MdArrowDropDown color='#5D6071' />} />
95
98
  </div>
96
99
 
@@ -24,6 +24,7 @@ import Drawer from './Drawer';
24
24
  import HistoricalChat from './HistoricalChat';
25
25
  import Dialog from './Dialog';
26
26
  import Label from './Label';
27
+ import ClearFiltersButton from './ClearFiltersButton';
27
28
 
28
29
  export {
29
30
  Button,
@@ -49,5 +50,6 @@ export {
49
50
  HistoricalChat,
50
51
  Dialog,
51
52
  Toast,
52
- Label
53
+ Label,
54
+ ClearFiltersButton,
53
55
  };