Files
molecular_frontend/src/Modals/NewMolecule/NewMolecule.tsx

242 lines
6.8 KiB
TypeScript
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import {
Button,
Center,
Modal,
Space,
Stepper,
Title,
Text,
Flex,
Select,
Textarea,
} from "@mantine/core";
import { useEffect, useState } from "react";
import "./NewMolecule.css";
import {
IconArchiveFilled,
IconArticleFilled,
IconFileFilled,
} from "@tabler/icons-react";
import {
ConvertMoleculeToStandart,
GetInFormats,
} from "Api/ConvertBackendCalls";
import { AxiosError } from "axios";
import CustomButton from "Components/CustomButton/CustomButton";
interface NewMoleculeModalProps {
isOpened: boolean;
setIsOpened: (opened: boolean) => void;
}
export function NewMoleculeModal(props: NewMoleculeModalProps) {
const [activeStep, setActiveStep] = useState(0);
const [selectedMethod, setSelectedMethod] = useState(0);
const [inMolecule, setInMolecule] = useState("");
const [inFormat, setInFormat] = useState<string | null>();
const [inOptions, setInOptions] = useState<string[] | undefined>();
const getOptions = () => {
GetInFormats().then((data: { [key: string]: string } | AxiosError) => {
if (data instanceof AxiosError) {
//TODO: handle Error
} else {
const values = Object.keys(data);
setInOptions(values);
}
});
};
useEffect(() => {
getOptions();
}, []);
//reset on open dialog
useEffect(() => {
if (props.isOpened) {
setActiveStep(0);
setSelectedMethod(0);
setInMolecule("");
setInFormat(undefined);
if (inOptions == undefined) {
getOptions();
}
}
}, [props.isOpened]);
const handleClose = () => {
props.setIsOpened(false);
};
const handleConvert = () => {
if (inFormat) {
ConvertMoleculeToStandart({
inputText: inMolecule,
inputFormat: inFormat,
make_3d: true,
add_h: false,
optimize: false,
}).then((data: string | AxiosError) => {
if (data instanceof AxiosError) {
//TODO: handle Error
} else {
setCurrentMoleculeString(data);
props.setIsOpened(false);
}
});
} else {
//TODO: add no format selected handling
}
};
const handleEmptyMolecule = () => {
props.setIsOpened(false);
};
return (
<Modal
opened={props.isOpened}
onClose={handleClose}
title=<Title size="xl">Новая молекула</Title>
centered
size="75%"
styles={{
content: { paddingLeft: "10px" },
title: { width: "100%" },
}}
>
<Stepper
active={activeStep}
onStepClick={setActiveStep}
allowNextStepsSelect={false}
classNames={{ root: "StepperRoot" }}
styles={{
steps: {
paddingTop: "30px",
paddingBottom: "30px",
paddingLeft: "20px",
minWidth: "0px",
alignSelf: "center",
},
content: {
flex: 1,
},
}}
style={{ display: "flex", flexDirection: "row" }}
orientation="vertical"
>
<Stepper.Step>
<div style={{ width: "100%", textAlign: "center" }}>
<Title size="lg">Шаг 1: Способ добавления молекулы</Title>
<Space h="lg" />
<Flex justify="center" gap="md" wrap="wrap">
<Button
onClick={() => {
setSelectedMethod(1);
handleEmptyMolecule();
}}
style={{ height: "100px", flexGrow: "1" }}
size="lg"
>
<Flex direction="row" gap="lg">
<IconFileFilled size={40} />
<Center>
<Text>Пустая молекула</Text>
</Center>
</Flex>
</Button>
<Button
onClick={() => {
setSelectedMethod(2);
setActiveStep(1);
}}
style={{ height: "100px", flexGrow: "1" }}
>
<Flex direction="row" gap="lg">
<IconArchiveFilled size="40" />
<Center>
<Text>Из файла / Архива</Text>
</Center>
</Flex>
</Button>
<Button
onClick={() => {
setSelectedMethod(3);
setActiveStep(1);
}}
style={{ height: "100px", flexGrow: "1" }}
>
<Flex direction="row" gap="lg">
<IconArticleFilled size={40} />
<Center>
<Text>Другой формат</Text>
</Center>
</Flex>
</Button>
</Flex>
</div>
</Stepper.Step>
<Stepper.Step>
<div style={{ width: "100%", textAlign: "center" }}>
{selectedMethod == 2 && (
<div>
<Title size="lg">Шаг 2: Выбор файла</Title>
<Space h="lg" />
</div>
)}
{selectedMethod == 3 && (
<div>
<Title size="md">Шаг 2: Ввод молекулы</Title>
<Space h="lg" />
<Textarea
className="moleculeInput"
value={inMolecule}
onChange={(e) => setInMolecule(e.currentTarget.value)}
placeholder="Введите текст молекулы"
classNames={{
wrapper: "moleculeInputWrapper",
}}
onKeyDown={(e) => {
// Stop arrow keys from reaching react-resizable-panels
if (
[
"ArrowUp",
"ArrowDown",
"ArrowLeft",
"ArrowRight",
].includes(e.key)
) {
e.stopPropagation();
}
}}
/>
<Space h="md" />
<Select
value={inFormat}
onChange={(value: string | null) => setInFormat(value)}
searchable
data={inOptions}
placeholder="Выберите формат"
classNames={{
input: "selectInFormat",
dropdown: "selectDropDown",
option: "selectDropDownOption",
}}
/>
<Space h="md" />
<CustomButton
color="accent"
onClick={handleConvert}
text="Преобразовать"
/>
</div>
)}
</div>
</Stepper.Step>
</Stepper>
</Modal>
);
}