diff --git a/frontend/app/search/[bmid]/page.tsx b/frontend/app/search/[bmid]/page.tsx
index f589cce..cecdbbd 100644
--- a/frontend/app/search/[bmid]/page.tsx
+++ b/frontend/app/search/[bmid]/page.tsx
@@ -216,7 +216,10 @@ export default function BiomodelDetailPage() {
return (
-
+
@@ -286,13 +289,23 @@ export default function BiomodelDetailPage() {
-
+
-
+
Overview
-
+
AI Analysis
@@ -332,7 +345,7 @@ export default function BiomodelDetailPage() {
-
+
{/* Applications Section */}
@@ -347,7 +360,9 @@ export default function BiomodelDetailPage() {
{data.applications?.map((app) => {
- const encodedAppName = encodeURIComponent(app.name || "");
+ const encodedAppName = encodeURIComponent(
+ app.name || "",
+ );
const bnglUrl = `https://vcell.cam.uchc.edu/api/v0/biomodel/${data.bmKey}/biomodel.bngl?appname=${encodedAppName}`;
const sbmlUrl = `https://vcell.cam.uchc.edu/api/v0/biomodel/${data.bmKey}/biomodel.sbml?appname=${encodedAppName}`;
return (
@@ -389,7 +404,7 @@ export default function BiomodelDetailPage() {
-
+
{/* Simulations Section */}
@@ -440,7 +455,9 @@ export default function BiomodelDetailPage() {
{ov.name} ({ov.type}):{" "}
- {ov.values ? ov.values.join(", ") : "No values"}
+ {ov.values
+ ? ov.values.join(", ")
+ : "No values"}
{" "}
(Cardinality: {ov.cardinality})
diff --git a/frontend/app/search/page.tsx b/frontend/app/search/page.tsx
index b3e1184..ab5313e 100644
--- a/frontend/app/search/page.tsx
+++ b/frontend/app/search/page.tsx
@@ -1,6 +1,7 @@
"use client";
-import { useState } from "react";
+import { useEffect, useRef, useState } from "react";
+import { useRouter } from "next/navigation";
import {
Search,
Filter,
@@ -33,7 +34,6 @@ import {
CollapsibleContent,
CollapsibleTrigger,
} from "@/components/ui/collapsible";
-import Link from "next/link";
import { cn } from "@/lib/utils";
import { SignInOutButton } from "@/components/sign-in-out-button";
@@ -83,13 +83,44 @@ const defaultFilters: SearchFilters = {
orderBy: "date_desc",
};
+const SEARCH_STATE_KEY = "vcell-search-state";
+
export default function BiomodelSearchPage() {
+ const router = useRouter();
const [filters, setFilters] = useState(defaultFilters);
const [results, setResults] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const [hasSearched, setHasSearched] = useState(false);
const [isAdvancedSearchOpen, setIsAdvancedSearchOpen] = useState(false);
+ const isHydrated = useRef(false);
+
+ // Restore filters/results saved before navigating away (e.g. to a result's detail page)
+ useEffect(() => {
+ try {
+ const saved = sessionStorage.getItem(SEARCH_STATE_KEY);
+ if (saved) {
+ const parsed = JSON.parse(saved);
+ if (parsed.filters) setFilters(parsed.filters);
+ if (parsed.results) setResults(parsed.results);
+ if (typeof parsed.hasSearched === "boolean")
+ setHasSearched(parsed.hasSearched);
+ if (typeof parsed.isAdvancedSearchOpen === "boolean")
+ setIsAdvancedSearchOpen(parsed.isAdvancedSearchOpen);
+ }
+ } catch {
+ // ignore malformed/unavailable storage
+ }
+ isHydrated.current = true;
+ }, []);
+
+ useEffect(() => {
+ if (!isHydrated.current) return;
+ sessionStorage.setItem(
+ SEARCH_STATE_KEY,
+ JSON.stringify({ filters, results, hasSearched, isAdvancedSearchOpen }),
+ );
+ }, [filters, results, hasSearched, isAdvancedSearchOpen]);
const handleSearch = async () => {
setIsLoading(true);
@@ -167,8 +198,8 @@ export default function BiomodelSearchPage() {
Biomodel Database Search
- Search and explore biomodels from the VCell database with advanced
- filtering options.
+ Search and explore biomodels from the VCell database with
+ advanced filtering options.
@@ -460,78 +491,82 @@ export default function BiomodelSearchPage() {
{results.map((model) => (
-
{
+ const selection = window.getSelection();
+ if (selection && selection.toString().length > 0) {
+ return;
+ }
+ router.push(`/search/${model.bmId}`);
+ }}
+ className="group shadow-sm border-slate-200 hover:border-blue-300 hover:shadow-md transition-all cursor-pointer"
>
-
-
-
-
- {model.privacy === 1 ? (
-
- ) : (
-
- )}
+
+
+
+ {model.privacy === 1 ? (
+
+ ) : (
+
+ )}
+
+
+
-
-
-
- {model.annot || "No description available."}
-
+
+ {model.annot || "No description available."}
+
-
-
-
- {model.ownerName}
-
-
-
- {formatDate(model.savedDate)}
-
-
-
- {model.simulations} simulation
- {model.simulations === 1 ? "" : "s"}
-
-
-
- {model.bmId}
+
+
+
+ {model.ownerName}
+
+
+
+ {formatDate(model.savedDate)}
+
+
+
+ {model.simulations} simulation
+ {model.simulations === 1 ? "" : "s"}
+
+
+
+ {model.bmId}
+
+
+
+ {model.groupUsers.length > 0 && (
+
+
+ Shared with:
+ {model.groupUsers.map((user, index) => (
+
+ {user}
+
+ ))}
-
- {model.groupUsers.length > 0 && (
-
-
- Shared with:
-
- {model.groupUsers.map((user, index) => (
-
- {user}
-
- ))}
-
- )}
-
+ )}
-
-
-
+
+
+
))}
diff --git a/frontend/components/ChatBox.tsx b/frontend/components/ChatBox.tsx
index 944bcf7..61e4999 100644
--- a/frontend/components/ChatBox.tsx
+++ b/frontend/components/ChatBox.tsx
@@ -126,7 +126,7 @@ export const ChatBox: React.FC
= ({
const db_link = `[Database](/search/${bmId})`;
const replacementString = `**${bmId}** -- ${ai_link} | ${db_link}`; */
const db_link = `[Database Details](/search/${bmId})`;
- const replacementString = `**${bmId}** || ${db_link}`;
+ const replacementString = `**${bmId}**`;
const idRegex = new RegExp(`(?