1- import React , { useMemo , useRef } from 'react' ;
1+ import React , {
2+ useCallback ,
3+ useEffect ,
4+ useMemo ,
5+ useRef ,
6+ useState ,
7+ } from 'react' ;
28import {
39 Table ,
410 TableBody ,
@@ -13,6 +19,7 @@ import {
1319 type LeafyGreenTableRow ,
1420 flexRender ,
1521 type HeaderGroup ,
22+ SearchInput ,
1623} from '@mongodb-js/compass-components' ;
1724import type { ShardZoneData } from '../store/reducer' ;
1825
@@ -23,6 +30,7 @@ const containerStyles = css({
2330interface ShardZoneRow {
2431 locationName : string ;
2532 zone : string ;
33+ searchable : string ;
2634}
2735
2836interface ShardZoneExpandableRow extends ShardZoneRow {
@@ -50,102 +58,151 @@ const parseRow = ({
5058} : ShardZoneData ) : ShardZoneRow => ( {
5159 locationName : `${ readableName } (${ isoCode } )` ,
5260 zone : `${ zoneName } (${ zoneLocations . join ( ', ' ) } )` ,
61+ searchable : readableName ,
5362} ) ;
5463
64+ const parseData = ( shardZones : ShardZoneData [ ] ) : ShardZoneExpandableRow [ ] => {
65+ const grouppedZones = shardZones . reduce <
66+ Record < ShardZoneData [ 'typeOneIsoCode' ] , ShardZoneExpandableRow >
67+ > ( ( groups , next ) => {
68+ const { typeOneIsoCode, isoCode } = next ;
69+ if ( ! groups [ typeOneIsoCode ] ) {
70+ groups [ typeOneIsoCode ] = { ...parseRow ( next ) , subRows : [ ] } ;
71+ }
72+ if ( typeOneIsoCode === isoCode ) {
73+ Object . assign ( groups [ typeOneIsoCode ] , parseRow ( next ) ) ;
74+ } else {
75+ groups [ typeOneIsoCode ] . subRows . push ( parseRow ( next ) ) ;
76+ }
77+ return groups ;
78+ } , { } ) ;
79+ return Object . values ( grouppedZones ) ;
80+ } ;
81+
5582export function ShardZonesTable ( {
5683 shardZones,
5784} : {
5885 shardZones : ShardZoneData [ ] ;
5986} ) {
6087 const tableContainerRef = useRef < HTMLDivElement > ( null ) ;
88+ const [ searchText , setSearchText ] = useState < string > ( '' ) ;
89+ const handleSearchTextChange = useCallback (
90+ ( e : React . ChangeEvent < HTMLInputElement > ) => {
91+ setSearchText ( e . currentTarget . value ) ;
92+ } ,
93+ [ setSearchText ]
94+ ) ;
6195
62- const data = useMemo < ShardZoneExpandableRow [ ] > ( ( ) => {
63- const grouppedZones = shardZones . reduce <
64- Record < ShardZoneData [ 'typeOneIsoCode' ] , ShardZoneExpandableRow >
65- > ( ( groups , next ) => {
66- const { typeOneIsoCode, isoCode } = next ;
67- if ( ! groups [ typeOneIsoCode ] ) {
68- groups [ typeOneIsoCode ] = { ...parseRow ( next ) , subRows : [ ] } ;
69- }
70- if ( typeOneIsoCode === isoCode ) {
71- Object . assign ( groups [ typeOneIsoCode ] , next ) ;
72- } else {
73- groups [ typeOneIsoCode ] . subRows . push ( parseRow ( next ) ) ;
74- }
75- return groups ;
76- } , { } ) ;
77- return Object . values ( grouppedZones ) ;
78- } , [ shardZones ] ) ;
96+ const data = useMemo < ShardZoneExpandableRow [ ] > (
97+ ( ) => parseData ( shardZones ) ,
98+ [ shardZones ]
99+ ) ;
100+
101+ const filteredData = useMemo < ShardZoneExpandableRow [ ] > (
102+ ( ) =>
103+ data . reduce < ShardZoneExpandableRow [ ] > ( ( filtered , next ) => {
104+ const { searchable, subRows } = next ;
105+ if ( searchable . includes ( searchText ) ) {
106+ filtered . push ( next ) ;
107+ return filtered ;
108+ }
109+ const matchingSubRows = subRows . filter ( ( subRow ) =>
110+ subRow . searchable . includes ( searchText )
111+ ) ;
112+ if ( matchingSubRows . length > 0 ) {
113+ filtered . push ( {
114+ ...next ,
115+ subRows : matchingSubRows ,
116+ } ) ;
117+ }
118+ return filtered ;
119+ } , [ ] ) ,
120+ [ data , searchText ]
121+ ) ;
79122
80123 const table = useLeafyGreenTable ( {
81124 containerRef : tableContainerRef ,
82- data,
125+ data : filteredData ,
83126 columns,
84127 } ) ;
85128
86129 const { rows } = table . getRowModel ( ) ;
87130
88- return (
89- // TODO(COMPASS-8336):
90- // Add search
91- // group zones by ShardZoneData.typeOneIsoCode
92- // and display them in a single row that can be expanded
131+ const rowsRef = useRef ( rows ) ;
132+ rowsRef . current = rows ;
133+ useEffect ( ( ) => {
134+ if ( ! searchText ) return ;
135+ for ( const row of rowsRef . current ) {
136+ if ( row . subRows . length && ! row . getIsExpanded ( ) ) {
137+ console . log ( 'expanding row' , row . original , row . getIsExpanded ( ) ) ;
138+ row . toggleExpanded ( ) ;
139+ }
140+ }
141+ } , [ searchText , rowsRef ] ) ;
93142
94- < Table
95- className = { containerStyles }
96- title = "Zone Mapping"
97- table = { table }
98- ref = { tableContainerRef }
99- >
100- < colgroup >
101- < col width = "300" > </ col >
102- < col />
103- </ colgroup >
104- < TableHead isSticky >
105- { table
106- . getHeaderGroups ( )
107- . map ( ( headerGroup : HeaderGroup < ShardZoneRow > ) => (
108- < HeaderRow key = { headerGroup . id } >
109- { headerGroup . headers . map ( ( header ) => {
110- return (
111- < HeaderCell key = { header . id } header = { header } >
112- { flexRender (
113- header . column . columnDef . header ,
114- header . getContext ( )
115- ) }
116- </ HeaderCell >
117- ) ;
118- } ) }
119- </ HeaderRow >
120- ) ) }
121- </ TableHead >
122- < TableBody >
123- { rows . map ( ( row : LeafyGreenTableRow < ShardZoneRow > ) => (
124- < Row key = { row . id } row = { row } >
125- { row . getVisibleCells ( ) . map ( ( cell ) => {
126- return (
127- < Cell key = { cell . id } >
128- { flexRender ( cell . column . columnDef . cell , cell . getContext ( ) ) }
129- </ Cell >
130- ) ;
131- } ) }
132- { row . subRows . map ( ( subRow ) => (
133- < Row key = { subRow . id } row = { subRow } >
134- { subRow . getVisibleCells ( ) . map ( ( cell ) => {
143+ return (
144+ < >
145+ < SearchInput
146+ value = { searchText }
147+ onChange = { handleSearchTextChange }
148+ aria-label = "Search for a location"
149+ placeholder = "Search for a location"
150+ />
151+ < Table
152+ className = { containerStyles }
153+ title = "Zone Mapping"
154+ table = { table }
155+ ref = { tableContainerRef }
156+ >
157+ < TableHead isSticky >
158+ { table
159+ . getHeaderGroups ( )
160+ . map ( ( headerGroup : HeaderGroup < ShardZoneRow > ) => (
161+ < HeaderRow key = { headerGroup . id } >
162+ { headerGroup . headers . map ( ( header ) => {
135163 return (
136- < Cell key = { cell . id } >
164+ < HeaderCell key = { header . id } header = { header } >
137165 { flexRender (
138- cell . column . columnDef . cell ,
139- cell . getContext ( )
166+ header . column . columnDef . header ,
167+ header . getContext ( )
140168 ) }
141- </ Cell >
169+ </ HeaderCell >
142170 ) ;
143171 } ) }
144- </ Row >
172+ </ HeaderRow >
145173 ) ) }
146- </ Row >
147- ) ) }
148- </ TableBody >
149- </ Table >
174+ </ TableHead >
175+ < TableBody >
176+ { rows . map ( ( row : LeafyGreenTableRow < ShardZoneRow > ) => (
177+ < Row key = { row . id } row = { row } >
178+ { row . getVisibleCells ( ) . map ( ( cell ) => {
179+ return (
180+ < Cell key = { cell . id } >
181+ { flexRender ( cell . column . columnDef . cell , cell . getContext ( ) ) }
182+ </ Cell >
183+ ) ;
184+ } ) }
185+ { row . subRows . map ( ( subRow ) => (
186+ < Row key = { subRow . id } row = { subRow } >
187+ { subRow . getVisibleCells ( ) . map ( ( cell ) => {
188+ return (
189+ < Cell key = { cell . id } >
190+ { ( ( ) => {
191+ // console.log({ cell, context: cell.getContext() });
192+ return flexRender (
193+ cell . column . columnDef . cell ,
194+ cell . getContext ( )
195+ ) ;
196+ } ) ( ) }
197+ </ Cell >
198+ ) ;
199+ } ) }
200+ </ Row >
201+ ) ) }
202+ </ Row >
203+ ) ) }
204+ </ TableBody >
205+ </ Table >
206+ </ >
150207 ) ;
151208}
0 commit comments