22import React , { useState , useMemo } from 'react' ;
33import { TableContainer , Table , TableHeader , TableRow , TableBody , TableHead , TableCell } from '../components/Table' ;
44import Dropdown from '../components/DropdownMenu' ;
5+ import Menu from '../components/Menu' ;
6+ import Checkbox from '../components/Checkbox' ;
7+ import RadioGroup from '../components/RadioGroup' ;
8+ import Button from '../components/Button' ;
59import { FunnelIcon as Filter } from '@heroicons/react/24/solid' ;
610import { ArrowsUpDownIcon as Sort } from '@heroicons/react/24/solid' ;
711import SearchBar from '../components/SearchBox' ;
812
9- const filterOptions = [
10- { itemLabel : 'Non-Discarded Variables' , value : 'non-discarded' , suffixText : '11' } ,
11- { itemLabel : 'Discarded Variables' , value : 'discarded' , suffixText : '7' } ,
12- ]
13+ const filterOptions = [ 'Non-Discarded Variables' , 'Discarded Variables' ]
1314
14- const sortOptions = [
15- { itemLabel : 'Name A-Z' , value : 'name-asc' } ,
16- { itemLabel : 'Name Z-A' , value : 'name-desc' } ,
17- { itemLabel : 'Non-Discarded Variables' , value : 'non-discarded' , defaultChecked : true } ,
18- { itemLabel : 'Discarded Variables' , value : 'discarded' } ,
19- ]
15+ const sortOptions = [ 'Name A-Z' , 'Name Z-A' , 'Non-Discarded Variables' , 'Discarded Variables' ]
2016
21- interface RowData {
22- name : string ;
23- steps : ( string | null ) [ ] ;
24- }
17+ interface RowData {
18+ name : string ;
19+ steps : ( string | null ) [ ] ;
20+ }
2521
26- const initialData : RowData [ ] = [
27- { name : 'tx' ,
28- steps : [ '123' , '456' , '789' , '101' , '112' , '131' , '415' , '161' , '718' , '192' ] } ,
29- { name : 'datum' ,
30- steps : [ 'datum1' , 'datum2' , 'datum3' , 'datum4' , 'datum5' , 'datum6' , 'datum7' , 'datum8' , 'datum9' , 'datum10' ] } ,
31- { name : 'redeemer' ,
32- steps : [ 'redeemer1' , 'redeemer2' , 'redeemer3' , 'redeemer4' , 'redeemer5' , 'redeemer6' , 'redeemer7' , 'redeemer8' , 'redeemer9' , 'redeemer10' ] } ,
33- { name : 'discarded1' ,
34- steps : [ null , null , null , null , null , null , null , null , null , null ] } ,
35- { name : 'value' ,
36- steps : [ '1000' , '2000' , '3000' , '4000' , '5000' , '6000' , '7000' , '8000' , '9000' , '10000' ] } ,
37- { name : 'script' ,
38- steps : [ 'script1' , 'script2' , 'script3' , 'script4' , 'script5' , 'script6' , 'script7' , 'script8' , 'script9' , 'script10' ] } ,
39- { name : 'dataHash' ,
40- steps : [ 'hash1' , 'hash2' , 'hash3' , 'hash4' , 'hash5' , 'hash6' , 'hash7' , 'hash8' , 'hash9' , 'hash10' ] } ,
41- { name : 'inlineDatum' ,
42- steps : [ 'inlineDatum1' , 'inlineDatum2' , 'inlineDatum3' , 'inlineDatum4' , 'inlineDatum5' , 'inlineDatum6' , 'inlineDatum7' , 'inlineDatum8' , 'inlineDatum9' , 'inlineDatum10' ] } ,
43- { name : 'inlineScript' ,
44- steps : [ 'inlineScript1' , 'inlineScript2' , 'inlineScript3' , 'inlineScript4' , 'inlineScript5' , 'inlineScript6' , 'inlineScript7' , 'inlineScript8' , 'inlineScript9' , 'inlineScript10' ] } ,
45- { name : 'discarded2' ,
46- steps : [ null , null , null , null , null , null , null , null , null , null ] } ,
47- { name : 'referenceScript' ,
48- steps : [ 'referenceScript1' , 'referenceScript2' , 'referenceScript3' , 'referenceScript4' , 'referenceScript5' , 'referenceScript6' , 'referenceScript7' , 'referenceScript8' , 'referenceScript9' , 'referenceScript10' ] } ,
49- { name : 'address' ,
50- steps : [ 'address1' , 'address2' , 'address3' , 'address4' , 'address5' , 'address6' , 'address7' , 'address8' , 'address9' , 'address10' ] } ,
51- { name : 'cert' ,
52- steps : [ 'cert1' , 'cert2' , 'cert3' , 'cert4' , 'cert5' , 'cert6' , 'cert7' , 'cert8' , 'cert9' , 'cert10' ] } ,
53- { name : 'discarded3' ,
54- steps : [ null , null , null , null , null , null , null , null , null , null ] } ,
55- { name : 'discarded4' ,
56- steps : [ null , null , null , null , null , null , null , null , null , null ] } ,
57- { name : 'discarded5' ,
58- steps : [ null , null , null , null , null , null , null , null , null , null ] } ,
59- ]
22+ const initialData : RowData [ ] = [
23+ { name : 'tx' ,
24+ steps : [ '123' , '456' , '789' , '101' , '112' , '131' , '415' , '161' , '718' , '192' ] } ,
25+ { name : 'datum' ,
26+ steps : [ 'datum1' , 'datum2' , 'datum3' , 'datum4' , 'datum5' , 'datum6' , 'datum7' , 'datum8' , 'datum9' , 'datum10' ] } ,
27+ { name : 'redeemer' ,
28+ steps : [ 'redeemer1' , 'redeemer2' , 'redeemer3' , 'redeemer4' , 'redeemer5' , 'redeemer6' , 'redeemer7' , 'redeemer8' , 'redeemer9' , 'redeemer10' ] } ,
29+ { name : 'discarded1' ,
30+ steps : [ null , null , null , null , null , null , null , null , null , null ] } ,
31+ { name : 'value' ,
32+ steps : [ '1000' , '2000' , '3000' , '4000' , '5000' , '6000' , '7000' , '8000' , '9000' , '10000' ] } ,
33+ { name : 'script' ,
34+ steps : [ 'script1' , 'script2' , 'script3' , 'script4' , 'script5' , 'script6' , 'script7' , 'script8' , 'script9' , 'script10' ] } ,
35+ { name : 'dataHash' ,
36+ steps : [ 'hash1' , 'hash2' , 'hash3' , 'hash4' , 'hash5' , 'hash6' , 'hash7' , 'hash8' , 'hash9' , 'hash10' ] } ,
37+ { name : 'inlineDatum' ,
38+ steps : [ 'inlineDatum1' , 'inlineDatum2' , 'inlineDatum3' , 'inlineDatum4' , 'inlineDatum5' , 'inlineDatum6' , 'inlineDatum7' , 'inlineDatum8' , 'inlineDatum9' , 'inlineDatum10' ] } ,
39+ { name : 'inlineScript' ,
40+ steps : [ 'inlineScript1' , 'inlineScript2' , 'inlineScript3' , 'inlineScript4' , 'inlineScript5' , 'inlineScript6' , 'inlineScript7' , 'inlineScript8' , 'inlineScript9' , 'inlineScript10' ] } ,
41+ { name : 'discarded2' ,
42+ steps : [ null , null , null , null , null , null , null , null , null , null ] } ,
43+ { name : 'referenceScript' ,
44+ steps : [ 'referenceScript1' , 'referenceScript2' , 'referenceScript3' , 'referenceScript4' , 'referenceScript5' , 'referenceScript6' , 'referenceScript7' , 'referenceScript8' , 'referenceScript9' , 'referenceScript10' ] } ,
45+ { name : 'address' ,
46+ steps : [ 'address1' , 'address2' , 'address3' , 'address4' , 'address5' , 'address6' , 'address7' , 'address8' , 'address9' , 'address10' ] } ,
47+ { name : 'cert' ,
48+ steps : [ 'cert1' , 'cert2' , 'cert3' , 'cert4' , 'cert5' , 'cert6' , 'cert7' , 'cert8' , 'cert9' , 'cert10' ] } ,
49+ { name : 'discarded3' ,
50+ steps : [ null , null , null , null , null , null , null , null , null , null ] } ,
51+ { name : 'discarded4' ,
52+ steps : [ null , null , null , null , null , null , null , null , null , null ] } ,
53+ { name : 'discarded5' ,
54+ steps : [ null , null , null , null , null , null , null , null , null , null ] } ,
55+ ]
6056
6157export default function TablePage ( ) {
6258 const [ searchTerm , setSearchTerm ] = useState ( '' ) ;
63- const [ sortValue , setSortValue ] = useState ( 'non-discarded' ) ;
64- const [ filterValues , setFilterValues ] = useState < string [ ] > ( [ 'discarded' ] ) ;
59+ const [ sortValue , setSortValue ] = useState ( sortOptions [ 2 ] ) ;
60+ const [ filterValues , setFilterValues ] = useState < string [ ] > ( [ filterOptions [ 1 ] ] ) ;
6561
6662 const displayData = useMemo ( ( ) => {
6763 let data = initialData ;
@@ -71,25 +67,25 @@ export default function TablePage(){
7167 data = data . filter ( row => row . name . toLowerCase ( ) . includes ( lowerTerm ) ) ;
7268 }
7369
74- if ( filterValues . includes ( "non-discarded" ) && ! filterValues . includes ( "discarded" ) ) {
70+ if ( filterValues . includes ( filterOptions [ 0 ] ) && ! filterValues . includes ( filterOptions [ 1 ] ) ) {
7571 data = data . filter ( row => row . steps . some ( step => step === null ) ) ;
76- } else if ( filterValues . includes ( "discarded" ) && ! filterValues . includes ( "non-discarded" ) ) {
72+ } else if ( filterValues . includes ( filterOptions [ 1 ] ) && ! filterValues . includes ( filterOptions [ 0 ] ) ) {
7773 data = data . filter ( row => row . steps . every ( step => step !== null ) ) ;
7874 } else if ( filterValues . length === 2 ) {
7975 data = [ ] ;
8076 }
8177
82- if ( sortValue === "name-asc" ) {
78+ if ( sortValue === sortOptions [ 0 ] ) {
8379 data = [ ...data ] . sort ( ( a , b ) => a . name . localeCompare ( b . name ) ) ;
84- } else if ( sortValue === "name-desc" ) {
80+ } else if ( sortValue === sortOptions [ 1 ] ) {
8581 data = [ ...data ] . sort ( ( a , b ) => b . name . localeCompare ( a . name ) ) ;
86- } else if ( sortValue === "non-discarded" ) {
82+ } else if ( sortValue === sortOptions [ 2 ] ) {
8783 data = [ ...data ] . sort ( ( a , b ) => {
8884 const aDiscarded = a . steps . every ( step => step === null ) ? 1 : 0 ;
8985 const bDiscarded = b . steps . every ( step => step === null ) ? 1 : 0 ;
9086 return aDiscarded - bDiscarded ;
9187 } ) ;
92- } else if ( sortValue === "discarded" ) {
88+ } else if ( sortValue === sortOptions [ 3 ] ) {
9389 data = [ ...data ] . sort ( ( a , b ) => {
9490 const aDiscarded = a . steps . every ( step => step !== null ) ? 1 : 0 ;
9591 const bDiscarded = b . steps . every ( step => step !== null ) ? 1 : 0 ;
@@ -98,7 +94,16 @@ export default function TablePage(){
9894 }
9995
10096 return data ;
101- } , [ searchTerm , filterValues , sortValue , initialData ] ) ;
97+ } , [ searchTerm , filterValues , sortValue ] ) ;
98+
99+ const handleFilterSelect = ( event : React . ChangeEvent < HTMLInputElement > ) => {
100+ const val = event . target . value ;
101+ if ( filterValues . includes ( val ) ) {
102+ setFilterValues ( filterValues . filter ( ( v ) => v !== val ) )
103+ } else {
104+ setFilterValues ( [ ...filterValues , val ] )
105+ }
106+ }
102107
103108 return (
104109 < div className = "font-[family-name:var(--font-geist-sans)] bg-surface flex h-dvh p-8" >
@@ -112,21 +117,43 @@ export default function TablePage(){
112117 />
113118 < div className = "flex gap-2" >
114119 < Dropdown
115- btnLabel = "Filter"
116- btnIcon = { { svg : < Filter /> } }
117- listItems = { filterOptions } type = 'checkbox'
120+ btnLabel = { filterValues . length === 0 ? "Filter" : filterValues . length === 1 ? "Filter: " + filterValues [ 0 ] : "Filter: " + filterValues . length }
121+ btnIcon = { { svg : < Filter /> } }
118122 position = 'right'
119- selected = { filterValues }
120- onChange = { ( val ) => setFilterValues ( val as string [ ] ) }
121- />
123+ >
124+ < >
125+ { filterOptions . map ( ( i ) =>
126+ < Menu . Item
127+ key = { i }
128+ className = 'flex justify-between' >
129+ < Checkbox
130+ label = { i }
131+ value = { i }
132+ checked = { filterValues . includes ( i ) }
133+ onChange = { handleFilterSelect }
134+ />
135+ </ Menu . Item >
136+ ) }
137+ < Menu . Divider />
138+ < Button variant = "inherit" content = "Clear All" onClick = { ( ) => setFilterValues ( [ ] ) } fullWidth className = 'mb-[8px]' />
139+ </ >
140+ </ Dropdown >
122141 < Dropdown
123- btnLabel = "Sort"
124- btnIcon = { { svg : < Sort /> } } listItems = { sortOptions }
125- type = 'radio'
142+ btnLabel = { "Sort: " + sortValue }
143+ btnIcon = { { svg : < Sort /> } }
126144 position = 'right'
127- selected = { sortValue }
128- onChange = { ( val ) => setSortValue ( val as string ) }
129- />
145+ >
146+ { sortOptions . map ( ( i ) =>
147+ < Menu . Item key = { i } className = 'flex justify-between' >
148+ < RadioGroup . Button
149+ label = { i }
150+ value = { i }
151+ checked = { i === sortValue }
152+ onChange = { ( ) => setSortValue ( i ) }
153+ />
154+ </ Menu . Item >
155+ ) }
156+ </ Dropdown >
130157 </ div >
131158 </ div >
132159 < Table >
0 commit comments