Skip to content

Commit

Permalink
feat: added acpype dynamic, dynamic cancellation
Browse files Browse the repository at this point in the history
  • Loading branch information
Ivo committed Apr 17, 2023
1 parent 15b5307 commit 6cb44ac
Show file tree
Hide file tree
Showing 22 changed files with 612 additions and 243 deletions.
1 change: 1 addition & 0 deletions apps/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"react-hook-form": "^7.43.9",
"react-i18next": "^12.2.0",
"react-icons": "^4.8.0",
"react-uuid": "^2.0.0",
"rehype-pretty-code": "^0.9.4",
"sharp": "^0.31.3",
"shiki": "^0.14.1",
Expand Down
2 changes: 1 addition & 1 deletion apps/client/public/locales/en-US/features.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
},
"running": {
"title": "Your Dynamic is Running",
"cancel": "Cancel",
"taskId": "Task ID",
"description": "Info",
"type": "Model",
"molecule": "Molecule",
Expand Down
2 changes: 1 addition & 1 deletion apps/client/src/components/Input/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const Input = forwardRef<HTMLInputElement, InputProps>(
</div>
<input
className={clsx(
"border border-primary-200/60 transition-all duration-500 px-2 py-1 h-10 outline-none file:transition-all file:duration-500 rounded-md bg-zinc-100 placeholder:text-zinc-400 file:bg-primary-500 file:text-zinc-50 file:mr-2 file:py-1 file:px-2 file:h-full file:-ml-1 file:rounded-md file:border-0 file:text-sm file:font-semibold hover:file:bg-primary-600 focus:ring-2 focus:ring-primary-400 focus:ring-offset-2 focus:ring-offset-zinc-200",
"border border-primary-400/60 transition-all duration-500 px-2 py-1 h-10 outline-none file:transition-all file:duration-500 rounded-md bg-zinc-100 placeholder:text-zinc-400 file:bg-primary-500 file:text-zinc-50 file:mr-2 file:py-1 file:px-2 file:h-full file:-ml-1 file:rounded-md file:border-0 file:text-sm file:font-semibold hover:file:bg-primary-600 focus:ring-2 focus:ring-primary-400 focus:ring-offset-2 focus:ring-offset-zinc-200",
{
"border-red-600/95 focus:ring-red-500": error
}
Expand Down
2 changes: 1 addition & 1 deletion apps/client/src/components/Layout/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ export function Header({ setTheme, theme }: MainNavProps) {
</div>

{showMobileMenu ? (
<div className="absolute inset-0 top-14 bg-zinc-100 p-2 flex flex-col gap-y-4">
<div className="absolute inset-0 z-10 top-14 bg-zinc-100 p-2 flex flex-col gap-y-4">
{renderedItems}
</div>
) : null}
Expand Down
65 changes: 0 additions & 65 deletions apps/client/src/components/Layout/MobileNav.tsx

This file was deleted.

4 changes: 2 additions & 2 deletions apps/client/src/components/Layout/Page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ export function PageLayout({
/>
</BreadcrumbItem>
{breadcrumbs &&
breadcrumbs.map((breadcrumb) => (
breadcrumbs.map((breadcrumb, index) => (
<BreadcrumbItem
key={breadcrumb.href}
key={breadcrumb.href + index}
href={breadcrumb.href}
>
{breadcrumb.label}
Expand Down
10 changes: 6 additions & 4 deletions apps/client/src/components/RunningDynamicStepList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ function Step({
) : null}
{running ? (
<div
className="my-auto"
className="my-auto z-0"
role="status"
>
<svg
Expand Down Expand Up @@ -87,17 +87,19 @@ export function RunningDynamicStepList({
</h4>
<div className="flex items-center gap-1 flex-wrap">
{steps.map((step, index) => (
<>
<div
className="flex items-center gap-x-1"
key={step + index}
>
<Step
active={activeSteps.includes(step)}
running={activeSteps[activeSteps.length - 1] === step}
key={step}
step={step}
/>
{index + 1 < steps.length ? (
<ArrowRight className="h-4 w-4" />
) : null}
</>
</div>
))}
</div>
</>
Expand Down
4 changes: 2 additions & 2 deletions apps/client/src/components/Select/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export const Select = <T extends string>({
>
<RSelect.Trigger
className={clsx(
"flex justify-between transition-all duration-500 items-center rounded-md border border-primary-200/60 data-[placeholder]:text-zinc-400 bg-zinc-100 px-2 py-1 h-10 outline-none focus:ring-2 focus:ring-primary-400 focus:ring-offset-2 focus:ring-offset-zinc-200",
"flex justify-between transition-all duration-500 items-center rounded-md border border-primary-400/60 data-[placeholder]:text-zinc-400 bg-zinc-100 px-2 py-1 h-10 outline-none focus:ring-2 focus:ring-primary-400 focus:ring-offset-2 focus:ring-offset-zinc-200",
{
"border-red-600/95 focus:ring-red-500": error
}
Expand All @@ -58,7 +58,7 @@ export const Select = <T extends string>({
</RSelect.Icon>
</RSelect.Trigger>
<RSelect.Content
className="p-2 z-10 w-[--radix-select-trigger-width] max-h-[16rem] bg-zinc-100 border border-primary-200/60 transition-all duration-500 rounded-md"
className="p-2 z-10 w-[--radix-select-trigger-width] max-h-[16rem] bg-zinc-100 border border-primary-400/60 transition-all duration-500 rounded-md"
position="popper"
>
<RSelect.ScrollUpButton className="flex items-center justify-center h-7 bg-transparent text-primary-500 cursor-default">
Expand Down
218 changes: 218 additions & 0 deletions apps/client/src/pages/dynamic/acpype.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
import { SubmitHandler, useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { CloudCog, Download } from "lucide-react";
import { GetServerSideProps } from "next";
import { useRouter } from "next/router";
import { useTranslation } from "next-i18next";
import { serverSideTranslations } from "next-i18next/serverSideTranslations";

import { Button } from "@app/components/Button";
import { Input } from "@app/components/Input";
import { PageLayout } from "@app/components/Layout/Page";
import { Select } from "@app/components/Select";
import { Switch } from "@app/components/Switch";
import { api } from "@app/lib/api";
import { getRunningDynamic } from "@app/queries/useRunningDynamic";
import {
ACPYPEFormSchema,
ACPYPEFormSchemaType
} from "@app/schemas/pages/dynamic/acpype.zod";
import { boxTypes } from "@app/utils/box-types";
import { acpypeForceFields } from "@app/utils/force-fields";
import { waterModels } from "@app/utils/water-models";

export default function ACPYPEDynamic() {
const {
formState: { errors },
handleSubmit,
register,
setValue,
watch
} = useForm<ACPYPEFormSchemaType>({
resolver: zodResolver(ACPYPEFormSchema),
defaultValues: {
neutralize: true,
ignore: true,
double: false
}
});
const router = useRouter();
const { t } = useTranslation(["features"]);

const handleSubmitDynamic: SubmitHandler<ACPYPEFormSchemaType> = async (
data
) => {
const formData = new FormData();

formData.append("file_pdb", data.protein[0]);
formData.append("file_itp", data.ligandItp[0]);
formData.append("file_gro", data.ligandGro[0]);
formData.append("force_field", data.forceField);
formData.append("water_model", data.waterModel);
formData.append("box_type", data.boxType);
formData.append("box_distance", data.boxDistance);
formData.append("bootstrap", data.bootstrap ? "True" : "False");
formData.append("neutralize", data.neutralize ? "True" : "False");
formData.append("double", data.double ? "True" : "False");
formData.append("ignore", data.ignore ? "True" : "False");
formData.append("username", "IvoVieira1");

await api
.post("/acpype", formData, {
headers: {
"Content-Type": "multipart/form-data"
}
})
.then(async ({ data }) => {
if (data.status === "generated") {
await api
.post(
"/run",
{
folder: data.folder
},
{
headers: {
"Content-Type": "multipart/form-data"
}
}
)
.then(() => router.push("/dynamic/running"))
.catch(() => alert("not running"));
}
})
.catch(() => alert("Não foi"));
};

return (
<PageLayout title={t("features:dynamic.types.acpype")}>
<form
className="flex flex-col gap-y-2"
onSubmit={handleSubmit(handleSubmitDynamic)}
>
<Input
label={t("features:dynamic.forms.file-pdb.title")}
type="file"
accept=".pdb"
error={errors.protein}
{...register("protein")}
/>

<Input
label={t("features:dynamic.forms.file-itp.title")}
type="file"
accept=".itp,.gro"
error={errors.ligandItp}
{...register("ligandItp")}
/>

<Input
label={t("features:dynamic.forms.file-gro.title")}
type="file"
accept=".pdb,.gro"
error={errors.ligandGro}
{...register("ligandGro")}
/>

<Select<keyof typeof acpypeForceFields>
error={errors.forceField}
label={t("features:dynamic.forms.force-field.title")}
name="forceField"
onChange={(newForceField) => setValue("forceField", newForceField)}
placeholder={t("features:dynamic.forms.force-field.placeholder")}
selectedValue={watch("forceField")}
values={acpypeForceFields}
/>

<Select<keyof typeof waterModels>
error={errors.waterModel}
label={t("features:dynamic.forms.water-model.title")}
name="waterModel"
onChange={(newWaterModel) => setValue("waterModel", newWaterModel)}
placeholder={t("features:dynamic.forms.water-model.placeholder")}
selectedValue={watch("waterModel")}
values={waterModels}
/>

<Select<keyof typeof boxTypes>
error={errors.boxType}
label={t("features:dynamic.forms.box-type.title")}
name="boxType"
onChange={(newBoxType) => setValue("boxType", newBoxType)}
placeholder={t("features:dynamic.forms.box-type.placeholder")}
selectedValue={watch("boxType")}
values={boxTypes}
/>

<Input
label={t("features:dynamic.forms.box-distance.title")}
error={errors.boxDistance}
type="number"
{...register("boxDistance")}
/>

<label>{t("features:dynamic.options")}</label>
<div className="flex flex-col gap-y-2">
<Switch
label={t("features:dynamic.forms.neutralize.title")}
checked={watch("neutralize")}
onCheckedChange={(bool) => setValue("neutralize", bool)}
name="neutralize"
disabled
/>

<Switch
label={t("features:dynamic.forms.ignore.title")}
checked={watch("ignore")}
onCheckedChange={(bool) => setValue("ignore", bool)}
name="ignore"
disabled
/>

<Switch
label={t("features:dynamic.forms.double.title")}
checked={watch("double")}
onCheckedChange={(bool) => setValue("double", bool)}
name="double"
disabled
/>

<Switch
label={t("features:dynamic.forms.run.title")}
checked={watch("bootstrap")}
onCheckedChange={(bool) => setValue("bootstrap", bool)}
name="bootstrap"
/>
</div>
<Button
className="mt-4"
LeftIcon={watch("bootstrap") === true ? CloudCog : Download}
type="submit"
>
{watch("bootstrap") === true
? t("features:dynamic.forms.submit.run")
: t("features:dynamic.forms.submit.download")}
</Button>
</form>
</PageLayout>
);
}

export const getServerSideProps: GetServerSideProps = async ({ locale }) => {
const data = await getRunningDynamic("IvoVieira1");

if (data?.status === "running") {
return {
redirect: {
destination: "/dynamic/running"
},
props: {}
};
}

return {
props: {
...(await serverSideTranslations(locale ?? "en-US", ["features"]))
}
};
};

0 comments on commit 6cb44ac

Please sign in to comment.