1- import { useState , useEffect } from 'react' ;
1+ import { useState , useEffect , useCallback , useMemo } from 'react' ;
22import './AccountEventsRoot.scss' ;
33import { Card , Row , Col } from 'react-bootstrap' ;
44import AccountEventsGraph from './AccountEventsGraph/AccountEventsGraph' ;
@@ -10,21 +10,72 @@ import { filterZeroActivityAccountEvents } from '../../../services/data-transfor
1010import { AccountEventsPeriod } from '../../../types/bookkeeper.type' ;
1111import { useSelector } from 'react-redux' ;
1212import { selectAccountEventPeriods } from '../../../store/bkprSelectors' ;
13+ import { FilterMode } from '../../../utilities/constants' ;
1314
1415const 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