Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 2 scenarios #87

Merged
merged 11 commits into from
Mar 19, 2024
37 changes: 37 additions & 0 deletions app/builder/Form.client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,43 @@ const App = () => {
}
}, [archive, activetCatalog]); // eslint-disable-line react-hooks/exhaustive-deps

useEffect(() => {
// on builder page check for zip in browser storage and loads it
if (activetCatalog.title === "") {
return;
}
if (typeof indexedDB === "undefined") {
console.error(
"IndexedDB not supported, unable to save workflow.zip file."
);
return;
}
const open = indexedDB.open("haddock3", 1);
open.onsuccess = function () {
const db = open.result;
const tx = db.transaction("zips", "readwrite");
const zips = tx.objectStore("zips");
const request = zips.get("workflow.zip");
request.onsuccess = function () {
const zip: Blob = request.result;
console.log("zip", zip);
if (zip === undefined) {
return;
}
const url = URL.createObjectURL(zip);
loadWorkflowArchive(url)
.finally(() => {
URL.revokeObjectURL(url);
})
.catch((error) => {
console.error("Error loading workflow from indexeddb", error);
});
// remove zip from indexeddb so next visit to builder page loads nothing
zips.delete("workflow.zip");
};
};
}, [activetCatalog]); // eslint-disable-line react-hooks/exhaustive-deps

return (
<div className="workflow-builder-app">
<div className="page grid h-full w-full gap-2 p-4">
Expand Down
1 change: 1 addition & 0 deletions app/components/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export const Navbar = () => {
<NavigationMenu className="">
<NavigationMenuList className="flex space-x-5">
<MyNavLink to="/builder">Builder</MyNavLink>
<MyNavLink to="/scenarios">Scenario</MyNavLink>
<MyNavLink to="/upload">Upload</MyNavLink>
<MyNavLink to="/jobs">Manage</MyNavLink>
<MyNavLink to="/about">About</MyNavLink>
Expand Down
120 changes: 120 additions & 0 deletions app/components/ui/dialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import * as React from "react";
import * as DialogPrimitive from "@radix-ui/react-dialog";
import { X } from "lucide-react";

import { cn } from "~/lib/utils";

const Dialog = DialogPrimitive.Root;

const DialogTrigger = DialogPrimitive.Trigger;

const DialogPortal = DialogPrimitive.Portal;

const DialogClose = DialogPrimitive.Close;

const DialogOverlay = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Overlay>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
>(({ className, ...props }, ref) => (
<DialogPrimitive.Overlay
ref={ref}
className={cn(
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
className
)}
{...props}
/>
));
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;

const DialogContent = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
>(({ className, children, ...props }, ref) => (
<DialogPortal>
<DialogOverlay />
<DialogPrimitive.Content
ref={ref}
className={cn(
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
className
)}
{...props}
>
{children}
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
<X className="h-4 w-4" />
<span className="sr-only">Close</span>
</DialogPrimitive.Close>
</DialogPrimitive.Content>
</DialogPortal>
));
DialogContent.displayName = DialogPrimitive.Content.displayName;

const DialogHeader = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col space-y-1.5 text-center sm:text-left",
className
)}
{...props}
/>
);
DialogHeader.displayName = "DialogHeader";

const DialogFooter = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
className
)}
{...props}
/>
);
DialogFooter.displayName = "DialogFooter";

const DialogTitle = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Title>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
>(({ className, ...props }, ref) => (
<DialogPrimitive.Title
ref={ref}
className={cn(
"text-lg font-semibold leading-none tracking-tight",
className
)}
{...props}
/>
));
DialogTitle.displayName = DialogPrimitive.Title.displayName;

const DialogDescription = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Description>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
>(({ className, ...props }, ref) => (
<DialogPrimitive.Description
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
));
DialogDescription.displayName = DialogPrimitive.Description.displayName;

export {
Dialog,
DialogPortal,
DialogOverlay,
DialogClose,
DialogTrigger,
DialogContent,
DialogHeader,
DialogFooter,
DialogTitle,
DialogDescription,
};
2 changes: 1 addition & 1 deletion app/components/ui/input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
<input
type={type}
className={cn(
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-secondary file:text-sm file:font-medium file:text-secondary-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className
)}
ref={ref}
Expand Down
6 changes: 6 additions & 0 deletions app/routes/_index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ const cards = [
title: "Build",
description: "Use the workflow builder to create and submit a job.",
},
{
target: "/scenarios",
image: builder_image,
title: "Scenarios",
description: "Explore and run predefined workflows.",
},
{
target: "/upload",
image: upload_image,
Expand Down
47 changes: 47 additions & 0 deletions app/routes/scenarios._index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Link } from "@remix-run/react";
import { Card, CardContent, CardHeader } from "~/components/ui/card";

interface Scenario {
url: string;
title: string;
description: string;
}

const scenarios: Scenario[] = [
{
url: "/scenarios/antibody-antigen",
title: "Antibody Antigen",
description: "Based on HADDOCK3 Antibody Antigen tutorial",
},
{
url: "/scenarios/protein-protein",
title: "Protein Protein",
description: "Based on HADDOCK2.4 Protein Protein docking tutorial",
},
];

function ScenarioCard({ url, title, description }: Scenario) {
return (
<Card className="w-96 rounded-2xl shadow-lg hover:shadow-xl">
<Link to={url}>
<CardHeader>
<h2 className="text-2xl">{title}</h2>
</CardHeader>
<CardContent>{description}</CardContent>
</Link>
</Card>
);
}

export default function ScenariosIndex() {
return (
<main>
<h1 className="text-3xl">Scenarios</h1>
<div className="flex flex-wrap justify-start gap-4 p-24">
{scenarios.map((scenario) => (
<ScenarioCard key={scenario.url} {...scenario} />
))}
</div>
</main>
);
}
Loading