1- import { Dispatch , FC , SetStateAction } from "react" ;
1+ import { Dispatch , FC , SetStateAction , useMemo , useState } from "react" ;
22import { Box , InputBase , IconButton } from "@mui/material" ;
33import Search from "@mui/icons-material/Search" ;
44import CloseIcon from "@mui/icons-material/Close" ;
55
66import { DataActionsFilters , DataActionsSorting } from "@molecules" ;
77import { OrderActionsChip } from "./OrderActionsChip" ;
8- import { theme } from "@/theme " ;
8+ import ChipButton from "../atoms/ChipButton " ;
99
1010type DataActionsBarProps = {
1111 chosenFilters ?: string [ ] ;
1212 chosenFiltersLength ?: number ;
1313 chosenSorting : string ;
1414 closeFilters ?: ( ) => void ;
1515 closeSorts : ( ) => void ;
16- filterOptions ?: {
17- key : string ;
18- label : string ;
19- } [ ] ;
16+ filterOptions ?: { key : string ; label : string } [ ] ;
2017 filtersOpen ?: boolean ;
2118 filtersTitle ?: string ;
2219 isFiltering ?: boolean ;
@@ -26,107 +23,155 @@ type DataActionsBarProps = {
2623 setChosenSorting : Dispatch < SetStateAction < string > > ;
2724 setFiltersOpen ?: Dispatch < SetStateAction < boolean > > ;
2825 setSearchText : Dispatch < SetStateAction < string > > ;
29- setSortOpen : Dispatch < SetStateAction < boolean > > ;
30- sortOpen : boolean ;
31- sortOptions ?: {
32- key : string ;
33- label : string ;
34- } [ ] ;
26+ setSortOpen ?: Dispatch < SetStateAction < boolean > > ;
27+ sortOpen ?: boolean ;
28+ sortOptions ?: { key : string ; label : string } [ ] ;
3529} ;
3630
37- export const DataActionsBar : FC < DataActionsBarProps > = ( { ...props } ) => {
38- const {
39- chosenFilters = [ ] ,
40- chosenFiltersLength,
41- chosenSorting,
42- closeFilters = ( ) => { } ,
43- closeSorts,
44- filterOptions = [ ] ,
45- filtersOpen,
46- filtersTitle,
47- isFiltering = true ,
48- searchText,
49- setChosenFilters = ( ) => { } ,
50- setChosenSorting,
51- setFiltersOpen,
52- setSearchText,
53- setSortOpen,
54- sortOpen,
55- sortOptions = [ ] ,
56- placeholder = "Search..." ,
57- } = props ;
58- const {
59- palette : { boxShadow2 } ,
60- } = theme ;
31+ export const DataActionsBar : FC < DataActionsBarProps > = ( {
32+ chosenFilters = [ ] ,
33+ chosenFiltersLength,
34+ chosenSorting,
35+ closeFilters = ( ) => { } ,
36+ closeSorts,
37+ filterOptions = [ ] ,
38+ filtersOpen,
39+ filtersTitle,
40+ isFiltering = true ,
41+ searchText,
42+ setChosenFilters = ( ) => { } ,
43+ setChosenSorting,
44+ setFiltersOpen,
45+ setSearchText,
46+ setSortOpen,
47+ sortOpen,
48+ sortOptions = [ ] ,
49+ placeholder = "Search..." ,
50+ } ) => {
51+ const [ localFiltersOpen , setLocalFiltersOpen ] = useState ( false ) ;
52+ const [ localSortOpen , setLocalSortOpen ] = useState ( false ) ;
53+
54+ const effectiveFiltersOpen = filtersOpen ?? localFiltersOpen ;
55+ const effectiveSortOpen = sortOpen ?? localSortOpen ;
56+ const setEffectiveFiltersOpen = setFiltersOpen ?? setLocalFiltersOpen ;
57+ const setEffectiveSortOpen = setSortOpen ?? setLocalSortOpen ;
58+
59+ const selectedFilterItems = useMemo (
60+ ( ) =>
61+ ( chosenFilters ?? [ ] ) . map ( ( key ) => ( {
62+ key,
63+ label : ( filterOptions ?? [ ] ) . find ( ( o ) => o . key === key ) ?. label ?? key ,
64+ } ) ) ,
65+ [ chosenFilters , filterOptions ] ,
66+ ) ;
67+
68+ const handleRemoveFilter = ( key : string ) =>
69+ setChosenFilters ?.( ( prev ) => ( prev ?? [ ] ) . filter ( ( k ) => k !== key ) ) ;
6170
6271 return (
63- < Box alignItems = "center" display = "flex" justifyContent = "space-between" >
64- < InputBase
65- inputProps = { { "data-testid" : "search-input" } }
66- onChange = { ( e ) => setSearchText ( e . target . value ) }
67- placeholder = { placeholder }
68- value = { searchText }
69- startAdornment = {
70- < Search
71- style = { {
72- color : "#99ADDE" ,
73- height : 16 ,
74- marginRight : 4 ,
75- width : 16 ,
76- } }
77- />
78- }
79- endAdornment = {
80- searchText && (
81- < IconButton
82- size = "small"
83- onClick = { ( ) => setSearchText ( "" ) }
84- sx = { { ml : 1 } }
85- >
86- < CloseIcon fontSize = "small" />
87- </ IconButton >
88- )
89- }
90- sx = { {
91- bgcolor : "white" ,
92- border : 1 ,
93- borderColor : "secondaryBlue" ,
94- borderRadius : 50 ,
95- boxShadow : `2px 2px 20px 0px ${ boxShadow2 } ` ,
96- fontSize : 11 ,
97- fontWeight : 500 ,
98- height : 48 ,
99- padding : "16px 24px" ,
100- maxWidth : 500 ,
101- } }
102- />
103- < OrderActionsChip
104- chosenFiltersLength = { chosenFiltersLength }
105- filtersOpen = { filtersOpen }
106- isFiltering = { isFiltering }
107- setFiltersOpen = { setFiltersOpen }
108- chosenSorting = { chosenSorting }
109- setSortOpen = { setSortOpen }
110- sortOpen = { sortOpen }
72+ < Box display = "flex" flexDirection = "column" gap = { 1.5 } >
73+ < Box
74+ alignItems = "center"
75+ display = "flex"
76+ justifyContent = "space-between"
77+ gap = { 1.5 }
78+ flexWrap = "wrap"
11179 >
112- { filtersOpen && (
113- < DataActionsFilters
114- chosenFilters = { chosenFilters }
115- setChosenFilters = { setChosenFilters }
116- closeFilters = { closeFilters }
117- options = { filterOptions }
118- title = { filtersTitle }
119- />
120- ) }
121- { sortOpen && (
122- < DataActionsSorting
123- chosenSorting = { chosenSorting }
124- setChosenSorting = { setChosenSorting }
125- closeSorts = { closeSorts }
126- options = { sortOptions }
127- />
128- ) }
129- </ OrderActionsChip >
80+ < InputBase
81+ inputProps = { { "data-testid" : "search-input" } }
82+ onChange = { ( e ) => setSearchText ( e . target . value ) }
83+ placeholder = { placeholder }
84+ value = { searchText }
85+ startAdornment = {
86+ < Search
87+ style = { {
88+ color : "#99ADDE" ,
89+ height : 16 ,
90+ marginRight : 4 ,
91+ width : 16 ,
92+ } }
93+ />
94+ }
95+ endAdornment = {
96+ searchText && (
97+ < IconButton
98+ size = "small"
99+ onClick = { ( ) => setSearchText ( "" ) }
100+ sx = { { ml : 1 } }
101+ >
102+ < CloseIcon fontSize = "small" />
103+ </ IconButton >
104+ )
105+ }
106+ sx = { {
107+ bgcolor : "white" ,
108+ border : 1 ,
109+ borderColor : "#6E87D9" ,
110+ borderRadius : 50 ,
111+ boxShadow : "2px 2px 20px 0 rgba(0,0,0,0.05)" ,
112+ fontSize : 11 ,
113+ fontWeight : 500 ,
114+ height : 48 ,
115+ padding : "16px 24px" ,
116+ maxWidth : 500 ,
117+ flex : "0 0 auto" ,
118+ } }
119+ />
120+
121+ < OrderActionsChip
122+ chosenFiltersLength = { chosenFiltersLength }
123+ filtersOpen = { effectiveFiltersOpen }
124+ isFiltering = { isFiltering }
125+ setFiltersOpen = { setEffectiveFiltersOpen }
126+ chosenSorting = { chosenSorting }
127+ setSortOpen = { setEffectiveSortOpen }
128+ sortOpen = { effectiveSortOpen }
129+ >
130+ { effectiveFiltersOpen && (
131+ < DataActionsFilters
132+ chosenFilters = { chosenFilters }
133+ setChosenFilters = { setChosenFilters }
134+ closeFilters = { closeFilters }
135+ options = { filterOptions }
136+ title = { filtersTitle }
137+ />
138+ ) }
139+ { effectiveSortOpen && (
140+ < DataActionsSorting
141+ chosenSorting = { chosenSorting }
142+ setChosenSorting = { setChosenSorting }
143+ closeSorts = { closeSorts }
144+ options = { sortOptions }
145+ />
146+ ) }
147+ </ OrderActionsChip >
148+ </ Box >
149+
150+ { selectedFilterItems . length > 0 && (
151+ < Box
152+ display = "flex"
153+ flexWrap = "wrap"
154+ gap = { 1 }
155+ alignItems = "flex-start"
156+ sx = { {
157+ mt : 2 ,
158+ "& > *" : { flex : "0 0 auto" , alignSelf : "flex-start" } ,
159+ } }
160+ >
161+ { selectedFilterItems . map ( ( { key, label } ) => (
162+ < ChipButton
163+ key = { key }
164+ label = { label }
165+ onDelete = { ( ) => handleRemoveFilter ( key ) }
166+ deleteIconPosition = "left"
167+ bgColor = "#B9CCF5"
168+ size = "small"
169+ />
170+ ) ) }
171+ </ Box >
172+ ) }
130173 </ Box >
131174 ) ;
132175} ;
176+
177+ export default DataActionsBar ;
0 commit comments