From c3cb541abe31bc3731bb2ec1fb35ec329c12ed66 Mon Sep 17 00:00:00 2001 From: elainefan331 Date: Wed, 17 Sep 2025 12:12:42 -0400 Subject: [PATCH 1/3] feat: introduce suggested databases panel that show real time DB cards independently of results --- public/img/search_page/search.png | Bin 0 -> 38259 bytes src/components/SearchPage/ClickTooltip.tsx | 40 +++ src/components/SearchPage/DatabaseCard.tsx | 108 +++---- src/pages/SearchPage.tsx | 339 +++++++++++---------- 4 files changed, 268 insertions(+), 219 deletions(-) create mode 100644 public/img/search_page/search.png create mode 100644 src/components/SearchPage/ClickTooltip.tsx diff --git a/public/img/search_page/search.png b/public/img/search_page/search.png new file mode 100644 index 0000000000000000000000000000000000000000..65bc86d4d2aac2b577cdb072ddd01c668d887038 GIT binary patch literal 38259 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 z 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 XeB@tkjE&B_UEoDH>S$GsJ4O2s*EA(R literal 0 HcmV?d00001 diff --git a/src/components/SearchPage/ClickTooltip.tsx b/src/components/SearchPage/ClickTooltip.tsx new file mode 100644 index 0000000..4fb423b --- /dev/null +++ b/src/components/SearchPage/ClickTooltip.tsx @@ -0,0 +1,40 @@ +import { Box, Tooltip, ClickAwayListener, TooltipProps } from "@mui/material"; +import { useState, PropsWithChildren } from "react"; + +type ClickTooltipProps = PropsWithChildren<{ + title: TooltipProps["title"]; + placement?: TooltipProps["placement"]; + componentsProps?: TooltipProps["componentsProps"]; +}>; + +export default function ClickTooltip({ + title, + placement = "right", + componentsProps, + children, +}: ClickTooltipProps) { + const [open, setOpen] = useState(false); + const toggle = () => setOpen((o) => !o); + const close = () => setOpen(false); + + return ( + + + + {/* span to ensure Tooltip always has a single DOM child */} + {children} + + + + ); +} diff --git a/src/components/SearchPage/DatabaseCard.tsx b/src/components/SearchPage/DatabaseCard.tsx index 0a76afb..f1525e8 100644 --- a/src/components/SearchPage/DatabaseCard.tsx +++ b/src/components/SearchPage/DatabaseCard.tsx @@ -102,7 +102,18 @@ const DatabaseCard: React.FC = ({ }; return ( - + = ({ gap: 2, }} > - {/* Logo as Avatar */} - - {logo && ( - + + + {logo && ( + + )} + + - )} - - {/* database card */} - - - Database:{" "} - {highlightKeyword(fullName || "Untitled Database", keyword)} - - + component={Link} + to={databaseLink} + target="_blank" + > + {highlightKeyword(fullName || "Untitled Database", keyword)} + + + + = ({ {Array.isArray(modalities) && modalities.length > 0 ? ( modalities.map(renderDatatype) ) : ( - // ( - // modalities.map((mod, idx) => ( - // onChipClick("modality", mod)} - // sx={{ - // "& .MuiChip-label": { - // paddingX: "6px", - // fontSize: "0.8rem", - // }, - // height: "24px", - // color: Colors.darkPurple, - // border: `1px solid ${Colors.darkPurple}`, - // fontWeight: "bold", - // transition: "all 0.2s ease", - // "&:hover": { - // backgroundColor: `${Colors.purple} !important`, - // color: "white", - // borderColor: Colors.purple, - // }, - // }} - // /> - // )) - // ) N/A diff --git a/src/pages/SearchPage.tsx b/src/pages/SearchPage.tsx index 6ccf638..97ec99f 100644 --- a/src/pages/SearchPage.tsx +++ b/src/pages/SearchPage.tsx @@ -1,5 +1,6 @@ import { generateSchemaWithDatabaseEnum } from "../utils/SearchPageFunctions/searchformSchema"; import ArrowCircleRightIcon from "@mui/icons-material/ArrowCircleRight"; +import InfoOutlinedIcon from "@mui/icons-material/InfoOutlined"; import { Typography, Container, @@ -9,11 +10,14 @@ import { Pagination, Chip, Drawer, + Tooltip, + IconButton, } from "@mui/material"; import { useTheme } from "@mui/material/styles"; import useMediaQuery from "@mui/material/useMediaQuery"; import Form from "@rjsf/mui"; import validator from "@rjsf/validator-ajv8"; +import ClickTooltip from "components/SearchPage/ClickTooltip"; import DatabaseCard from "components/SearchPage/DatabaseCard"; import DatasetCard from "components/SearchPage/DatasetCard"; import SubjectCard from "components/SearchPage/SubjectCard"; @@ -77,14 +81,6 @@ const SearchPage: React.FC = () => { // for database card const keywordInput = String(formData?.keyword ?? "").trim(); const selectedDbId = String(formData?.database ?? "").trim(); - console.log("keyword", keywordInput); - - // const registryMatches: RegistryItem[] = React.useMemo(() => { - // if (!Array.isArray(registry) || !keywordInput) return []; - // return (registry as RegistryItem[]).filter((r) => - // matchesKeyword(r, keywordInput) - // ); - // }, [registry, keywordInput]); const registryMatches: RegistryItem[] = React.useMemo(() => { if (!Array.isArray(registry)) return []; @@ -299,6 +295,7 @@ const SearchPage: React.FC = () => { { }, }} > - Submit + Search - - ) - : null} - - - - - - {results.length > 0 && - paginatedResults.length > 0 && - paginatedResults.map((item, idx) => { - try { - const parsedJson = JSON.parse(item.json); - const globalIndex = (page - 1) * itemsPerPage + idx; - - const isDataset = - parsedJson?.value?.subj && - Array.isArray(parsedJson.value.subj); - - return isDataset ? ( - - ) : ( - - ); - } catch (e) { - console.error( - `Failed to parse JSON for item #${idx}`, - e - ); - return null; - } - })} - - ) : ( - - {results?.msg === "empty output" - ? "No results found based on your criteria. Please adjust the filters and try again." - : "Something went wrong. Please try again later."} - - )} - - )} */} {/* mobile version filters */} From decc7117d07bd45bc7948e8de2c1fb8dfed14827 Mon Sep 17 00:00:00 2001 From: elainefan331 Date: Wed, 17 Sep 2025 13:53:02 -0400 Subject: [PATCH 2/3] feat: refresh content by selected revision for dataset page --- .../DatasetDetailPage/MetaDataPanel.tsx | 50 +++++++++++++++---- src/pages/SearchPage.tsx | 11 ++-- src/pages/UpdatedDatasetDetailPage.tsx | 38 ++++++++++++-- src/redux/neurojson/neurojson.action.ts | 6 ++- src/services/neurojson.service.ts | 19 +++++-- 5 files changed, 99 insertions(+), 25 deletions(-) diff --git a/src/components/DatasetDetailPage/MetaDataPanel.tsx b/src/components/DatasetDetailPage/MetaDataPanel.tsx index ad63381..b4b7573 100644 --- a/src/components/DatasetDetailPage/MetaDataPanel.tsx +++ b/src/components/DatasetDetailPage/MetaDataPanel.tsx @@ -18,6 +18,10 @@ type Props = { datasetDocument: any; dbName: string | undefined; docId: string | undefined; + // NEW: + currentRev?: string; // from URL (?rev=...) + onChangeRev?: (rev?: string | null) => void; // to update URL + revsList?: { rev: string }[]; }; type RevInfo = { rev: string }; @@ -27,16 +31,37 @@ const MetaDataPanel: React.FC = ({ datasetDocument, dbName, docId, + currentRev, + onChangeRev, + revsList = [], // default empty }) => { - const revs: RevInfo[] = useMemo( - () => - Array.isArray(datasetDocument?.["_revs_info"]) - ? (datasetDocument!["_revs_info"] as RevInfo[]) - : [], - [datasetDocument] - ); - const [revIdx, setRevIdx] = useState(0); + // const revs: RevInfo[] = useMemo( + // () => + // Array.isArray(datasetDocument?.["_revs_info"]) + // ? (datasetDocument!["_revs_info"] as RevInfo[]) + // : [], + // [datasetDocument] + // ); + const revs = revsList; + + // derive index from currentRev; fallback to 0 (latest) + const deriveIdx = React.useCallback((revList: RevInfo[], cur?: string) => { + if (!revList.length) return 0; + if (!cur) return 0; + const idx = revList.findIndex((r) => r.rev === cur); + return idx >= 0 ? idx : 0; + }, []); + + const [revIdx, setRevIdx] = useState(deriveIdx(revs, currentRev)); + + // keep local idx synced when URL rev or list changes + React.useEffect(() => { + setRevIdx(deriveIdx(revs, currentRev)); + }, [revs, currentRev, deriveIdx]); + const selected = revs[revIdx]; + // const [revIdx, setRevIdx] = useState(0); + // const selected = revs[revIdx]; return ( = ({ labelId="rev-select-label" label="Select revision" value={revIdx} - onChange={(e) => setRevIdx(Number(e.target.value))} + onChange={(e) => { + const idx = Number(e.target.value); + setRevIdx(idx); + const chosen = revs[idx]?.rev; + // update URL -> parent will refetch with ?rev=chosen + onChangeRev?.(chosen || null); + }} + // onChange={(e) => setRevIdx(Number(e.target.value))} > {revs.map((r, idx) => { const [verNum, hash] = r.rev.split("-", 2); diff --git a/src/pages/SearchPage.tsx b/src/pages/SearchPage.tsx index 97ec99f..f0e4b91 100644 --- a/src/pages/SearchPage.tsx +++ b/src/pages/SearchPage.tsx @@ -77,6 +77,9 @@ const SearchPage: React.FC = () => { const [showMobileFilters, setShowMobileFilters] = useState(false); const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down("sm")); + const upMd = useMediaQuery(theme.breakpoints.up("md")); + + const placement = upMd ? "right" : "top"; // for database card const keywordInput = String(formData?.keyword ?? "").trim(); @@ -589,14 +592,12 @@ const SearchPage: React.FC = () => { Suggested databases { const { dbName, docId } = useParams<{ dbName: string; docId: string }>(); const navigate = useNavigate(); + // for revision + const [searchParams, setSearchParams] = useSearchParams(); + const rev = searchParams.get("rev") || undefined; + + const handleSelectRevision = (newRev?: string | null) => { + setSearchParams((prev) => { + const p = new URLSearchParams(prev); + if (newRev) p.set("rev", newRev); + else p.delete("rev"); + return p; + }); + }; + const dispatch = useAppDispatch(); const { selectedDocument: datasetDocument, @@ -257,10 +270,21 @@ const UpdatedDatasetDetailPage: React.FC = () => { if (!dbName || !docId) return; (async () => { - await dispatch(fetchDocumentDetails({ dbName, docId })); // render tree ASAP - dispatch(fetchDbInfoByDatasetId({ dbName, docId })); // don't await + await dispatch(fetchDocumentDetails({ dbName, docId, rev })); // for dataset detail + dispatch(fetchDbInfoByDatasetId({ dbName, docId })); // for metadata panel (include modality) })(); - }, [dbName, docId, dispatch]); + }, [dbName, docId, rev, dispatch]); + // for revs list storage + const [revsList, setRevsList] = React.useState<{ rev: string }[]>([]); + + useEffect(() => { + const fromDoc = Array.isArray(datasetDocument?._revs_info) + ? (datasetDocument._revs_info as { rev: string }[]) + : []; + if (fromDoc.length && revsList.length === 0) { + setRevsList(fromDoc); + } + }, [datasetDocument, revsList.length]); useEffect(() => { if (datasetDocument) { @@ -840,6 +864,10 @@ const UpdatedDatasetDetailPage: React.FC = () => { dbViewInfo={dbViewInfo} dbName={dbName} docId={docId} + // new props: + currentRev={rev} // reflect URL selection + onChangeRev={handleSelectRevision} + revsList={revsList} /> diff --git a/src/redux/neurojson/neurojson.action.ts b/src/redux/neurojson/neurojson.action.ts index 813cd29..c050ad8 100644 --- a/src/redux/neurojson/neurojson.action.ts +++ b/src/redux/neurojson/neurojson.action.ts @@ -69,14 +69,15 @@ export const loadAllDocuments = createAsyncThunk( } ); +// fetch dataset detail for dataset detail page export const fetchDocumentDetails = createAsyncThunk( "neurojson/fetchDocumentDetails", async ( - { dbName, docId }: { dbName: string; docId: string }, + { dbName, docId, rev }: { dbName: string; docId: string; rev?: string }, { rejectWithValue } ) => { try { - const data = await NeurojsonService.getDocumentById(dbName, docId); + const data = await NeurojsonService.getDocumentById(dbName, docId, rev); return data; } catch (error: any) { return rejectWithValue("Failed to fetch document details."); @@ -108,6 +109,7 @@ export const fetchMetadataSearchResults = createAsyncThunk( } ); +// fetch data for metadata panel in dataset detail page export const fetchDbInfoByDatasetId = createAsyncThunk( "neurojson/fetchDbInfoByDatasetId", async ( diff --git a/src/services/neurojson.service.ts b/src/services/neurojson.service.ts index 8e5b706..fe6859d 100644 --- a/src/services/neurojson.service.ts +++ b/src/services/neurojson.service.ts @@ -28,11 +28,22 @@ export const NeurojsonService = { return response.data; }, - getDocumentById: async (dbName: string, documentId: string): Promise => { + getDocumentById: async ( + dbName: string, + documentId: string, + rev?: string + ): Promise => { try { - const response = await api.get( - `${baseURL}/${dbName}/${documentId}?revs_info=true` - ); + const url = `${baseURL}/${dbName}/${documentId}`; + // const response = await api.get( + // `${baseURL}/${dbName}/${documentId}?revs_info=true` + // ); + const response = await api.get(url, { + params: { + revs_info: true, + ...(rev ? { rev } : {}), // add ?rev=... only when provided + }, + }); return response.data; } catch (error) { console.error( From c176b90f2b13a399711827727acfde2e942f0f24 Mon Sep 17 00:00:00 2001 From: elainefan331 Date: Thu, 18 Sep 2025 15:18:58 -0400 Subject: [PATCH 3/3] style: update the search results border line to make it align with the suggested databases --- src/pages/SearchPage.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/pages/SearchPage.tsx b/src/pages/SearchPage.tsx index f0e4b91..ef303a2 100644 --- a/src/pages/SearchPage.tsx +++ b/src/pages/SearchPage.tsx @@ -719,10 +719,8 @@ const SearchPage: React.FC = () => { )} {hasSearched && (