From d7176a3257aa3ccb4e8df54fc1a82776c74898ca Mon Sep 17 00:00:00 2001 From: elainefan331 Date: Tue, 14 Apr 2026 10:18:16 -0400 Subject: [PATCH 1/8] fix: support double-click to reset uPlot series on Mac --- src/pages/UpdatedDatasetDetailPage.tsx | 2 +- src/utils/preview.js | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/pages/UpdatedDatasetDetailPage.tsx b/src/pages/UpdatedDatasetDetailPage.tsx index 52f87ca..67b3cb6 100644 --- a/src/pages/UpdatedDatasetDetailPage.tsx +++ b/src/pages/UpdatedDatasetDetailPage.tsx @@ -1568,7 +1568,7 @@ const UpdatedDatasetDetailPage: React.FC = () => { style={{ display: "none", marginTop: "16px", - background: Colors.darkGray, + background: Colors.lightGray, color: Colors.black, padding: "12px", borderRadius: "8px", diff --git a/src/utils/preview.js b/src/utils/preview.js index 02f3908..dbb1c56 100644 --- a/src/utils/preview.js +++ b/src/utils/preview.js @@ -396,7 +396,7 @@ function dopreview(key, idx, isinternal, hastime) { $("#chartpanel").css("padding", "10px"); $("#chartpanel").show(); $("#chartpanel").html( - '

Data preview

×
' + '

Data preview

×
' ); if (dataroot instanceof nj.NdArray) { // console.log("dataroot", dataroot); @@ -445,6 +445,15 @@ function dopreview(key, idx, isinternal, hastime) { plotdata, document.getElementById("plotchart") ); + // Reset all series on double-click (works on both Mac and Windows) + uplotInstance.root.addEventListener("dblclick", (e) => { + e.preventDefault(); + e.stopPropagation(); + uplotInstance.series.forEach((s, i) => { + if (i === 0) return; // skip x-axis + uplotInstance.setSeries(i, { show: true }); + }); + }); } else { // let u = new uPlot( // opts, From ad92d728277ff4f1ec4129b6656ce0ed51f46d71 Mon Sep 17 00:00:00 2001 From: elainefan331 Date: Thu, 16 Apr 2026 09:42:07 -0400 Subject: [PATCH 2/8] fix: strip markdown fences from BIDSPlan YAML string before saving --- .../DatasetOrganizer/utils/plannerHelpers.ts | 9 ++++++- src/utils/preview.js | 27 +++++++++++++------ 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/components/User/Dashboard/DatasetOrganizer/utils/plannerHelpers.ts b/src/components/User/Dashboard/DatasetOrganizer/utils/plannerHelpers.ts index 5b203e8..820c61f 100644 --- a/src/components/User/Dashboard/DatasetOrganizer/utils/plannerHelpers.ts +++ b/src/components/User/Dashboard/DatasetOrganizer/utils/plannerHelpers.ts @@ -858,7 +858,14 @@ export const buildBidsPlan = async ( } // Preserve raw YAML string for saving - const planYamlStr = raw.startsWith("```") ? planYaml._raw ?? raw : raw; + // const planYamlStr = raw.startsWith("```") ? planYaml._raw ?? raw : raw; + // Preserve raw YAML string for saving — strip markdown fences if present (mirrors planner.py Step 3) + let planYamlStr = raw.trim(); + if (planYamlStr.startsWith("```yaml")) planYamlStr = planYamlStr.slice(7); + else if (planYamlStr.startsWith("```")) + planYamlStr = planYamlStr.split("\n").slice(1).join("\n"); + if (planYamlStr.endsWith("```")) planYamlStr = planYamlStr.slice(0, -3); + planYamlStr = planYamlStr.trim(); log("✓ BIDSPlan complete"); return { diff --git a/src/utils/preview.js b/src/utils/preview.js index dbb1c56..3013967 100644 --- a/src/utils/preview.js +++ b/src/utils/preview.js @@ -398,6 +398,7 @@ function dopreview(key, idx, isinternal, hastime) { $("#chartpanel").html( '

Data preview

×
' ); + if (dataroot instanceof nj.NdArray) { // console.log("dataroot", dataroot); if (dataroot.shape[0] > dataroot.shape[1]) @@ -445,15 +446,16 @@ function dopreview(key, idx, isinternal, hastime) { plotdata, document.getElementById("plotchart") ); + // Reset all series on double-click (works on both Mac and Windows) - uplotInstance.root.addEventListener("dblclick", (e) => { - e.preventDefault(); - e.stopPropagation(); - uplotInstance.series.forEach((s, i) => { - if (i === 0) return; // skip x-axis - uplotInstance.setSeries(i, { show: true }); - }); - }); + // uplotInstance.root.addEventListener("dblclick", (e) => { + // e.preventDefault(); + // e.stopPropagation(); + // uplotInstance.series.forEach((s, i) => { + // if (i === 0) return; // skip x-axis + // uplotInstance.setSeries(i, { show: true }); + // }); + // }); } else { // let u = new uPlot( // opts, @@ -469,6 +471,15 @@ function dopreview(key, idx, isinternal, hastime) { [[...Array(dataroot.length).keys()], dataroot], document.getElementById("plotchart") ); + + // uplotInstance.root.addEventListener("dblclick", (e) => { + // e.preventDefault(); + // e.stopPropagation(); + // uplotInstance.series.forEach((s, i) => { + // if (i === 0) return; + // uplotInstance.setSeries(i, { show: true }); + // }); + // }); } // for spinner From 072db3dcfd57c566e245ce0d9b5115d1613c4f7d Mon Sep 17 00:00:00 2001 From: elainefan331 Date: Thu, 16 Apr 2026 10:24:02 -0400 Subject: [PATCH 3/8] fix: expand external data path segments and add 2D plot interaction tips --- src/pages/UpdatedDatasetDetailPage.tsx | 2 +- src/utils/preview.js | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/pages/UpdatedDatasetDetailPage.tsx b/src/pages/UpdatedDatasetDetailPage.tsx index 67b3cb6..db1236d 100644 --- a/src/pages/UpdatedDatasetDetailPage.tsx +++ b/src/pages/UpdatedDatasetDetailPage.tsx @@ -335,7 +335,7 @@ const UpdatedDatasetDetailPage: React.FC = () => { : "Unknown Size"; const parts = currentPath.split("/"); - const subpath = parts.slice(-3).join("/"); + const subpath = parts.slice(-6).join("/"); const label = parentKey || "ExternalData"; links.push({ diff --git a/src/utils/preview.js b/src/utils/preview.js index 3013967..d8721f8 100644 --- a/src/utils/preview.js +++ b/src/utils/preview.js @@ -396,7 +396,18 @@ function dopreview(key, idx, isinternal, hastime) { $("#chartpanel").css("padding", "10px"); $("#chartpanel").show(); $("#chartpanel").html( - '

Data preview

×
' + '

Data preview

×' + + '
' + + "Tips: " + + "Click a item to toggle a signal  | 
" + + "⌘+Click (Mac) / Ctrl+Click (Windows) to isolate one signal  |  " + + "Shift+Click to add more signals to the selection  |  " + + "Click and drag on the plot to zoom into a region  | " + + "Double-click to restore selected signals (Mac)  |  " + + "Double-click to restore all signals (Windows)  |  " + + "⌘+Click the same selected item to restore all signals (Mac)" + + "
" + + '
' ); if (dataroot instanceof nj.NdArray) { From 2fffdb9ed74de7ecd42805e0596a1904abc14fb3 Mon Sep 17 00:00:00 2001 From: elainefan331 Date: Thu, 16 Apr 2026 13:07:32 -0400 Subject: [PATCH 4/8] feat: show source path and index above 2D chart panel --- src/pages/UpdatedDatasetDetailPage.tsx | 50 ++++++++++++++++++++++---- src/utils/preview.js | 11 ++++-- 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/src/pages/UpdatedDatasetDetailPage.tsx b/src/pages/UpdatedDatasetDetailPage.tsx index db1236d..a5be12c 100644 --- a/src/pages/UpdatedDatasetDetailPage.tsx +++ b/src/pages/UpdatedDatasetDetailPage.tsx @@ -262,7 +262,7 @@ const UpdatedDatasetDetailPage: React.FC = () => { const [searchParams, setSearchParams] = useSearchParams(); const focus = searchParams.get("focus") || undefined; // get highlight from url const rev = searchParams.get("rev") || undefined; // get revision from url - + const [chart2DPreviewPath, setChart2DPreviewPath] = useState(""); const [externalLinks, setExternalLinks] = useState([]); const [internalLinks, setInternalLinks] = useState([]); const [isInternalExpanded, setIsInternalExpanded] = useState(true); @@ -284,6 +284,14 @@ const UpdatedDatasetDetailPage: React.FC = () => { ? rawSummary : Object.values(rawSummary).filter(Boolean).join("\n\n"); const readme = datasetDocument?.["README"] ?? ""; + + useEffect(() => { + window.__clear2DPath = () => setChart2DPreviewPath(""); + return () => { + delete window.__clear2DPath; + }; + }, []); + const handleSelectRevision = (newRev?: string | null) => { setSearchParams((prev) => { const p = new URLSearchParams(prev); // copy of the query url @@ -625,7 +633,9 @@ const UpdatedDatasetDetailPage: React.FC = () => { const handlePreview = ( dataOrUrl: string | any, idx: number, - isInternal: boolean = false + isInternal: boolean = false, + previewPath: string = "", + displayNumber?: number ) => { // console.log( // "🟢 Preview button clicked for:", @@ -635,6 +645,9 @@ const UpdatedDatasetDetailPage: React.FC = () => { // "Is Internal:", // isInternal // ); + setChart2DPreviewPath( + displayNumber ? `[${displayNumber}] ${previewPath}` : previewPath + ); // Clear any stale preview type from last run delete (window as any).__previewType; @@ -783,14 +796,14 @@ const UpdatedDatasetDetailPage: React.FC = () => { // Try internal data first const internal = internalMap.get(previewPath); if (internal) { - handlePreview(internal.data, internal.index, true); + handlePreview(internal.data, internal.index, true, previewPath); return; } // Then try external data by JSON path const external = linkMap.get(previewPath); if (external) { - handlePreview(external.url, external.index, false); + handlePreview(external.url, external.index, false, previewPath); } }, [ datasetDocument, @@ -1324,7 +1337,12 @@ const UpdatedDatasetDetailPage: React.FC = () => { }, }} onClick={() => - handlePreview(link.data, link.index, true) + handlePreview( + link.data, + link.index, + true, + link.path + ) } > Preview @@ -1463,7 +1481,7 @@ const UpdatedDatasetDetailPage: React.FC = () => { }} title={link.name} > - {link.name} + {index + 1}. {link.name}