99 Heading ,
1010 SearchBar
1111} from '@douglasneuroinformatics/libui/components' ;
12+ import type { TanstackTable } from '@douglasneuroinformatics/libui/components' ;
1213import { useDownload , useNotificationsStore , useTranslation } from '@douglasneuroinformatics/libui/hooks' ;
1314import type { InstrumentRecordsExport } from '@opendatacapture/schemas/instrument-records' ;
1415import type { Subject } from '@opendatacapture/schemas/subject' ;
@@ -29,70 +30,14 @@ type MasterDataTableProps = {
2930 onSelect : ( subject : Subject ) => void ;
3031} ;
3132
32- const MasterDataTable = ( { data , onSelect } : MasterDataTableProps ) => {
33+ const Toggles : React . FC < { table : TanstackTable . Table < Subject > } > = ( { table } ) => {
3334 const { t } = useTranslation ( ) ;
34- const subjectIdDisplaySetting = useAppStore ( ( store ) => store . currentGroup ?. settings . subjectIdDisplayLength ) ;
35-
36- return (
37- < div >
38- < DataTable
39- columns = { [
40- {
41- accessorFn : ( subject ) => removeSubjectIdScope ( subject . id ) . slice ( 0 , subjectIdDisplaySetting ?? 9 ) ,
42- header : t ( 'datahub.index.table.subject' ) ,
43- id : 'subjectId'
44- } ,
45- {
46- accessorFn : ( subject ) => ( subject . dateOfBirth ? toBasicISOString ( new Date ( subject . dateOfBirth ) ) : 'NULL' ) ,
47- header : t ( 'core.identificationData.dateOfBirth.label' ) ,
48- id : 'date-of-birth'
49- } ,
50- {
51- accessorFn : ( subject ) => {
52- switch ( subject . sex ) {
53- case 'FEMALE' :
54- return t ( 'core.identificationData.sex.female' ) ;
55- case 'MALE' :
56- return t ( 'core.identificationData.sex.male' ) ;
57- default :
58- return 'NULL' ;
59- }
60- } ,
61- header : t ( 'core.identificationData.sex.label' ) ,
62- id : 'sex'
63- }
64- ] }
65- data = { data }
66- data-testid = "master-data-table"
67- rowActions = { [
68- {
69- label : t ( { en : 'View' , fr : 'Voir' } ) ,
70- onSelect
71- }
72- ] }
73- onSearchChange = { ( value , table ) => {
74- const subjectIdColumn = table . getColumn ( 'subjectId' ) ! ;
75- subjectIdColumn . setFilterValue ( value ) ;
76- } }
77- />
78- </ div >
79- ) ;
80- } ;
81-
82- const RouteComponent = ( ) => {
83- const [ isLookupOpen , setIsLookupOpen ] = useState ( false ) ;
84-
85- const currentGroup = useAppStore ( ( store ) => store . currentGroup ) ;
86- const currentUser = useAppStore ( ( store ) => store . currentUser ) ;
8735
8836 const download = useDownload ( ) ;
8937 const addNotification = useNotificationsStore ( ( store ) => store . addNotification ) ;
90- const { t } = useTranslation ( ) ;
91- const navigate = useNavigate ( ) ;
9238
93- const { data } = useSubjectsQuery ( { params : { groupId : currentGroup ?. id } } ) ;
94- const [ tableData , setTableData ] = useState < Subject [ ] > ( data ?? [ ] ) ;
95- const [ searchString , setSearchString ] = useState ( '' ) ;
39+ const currentGroup = useAppStore ( ( store ) => store . currentGroup ) ;
40+ const currentUser = useAppStore ( ( store ) => store . currentUser ) ;
9641
9742 const getExportRecords = async ( ) => {
9843 const response = await axios . get < InstrumentRecordsExport > ( '/v1/instrument-records/export' , {
@@ -107,9 +52,9 @@ const RouteComponent = () => {
10752 const baseFilename = `${ currentUser ! . username } _${ new Date ( ) . toISOString ( ) } ` ;
10853 getExportRecords ( )
10954 . then ( ( data ) : any => {
110- const listedSubjects = tableData . map ( ( record ) => {
111- return removeSubjectIdScope ( record . id ) ;
112- } ) ;
55+ const listedSubjects = table
56+ . getRowModel ( )
57+ . rows . flatMap ( ( row ) => row . getVisibleCells ( ) . map ( ( cell ) => removeSubjectIdScope ( cell . row . original . id ) ) ) ;
11358
11459 const filteredData = data . filter ( ( dataEntry ) => listedSubjects . includes ( dataEntry . subjectId ) ) ;
11560
@@ -160,33 +105,173 @@ const RouteComponent = () => {
160105 } ) ;
161106 } ;
162107
163- const lookupSubject = async ( { id } : { id : string } ) => {
164- const response = await axios . get < Subject > ( `/v1/subjects/${ id } ` , {
165- validateStatus : ( status ) => status === 200 || status === 404
166- } ) ;
167- if ( response . status === 404 ) {
168- addNotification ( { message : t ( 'core.notFound' ) , type : 'warning' } ) ;
169- setIsLookupOpen ( false ) ;
170- } else {
171- addNotification ( { type : 'success' } ) ;
172- await navigate ( { to : `./${ response . data . id } /table` } ) ;
173- }
174- } ;
108+ return (
109+ < >
110+ < ActionDropdown
111+ widthFull
112+ className = "min-w-48"
113+ data-spotlight-type = "export-data-dropdown"
114+ data-testid = "datahub-export-dropdown"
115+ options = { [ 'CSV' , 'JSON' , 'Excel' ] }
116+ title = { t ( 'datahub.index.table.export' ) }
117+ onSelection = { handleExportSelection }
118+ />
119+ </ >
120+ ) ;
121+ // const table = useDataTableHandle('table', true);
122+ // const columns = table.getAllColumns();
123+ // const statusColumn = columns.find((column) => column.id === 'status')!;
124+
125+ // const filterValue = statusColumn.getFilterValue() as PaymentStatus[];
126+
127+ // return (
128+ // <>
129+ // <DropdownMenu>
130+ // <DropdownMenu.Trigger asChild>
131+ // <Button className="flex items-center gap-2" variant="outline">
132+ // Columns
133+ // <ChevronDownIcon />
134+ // </Button>
135+ // </DropdownMenu.Trigger>
136+ // <DropdownMenu.Content align="end">
137+ // {columns
138+ // .filter((column) => column.getCanHide())
139+ // .map((column) => {
140+ // return (
141+ // <DropdownMenu.CheckboxItem
142+ // checked={column.getIsVisible()}
143+ // className="capitalize"
144+ // key={column.id}
145+ // onCheckedChange={(value) => column.toggleVisibility(!!value)}
146+ // >
147+ // {column.id}
148+ // </DropdownMenu.CheckboxItem>
149+ // );
150+ // }) }
151+ // </DropdownMenu.Content>
152+ // </DropdownMenu>
153+ // <DropdownMenu>
154+ // <DropdownMenu.Trigger asChild>
155+ // <Button className="flex items-center gap-2" variant="outline">
156+ // Filters
157+ // <ChevronDownIcon />
158+ // </Button>
159+ // </DropdownMenu.Trigger>
160+ // <DropdownMenu.Content widthFull align="start">
161+ // {statuses.map((option) => (
162+ // <DropdownMenu.CheckboxItem
163+ // checked={filterValue.includes(option)}
164+ // className="capitalize"
165+ // key={option}
166+ // onCheckedChange={(checked) => {
167+ // statusColumn.setFilterValue((prevValue: PaymentStatus[]) => {
168+ // if (checked) {
169+ // return [...prevValue, option];
170+ // }
171+ // return prevValue.filter((item) => item !== option);
172+ // });
173+ // }}
174+ // >
175+ // {option}
176+ // </DropdownMenu.CheckboxItem>
177+ // ))}
178+ // </DropdownMenu.Content>
179+ // </DropdownMenu>
180+ // </>
181+ // );
182+ } ;
183+
184+ const MasterDataTable = ( { data, onSelect } : MasterDataTableProps ) => {
185+ const { t } = useTranslation ( ) ;
186+ const subjectIdDisplaySetting = useAppStore ( ( store ) => store . currentGroup ?. settings . subjectIdDisplayLength ) ;
187+
188+ return (
189+ < div >
190+ < DataTable
191+ columns = { [
192+ {
193+ accessorFn : ( subject ) => removeSubjectIdScope ( subject . id ) . slice ( 0 , subjectIdDisplaySetting ?? 9 ) ,
194+ header : t ( 'datahub.index.table.subject' ) ,
195+ id : 'subjectId'
196+ } ,
197+ {
198+ accessorFn : ( subject ) => ( subject . dateOfBirth ? toBasicISOString ( new Date ( subject . dateOfBirth ) ) : 'NULL' ) ,
199+ header : t ( 'core.identificationData.dateOfBirth.label' ) ,
200+ id : 'date-of-birth'
201+ } ,
202+ {
203+ accessorFn : ( subject ) => {
204+ switch ( subject . sex ) {
205+ case 'FEMALE' :
206+ return t ( 'core.identificationData.sex.female' ) ;
207+ case 'MALE' :
208+ return t ( 'core.identificationData.sex.male' ) ;
209+ default :
210+ return 'NULL' ;
211+ }
212+ } ,
213+ header : t ( 'core.identificationData.sex.label' ) ,
214+ id : 'sex'
215+ }
216+ ] }
217+ data = { data }
218+ data-testid = "master-data-table"
219+ rowActions = { [
220+ {
221+ label : t ( { en : 'View' , fr : 'Voir' } ) ,
222+ onSelect
223+ }
224+ ] }
225+ togglesComponent = { Toggles }
226+ onSearchChange = { ( value , table ) => {
227+ const subjectIdColumn = table . getColumn ( 'subjectId' ) ! ;
228+ subjectIdColumn . setFilterValue ( value ) ;
229+ } }
230+ />
231+ </ div >
232+ ) ;
233+ } ;
234+
235+ const RouteComponent = ( ) => {
236+ const [ isLookupOpen , setIsLookupOpen ] = useState ( false ) ;
237+
238+ const currentGroup = useAppStore ( ( store ) => store . currentGroup ) ;
239+ const currentUser = useAppStore ( ( store ) => store . currentUser ) ;
240+
241+ const { t } = useTranslation ( ) ;
242+ const navigate = useNavigate ( ) ;
243+
244+ const { data } = useSubjectsQuery ( { params : { groupId : currentGroup ?. id } } ) ;
245+ const [ tableData , setTableData ] = useState < Subject [ ] > ( data ?? [ ] ) ;
246+ const [ searchString , setSearchString ] = useState ( '' ) ;
247+
248+ // const lookupSubject = async ({ id }: { id: string }) => {
249+ // const response = await axios.get<Subject>(`/v1/subjects/${id}`, {
250+ // validateStatus: (status) => status === 200 || status === 404
251+ // });
252+ // if (response.status === 404) {
253+ // addNotification({ message: t('core.notFound'), type: 'warning' });
254+ // setIsLookupOpen(false);
255+ // } else {
256+ // addNotification({ type: 'success' });
257+ // await navigate({ to: `./${response.data.id}/table` });
258+ // }
259+ // };
175260
176- useEffect ( ( ) => {
177- const definedTableData = data ?? [ ] ;
261+ // useEffect(() => {
262+ // const definedTableData = data ?? [];
178263
179- if ( ! searchString ) {
180- setTableData ( definedTableData ) ;
181- return ;
182- }
264+ // if (!searchString) {
265+ // setTableData(definedTableData);
266+ // return;
267+ // }
183268
184- const filtered = data . filter ( ( record ) =>
185- removeSubjectIdScope ( record . id ) . toLowerCase ( ) . includes ( searchString . toLowerCase ( ) )
186- ) ;
269+ // const filtered = data.filter((record) =>
270+ // removeSubjectIdScope(record.id).toLowerCase().includes(searchString.toLowerCase())
271+ // );
187272
188- setTableData ( filtered ) ;
189- } , [ searchString , data ] ) ;
273+ // setTableData(filtered);
274+ // }, [searchString, data]);
190275
191276 return (
192277 < React . Fragment >
@@ -233,14 +318,14 @@ const RouteComponent = () => {
233318 </ Dialog . Content >
234319 </ Dialog >
235320 < div className = "flex min-w-60 gap-2 lg:shrink" >
236- < ActionDropdown
321+ { /* <ActionDropdown
237322 widthFull
238323 data-spotlight-type="export-data-dropdown"
239324 data-testid="datahub-export-dropdown"
240325 options={['CSV', 'JSON', 'Excel']}
241326 title={t('datahub.index.table.export')}
242327 onSelection={handleExportSelection}
243- />
328+ /> */ }
244329 </ div >
245330 </ div >
246331 < MasterDataTable
0 commit comments