11import { generateSchemaWithDatabaseEnum } from "./searchformSchema" ;
2+ import ArrowCircleRightIcon from "@mui/icons-material/ArrowCircleRight" ;
23import {
34 Typography ,
45 Container ,
@@ -14,6 +15,7 @@ import SubjectCard from "components/SearchPage/SubjectCard";
1415import { Colors } from "design/theme" ;
1516import { useAppDispatch } from "hooks/useAppDispatch" ;
1617import { useAppSelector } from "hooks/useAppSelector" ;
18+ import pako from "pako" ;
1719import React from "react" ;
1820import { useState , useEffect , useMemo } from "react" ;
1921import {
@@ -40,6 +42,41 @@ const SearchPage: React.FC = () => {
4042 > ( [ ] ) ;
4143 const [ skip , setSkip ] = useState ( 0 ) ;
4244 const [ page , setPage ] = useState ( 1 ) ;
45+ const [ queryLink , setQueryLink ] = useState ( "" ) ;
46+
47+ // parse query from url on page load
48+ useEffect ( ( ) => {
49+ const hash = window . location . hash ;
50+ if ( hash . startsWith ( "#query=" ) ) {
51+ const encoded = hash . replace ( "#query=" , "" ) ;
52+ try {
53+ const decoded = pako . inflate (
54+ Uint8Array . from ( atob ( encoded ) , ( c ) => c . charCodeAt ( 0 ) ) ,
55+ { to : "string" }
56+ ) ;
57+ const parsed = JSON . parse ( decoded ) ;
58+ setFormData ( parsed ) ;
59+ const requestData = { ...parsed , skip : 0 } ;
60+ setSkip ( 0 ) ;
61+ setHasSearched ( true ) ;
62+ dispatch ( fetchMetadataSearchResults ( requestData ) ) . then ( ( res : any ) => {
63+ if ( res . payload ) {
64+ setResults ( res . payload ) ;
65+ }
66+ } ) ;
67+ } catch ( e ) {
68+ console . error ( "Failed to parse query from URL" , e ) ;
69+ }
70+ }
71+ } , [ dispatch ] ) ;
72+
73+ // generate a direct link to the query
74+ const updateQueryLink = ( queryData : Record < string , any > ) => {
75+ const deflated = pako . deflate ( JSON . stringify ( queryData ) ) ;
76+ const encoded = btoa ( String . fromCharCode ( ...deflated ) ) ;
77+ const link = `${ window . location . origin } ${ window . location . pathname } #query=${ encoded } ` ;
78+ setQueryLink ( link ) ;
79+ } ;
4380
4481 // setting pagination
4582 const itemsPerPage = 10 ;
@@ -51,10 +88,6 @@ const SearchPage: React.FC = () => {
5188 setPage ( value ) ;
5289 } ;
5390
54- // const paginatedResults = Array.isArray(searchResults)
55- // ? searchResults.slice((page - 1) * itemsPerPage, page * itemsPerPage)
56- // : [];
57-
5891 const paginatedResults = Array . isArray ( results )
5992 ? results . slice ( ( page - 1 ) * itemsPerPage , page * itemsPerPage )
6093 : [ ] ;
@@ -168,6 +201,16 @@ const SearchPage: React.FC = () => {
168201 ? activeStyle
169202 : { }
170203 : hiddenStyle ,
204+ session_name : showSubjectFilters
205+ ? formData [ "session_name" ]
206+ ? activeStyle
207+ : { }
208+ : hiddenStyle ,
209+ run_name : showSubjectFilters
210+ ? formData [ "run_name" ]
211+ ? activeStyle
212+ : { }
213+ : hiddenStyle ,
171214
172215 "ui:submitButtonOptions" : {
173216 props : {
@@ -209,18 +252,18 @@ const SearchPage: React.FC = () => {
209252 } ;
210253
211254 // print the result in dev tool
212- if ( Array . isArray ( searchResults ) ) {
213- searchResults . forEach ( ( item , idx ) => {
214- try {
215- const parsed = JSON . parse ( item . json ) ;
216- console . log ( `Result #${ idx } :` , { ...item , parsedJson : parsed } ) ;
217- } catch ( e ) {
218- console . error ( `Failed to parse JSON for item #${ idx } ` , e ) ;
219- }
220- } ) ;
221- } else {
222- console . warn ( "searchResults is not an array:" , searchResults ) ;
223- }
255+ // if (Array.isArray(searchResults)) {
256+ // searchResults.forEach((item, idx) => {
257+ // try {
258+ // const parsed = JSON.parse(item.json);
259+ // console.log(`Result #${idx}:`, { ...item, parsedJson: parsed });
260+ // } catch (e) {
261+ // console.error(`Failed to parse JSON for item #${idx}`, e);
262+ // }
263+ // });
264+ // } else {
265+ // console.warn("searchResults is not an array:", searchResults);
266+ // }
224267
225268 // determine the results are subject-level or dataset-level
226269 let isDataset : boolean | null = null ;
@@ -249,7 +292,6 @@ const SearchPage: React.FC = () => {
249292
250293 // submit function
251294 const handleSubmit = ( { formData } : any ) => {
252- // dispatch(fetchMetadataSearchResults(formData));
253295 const requestData = { ...formData , skip : 0 } ;
254296 setFormData ( requestData ) ;
255297 setSkip ( 0 ) ;
@@ -258,6 +300,7 @@ const SearchPage: React.FC = () => {
258300 } ) ;
259301 setHasSearched ( true ) ;
260302 setPage ( 1 ) ;
303+ updateQueryLink ( formData ) ;
261304 } ;
262305
263306 // reset function
@@ -313,6 +356,21 @@ const SearchPage: React.FC = () => {
313356 minWidth : "35%" ,
314357 } }
315358 >
359+ { queryLink && (
360+ < Box mt = { 2 } >
361+ < a
362+ href = { queryLink }
363+ target = "_blank"
364+ rel = "noopener noreferrer"
365+ style = { { textDecoration : "none" , color : Colors . purple } }
366+ >
367+ < Box component = "span" display = "inline-flex" alignItems = "center" >
368+ Direct Link to This Query
369+ < ArrowCircleRightIcon sx = { { marginLeft : 0.5 } } />
370+ </ Box >
371+ </ a >
372+ </ Box >
373+ ) }
316374 < Box
317375 sx = { {
318376 display : "flex" ,
@@ -397,15 +455,14 @@ const SearchPage: React.FC = () => {
397455 Loading search results...
398456 </ Typography >
399457 </ Box >
400- ) : Array . isArray ( results ) ? ( // change searchResults into results
458+ ) : Array . isArray ( results ) ? (
401459 < >
402460 < Typography
403461 variant = "h6"
404462 sx = { { borderBottom : "1px solid lightgray" , mb : 2 } }
405463 >
406- { results . length > 0 //change searchResults into results
464+ { results . length > 0
407465 ? `Showing ${ results . length } ${
408- //change searchResults into results
409466 isDataset ? "Datasets" : "Subjects"
410467 } `
411468 : `No matching ${
@@ -424,7 +481,6 @@ const SearchPage: React.FC = () => {
424481
425482 < Box textAlign = "center" mt = { 2 } mb = { 2 } >
426483 < Pagination
427- // count={Math.ceil(searchResults.length / itemsPerPage)}
428484 count = { Math . ceil ( results . length / itemsPerPage ) }
429485 page = { page }
430486 onChange = { handlePageChange }
@@ -451,8 +507,7 @@ const SearchPage: React.FC = () => {
451507 </ Box >
452508
453509 { results . length > 0 &&
454- paginatedResults . length > 0 && //change searchResults into results
455- // searchResults.slice(0, visibleCount)
510+ paginatedResults . length > 0 &&
456511 paginatedResults . map ( ( item , idx ) => {
457512 try {
458513 const parsedJson = JSON . parse ( item . json ) ;
@@ -489,7 +544,7 @@ const SearchPage: React.FC = () => {
489544 </ >
490545 ) : (
491546 < Typography sx = { { color : Colors . error } } >
492- { results ?. msg === "empty output" //change searchResults into results
547+ { results ?. msg === "empty output"
493548 ? "No results found based on your criteria. Please adjust the filters and try again."
494549 : "Something went wrong. Please try again later." }
495550 </ Typography >
0 commit comments