Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added public/img/search_page/search.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
50 changes: 41 additions & 9 deletions src/components/DatasetDetailPage/MetaDataPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Expand All @@ -27,16 +31,37 @@ const MetaDataPanel: React.FC<Props> = ({
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<number>(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 (
<Box
Expand Down Expand Up @@ -191,7 +216,14 @@ const MetaDataPanel: React.FC<Props> = ({
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);
Expand Down
40 changes: 40 additions & 0 deletions src/components/SearchPage/ClickTooltip.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<ClickAwayListener onClickAway={close}>
<Box sx={{ display: "inline-flex" }}>
<Tooltip
open={open}
onClose={close}
disableFocusListener
disableHoverListener
disableTouchListener
placement={placement}
componentsProps={componentsProps}
title={title}
arrow
>
{/* span to ensure Tooltip always has a single DOM child */}
<span onClick={toggle}>{children}</span>
</Tooltip>
</Box>
</ClickAwayListener>
);
}
108 changes: 46 additions & 62 deletions src/components/SearchPage/DatabaseCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,18 @@ const DatabaseCard: React.FC<Props> = ({
};

return (
<Card sx={{ mb: 3, position: "relative" }}>
<Card
sx={{
mb: 3,
position: "relative",
transition: "all .2s ease",
borderStyle: "dashed",
borderColor: "divider",
backgroundColor: "#FCFCFF",
boxShadow: 0,
width: { xs: "350px", md: "200px" },
}}
>
<CardContent>
<Box
sx={{
Expand All @@ -113,45 +124,44 @@ const DatabaseCard: React.FC<Props> = ({
gap: 2,
}}
>
{/* Logo as Avatar */}
<Box sx={{ display: "flex", alignItems: "center" }}>
{logo && (
<Avatar
variant="square"
src={logo}
alt={fullName || "Database Logo"}
<Box>
<Box sx={{ display: "flex", gap: 1, alignItems: "flex-start" }}>
<Box sx={{ display: "flex", alignItems: "center" }}>
{logo && (
<Avatar
variant="square"
src={logo}
alt={fullName || "Database Logo"}
sx={{
width: 40,
height: 40,
mb: 1,
"& img": {
objectFit: "contain", // show full image inside
},
}}
/>
)}
</Box>
<Typography
sx={{
width: 60,
height: 60,
mb: 1,
"& img": {
objectFit: "contain", // show full image inside
},
fontWeight: 600,
color: Colors.darkPurple,
textDecoration: "none",
":hover": { textDecoration: "underline" },
}}
/>
)}
</Box>
{/* database card */}
<Box>
<Typography
variant="h6"
sx={{
fontWeight: 600,
color: Colors.darkPurple,
textDecoration: "none",
":hover": { textDecoration: "underline" },
}}
component={Link}
to={databaseLink}
target="_blank"
>
Database:{" "}
{highlightKeyword(fullName || "Untitled Database", keyword)}
</Typography>
<Stack spacing={2} margin={1}>
component={Link}
to={databaseLink}
target="_blank"
>
{highlightKeyword(fullName || "Untitled Database", keyword)}
</Typography>
</Box>

<Stack spacing={0.5}>
<Stack
direction="row"
spacing={1}
spacing={0.5}
flexWrap="wrap"
gap={1}
alignItems="center"
Expand All @@ -163,32 +173,6 @@ const DatabaseCard: React.FC<Props> = ({
{Array.isArray(modalities) && modalities.length > 0 ? (
modalities.map(renderDatatype)
) : (
// (
// modalities.map((mod, idx) => (
// <Chip
// key={idx}
// label={mod}
// variant="outlined"
// onClick={() => 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,
// },
// }}
// />
// ))
// )
<Typography variant="body2" mt={1}>
N/A
</Typography>
Expand Down
Loading