Skip to content

Commit 218c3ef

Browse files
Use MultiSelect in Account Events
1 parent 1a1c8f6 commit 218c3ef

File tree

1 file changed

+68
-13
lines changed

1 file changed

+68
-13
lines changed

apps/frontend/src/components/bookkeeper/AccountEvents/AccountEventsRoot.tsx

Lines changed: 68 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState, useEffect } from 'react';
1+
import { useState, useEffect, useCallback, useMemo } from 'react';
22
import './AccountEventsRoot.scss';
33
import { Card, Row, Col } from 'react-bootstrap';
44
import AccountEventsGraph from './AccountEventsGraph/AccountEventsGraph';
@@ -10,21 +10,72 @@ import { filterZeroActivityAccountEvents } from '../../../services/data-transfor
1010
import { AccountEventsPeriod } from '../../../types/bookkeeper.type';
1111
import { useSelector } from 'react-redux';
1212
import { selectAccountEventPeriods } from '../../../store/bkprSelectors';
13+
import { FilterMode } from '../../../utilities/constants';
1314

1415
const AccountEventsRoot = () => {
1516
const navigate = useNavigate();
1617
const accEvntPeriods = useSelector(selectAccountEventPeriods);
1718
const [showZeroActivityPeriods, setShowZeroActivityPeriods] = useState<boolean>(false);
19+
const [selectedChannelIds, setSelectedChannelIds] = useState<string[]>([]);
20+
const [channelFilterMode, setChannelFilterMode] = useState<FilterMode>('include');
1821
const [accountEventsData, setAccountEventsData] = useState<AccountEventsPeriod[]>(accEvntPeriods);
22+
const multiSelectOptions = useMemo(() => {
23+
const seen = new Set<string>();
24+
const accounts: { name: string; dataKey: string }[] = [];
25+
accEvntPeriods.forEach(period => {
26+
period.accounts.forEach(account => {
27+
const id = account.short_channel_id || account.account || account.remote_alias || '';
28+
if (!seen.has(id)) {
29+
seen.add(id);
30+
accounts.push({ name: id, dataKey: id });
31+
}
32+
});
33+
});
34+
return accounts;
35+
}, [accEvntPeriods]);
1936

20-
const handleShowZeroActivityChange = (show: boolean) => {
37+
const applyFilters = useCallback((
38+
periods: AccountEventsPeriod[],
39+
showZero: boolean,
40+
channelIds: string[],
41+
filterMode: FilterMode,
42+
): AccountEventsPeriod[] => {
43+
const zeroFiltered = filterZeroActivityAccountEvents(periods, showZero);
44+
45+
if (!channelIds || channelIds.length === 0) {
46+
return zeroFiltered;
47+
}
48+
49+
return zeroFiltered.map(period => ({
50+
...period,
51+
accounts: period.accounts.filter(account => {
52+
const id = account.short_channel_id;
53+
const isMatch = id ? channelIds.includes(id) : false;
54+
return filterMode === 'include' ? isMatch : !isMatch;
55+
}),
56+
}));
57+
}, []);
58+
59+
const handleShowZeroActivityChange = useCallback((show: boolean) => {
2160
setShowZeroActivityPeriods(show);
22-
setAccountEventsData(filterZeroActivityAccountEvents((accEvntPeriods), show));
23-
};
61+
setAccountEventsData(applyFilters(accEvntPeriods, show, selectedChannelIds, channelFilterMode));
62+
}, [accEvntPeriods, selectedChannelIds, channelFilterMode, applyFilters]);
63+
64+
const multiSelectChangeHandler = useCallback((selectedOptions: string[], filterMode: FilterMode) => {
65+
setTimeout(() => {
66+
setSelectedChannelIds(selectedOptions);
67+
setChannelFilterMode(filterMode);
68+
setAccountEventsData(
69+
applyFilters(accEvntPeriods, showZeroActivityPeriods, selectedOptions, filterMode)
70+
);
71+
}, 0);
72+
}, [accEvntPeriods, showZeroActivityPeriods, applyFilters]);
2473

2574
useEffect(() => {
26-
setAccountEventsData(filterZeroActivityAccountEvents((accEvntPeriods), showZeroActivityPeriods));
27-
}, [accEvntPeriods, showZeroActivityPeriods]);
75+
setAccountEventsData(
76+
applyFilters(accEvntPeriods, showZeroActivityPeriods, selectedChannelIds, channelFilterMode)
77+
);
78+
}, [accEvntPeriods]);
2879

2980
return (
3081
<div className='account-events-container' data-testid='account-events-container'>
@@ -35,20 +86,24 @@ const AccountEventsRoot = () => {
3586
<Col className='text-end'>
3687
<span
3788
className='span-close-svg'
38-
onClick={() => {
39-
navigate('..');
40-
}}
89+
onClick={() => navigate('..')}
4190
>
4291
<CloseSVG />
4392
</span>
4493
</Col>
4594
</Row>
46-
<DataFilterOptions filter='accountevents' onShowZeroActivityChange={handleShowZeroActivityChange} />
95+
<DataFilterOptions
96+
filter='accountevents'
97+
onShowZeroActivityChange={handleShowZeroActivityChange}
98+
multiSelectValues={multiSelectOptions}
99+
multiSelectPlaceholder='Filter Channels'
100+
multiSelectChangeHandler={multiSelectChangeHandler}
101+
/>
47102
</Card.Header>
48103
<Card.Body className='pt-1 pb-3 d-flex flex-column align-items-center'>
49-
<Col xs={12} className='account-events-graph-container'>
50-
<AccountEventsGraph periods={accountEventsData} />
51-
</Col>
104+
<Col xs={12} className='account-events-graph-container'>
105+
<AccountEventsGraph periods={accountEventsData} />
106+
</Col>
52107
<Col xs={12} className='account-events-table-container'>
53108
<AccountEventsTable periods={accountEventsData} />
54109
</Col>

0 commit comments

Comments
 (0)