Skip to content

Commit decc711

Browse files
committed
feat: refresh content by selected revision for dataset page
1 parent c3cb541 commit decc711

File tree

5 files changed

+99
-25
lines changed

5 files changed

+99
-25
lines changed

src/components/DatasetDetailPage/MetaDataPanel.tsx

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ type Props = {
1818
datasetDocument: any;
1919
dbName: string | undefined;
2020
docId: string | undefined;
21+
// NEW:
22+
currentRev?: string; // from URL (?rev=...)
23+
onChangeRev?: (rev?: string | null) => void; // to update URL
24+
revsList?: { rev: string }[];
2125
};
2226

2327
type RevInfo = { rev: string };
@@ -27,16 +31,37 @@ const MetaDataPanel: React.FC<Props> = ({
2731
datasetDocument,
2832
dbName,
2933
docId,
34+
currentRev,
35+
onChangeRev,
36+
revsList = [], // default empty
3037
}) => {
31-
const revs: RevInfo[] = useMemo(
32-
() =>
33-
Array.isArray(datasetDocument?.["_revs_info"])
34-
? (datasetDocument!["_revs_info"] as RevInfo[])
35-
: [],
36-
[datasetDocument]
37-
);
38-
const [revIdx, setRevIdx] = useState(0);
38+
// const revs: RevInfo[] = useMemo(
39+
// () =>
40+
// Array.isArray(datasetDocument?.["_revs_info"])
41+
// ? (datasetDocument!["_revs_info"] as RevInfo[])
42+
// : [],
43+
// [datasetDocument]
44+
// );
45+
const revs = revsList;
46+
47+
// derive index from currentRev; fallback to 0 (latest)
48+
const deriveIdx = React.useCallback((revList: RevInfo[], cur?: string) => {
49+
if (!revList.length) return 0;
50+
if (!cur) return 0;
51+
const idx = revList.findIndex((r) => r.rev === cur);
52+
return idx >= 0 ? idx : 0;
53+
}, []);
54+
55+
const [revIdx, setRevIdx] = useState<number>(deriveIdx(revs, currentRev));
56+
57+
// keep local idx synced when URL rev or list changes
58+
React.useEffect(() => {
59+
setRevIdx(deriveIdx(revs, currentRev));
60+
}, [revs, currentRev, deriveIdx]);
61+
3962
const selected = revs[revIdx];
63+
// const [revIdx, setRevIdx] = useState(0);
64+
// const selected = revs[revIdx];
4065

4166
return (
4267
<Box
@@ -191,7 +216,14 @@ const MetaDataPanel: React.FC<Props> = ({
191216
labelId="rev-select-label"
192217
label="Select revision"
193218
value={revIdx}
194-
onChange={(e) => setRevIdx(Number(e.target.value))}
219+
onChange={(e) => {
220+
const idx = Number(e.target.value);
221+
setRevIdx(idx);
222+
const chosen = revs[idx]?.rev;
223+
// update URL -> parent will refetch with ?rev=chosen
224+
onChangeRev?.(chosen || null);
225+
}}
226+
// onChange={(e) => setRevIdx(Number(e.target.value))}
195227
>
196228
{revs.map((r, idx) => {
197229
const [verNum, hash] = r.rev.split("-", 2);

src/pages/SearchPage.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ const SearchPage: React.FC = () => {
7777
const [showMobileFilters, setShowMobileFilters] = useState(false);
7878
const theme = useTheme();
7979
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
80+
const upMd = useMediaQuery(theme.breakpoints.up("md"));
81+
82+
const placement = upMd ? "right" : "top";
8083

8184
// for database card
8285
const keywordInput = String(formData?.keyword ?? "").trim();
@@ -589,14 +592,12 @@ const SearchPage: React.FC = () => {
589592
<Typography variant="h6">Suggested databases</Typography>
590593

591594
<ClickTooltip
592-
placement="right"
593-
// enterTouchDelay={0}
594-
// leaveTouchDelay={300}
595+
placement={placement}
595596
componentsProps={{
596597
tooltip: {
597598
sx: {
598-
bgcolor: "#fff", // solid white background
599-
color: Colors.darkPurple, // dark text
599+
bgcolor: "#fff",
600+
color: Colors.darkPurple,
600601
border: `1px solid ${Colors.lightGray}`,
601602
boxShadow: 3,
602603
maxWidth: { sm: 200, md: 400 },

src/pages/UpdatedDatasetDetailPage.tsx

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import CloudDownloadIcon from "@mui/icons-material/CloudDownload";
33
import DescriptionIcon from "@mui/icons-material/Description";
44
import ExpandLess from "@mui/icons-material/ExpandLess";
55
import ExpandMore from "@mui/icons-material/ExpandMore";
6-
// import FolderIcon from "@mui/icons-material/Folder";
76
import HomeIcon from "@mui/icons-material/Home";
87
import {
98
Box,
@@ -27,12 +26,13 @@ import { useAppDispatch } from "hooks/useAppDispatch";
2726
import { useAppSelector } from "hooks/useAppSelector";
2827
import React, { useEffect, useMemo, useState } from "react";
2928
// import ReactJson from "react-json-view";
30-
import { useParams, useNavigate } from "react-router-dom";
29+
import { useParams, useNavigate, useSearchParams } from "react-router-dom";
3130
import {
3231
fetchDocumentDetails,
3332
fetchDbInfoByDatasetId,
3433
} from "redux/neurojson/neurojson.action";
3534
import { NeurojsonSelector } from "redux/neurojson/neurojson.selector";
35+
import { NeurojsonService } from "services/neurojson.service";
3636
import RoutesEnum from "types/routes.enum";
3737

3838
interface ExternalDataLink {
@@ -54,6 +54,19 @@ interface InternalDataLink {
5454
const UpdatedDatasetDetailPage: React.FC = () => {
5555
const { dbName, docId } = useParams<{ dbName: string; docId: string }>();
5656
const navigate = useNavigate();
57+
// for revision
58+
const [searchParams, setSearchParams] = useSearchParams();
59+
const rev = searchParams.get("rev") || undefined;
60+
61+
const handleSelectRevision = (newRev?: string | null) => {
62+
setSearchParams((prev) => {
63+
const p = new URLSearchParams(prev);
64+
if (newRev) p.set("rev", newRev);
65+
else p.delete("rev");
66+
return p;
67+
});
68+
};
69+
5770
const dispatch = useAppDispatch();
5871
const {
5972
selectedDocument: datasetDocument,
@@ -257,10 +270,21 @@ const UpdatedDatasetDetailPage: React.FC = () => {
257270
if (!dbName || !docId) return;
258271

259272
(async () => {
260-
await dispatch(fetchDocumentDetails({ dbName, docId })); // render tree ASAP
261-
dispatch(fetchDbInfoByDatasetId({ dbName, docId })); // don't await
273+
await dispatch(fetchDocumentDetails({ dbName, docId, rev })); // for dataset detail
274+
dispatch(fetchDbInfoByDatasetId({ dbName, docId })); // for metadata panel (include modality)
262275
})();
263-
}, [dbName, docId, dispatch]);
276+
}, [dbName, docId, rev, dispatch]);
277+
// for revs list storage
278+
const [revsList, setRevsList] = React.useState<{ rev: string }[]>([]);
279+
280+
useEffect(() => {
281+
const fromDoc = Array.isArray(datasetDocument?._revs_info)
282+
? (datasetDocument._revs_info as { rev: string }[])
283+
: [];
284+
if (fromDoc.length && revsList.length === 0) {
285+
setRevsList(fromDoc);
286+
}
287+
}, [datasetDocument, revsList.length]);
264288

265289
useEffect(() => {
266290
if (datasetDocument) {
@@ -840,6 +864,10 @@ const UpdatedDatasetDetailPage: React.FC = () => {
840864
dbViewInfo={dbViewInfo}
841865
dbName={dbName}
842866
docId={docId}
867+
// new props:
868+
currentRev={rev} // reflect URL selection
869+
onChangeRev={handleSelectRevision}
870+
revsList={revsList}
843871
/>
844872
</Box>
845873
</Box>

src/redux/neurojson/neurojson.action.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,15 @@ export const loadAllDocuments = createAsyncThunk(
6969
}
7070
);
7171

72+
// fetch dataset detail for dataset detail page
7273
export const fetchDocumentDetails = createAsyncThunk(
7374
"neurojson/fetchDocumentDetails",
7475
async (
75-
{ dbName, docId }: { dbName: string; docId: string },
76+
{ dbName, docId, rev }: { dbName: string; docId: string; rev?: string },
7677
{ rejectWithValue }
7778
) => {
7879
try {
79-
const data = await NeurojsonService.getDocumentById(dbName, docId);
80+
const data = await NeurojsonService.getDocumentById(dbName, docId, rev);
8081
return data;
8182
} catch (error: any) {
8283
return rejectWithValue("Failed to fetch document details.");
@@ -108,6 +109,7 @@ export const fetchMetadataSearchResults = createAsyncThunk(
108109
}
109110
);
110111

112+
// fetch data for metadata panel in dataset detail page
111113
export const fetchDbInfoByDatasetId = createAsyncThunk(
112114
"neurojson/fetchDbInfoByDatasetId",
113115
async (

src/services/neurojson.service.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,22 @@ export const NeurojsonService = {
2828

2929
return response.data;
3030
},
31-
getDocumentById: async (dbName: string, documentId: string): Promise<any> => {
31+
getDocumentById: async (
32+
dbName: string,
33+
documentId: string,
34+
rev?: string
35+
): Promise<any> => {
3236
try {
33-
const response = await api.get(
34-
`${baseURL}/${dbName}/${documentId}?revs_info=true`
35-
);
37+
const url = `${baseURL}/${dbName}/${documentId}`;
38+
// const response = await api.get(
39+
// `${baseURL}/${dbName}/${documentId}?revs_info=true`
40+
// );
41+
const response = await api.get(url, {
42+
params: {
43+
revs_info: true,
44+
...(rev ? { rev } : {}), // add ?rev=... only when provided
45+
},
46+
});
3647
return response.data;
3748
} catch (error) {
3849
console.error(

0 commit comments

Comments
 (0)