diff --git a/frontend/i14/src/components/workflows/OptionSelect.tsx b/frontend/i14/src/components/workflows/OptionSelect.tsx new file mode 100644 index 00000000..58dc86b8 --- /dev/null +++ b/frontend/i14/src/components/workflows/OptionSelect.tsx @@ -0,0 +1,51 @@ +import React, { FC } from "react"; +import { + FormControl, + InputLabel, + Select, + IconButton, + Tooltip, + Grid, +} from "@mui/material"; +import InfoIcon from "@mui/icons-material/Info"; +import type { SelectChangeEvent } from "@mui/material/Select"; +import type { Option } from "../../types/workflowFields"; + +type Props = { + label: string; + value: string; + options: Option[]; + onChange: (e: SelectChangeEvent) => void; +}; + +const OptionSelect: FC = ({ label, value, options, onChange }) => { + const selected = options.find((o) => o.value === value); + + return ( + + {label} + + + + + + + + + + ); +}; + +export default OptionSelect; diff --git a/frontend/i14/src/components/workflows/WorkflowForm.tsx b/frontend/i14/src/components/workflows/WorkflowForm.tsx index 3b146321..90c20cc5 100644 --- a/frontend/i14/src/components/workflows/WorkflowForm.tsx +++ b/frontend/i14/src/components/workflows/WorkflowForm.tsx @@ -1,139 +1,135 @@ -import React, { FC, ChangeEvent, useState } from "react"; +import React, { FC, useMemo, useState } from "react"; import { Button, - MenuItem, - IconButton, - InputLabel, + FormLabel, + TextField, + ToggleButton, + ToggleButtonGroup, Grid, - Select, Stack, - TextField, - Tooltip, Typography, } from "@mui/material"; -import InfoIcon from "@mui/icons-material/Info"; -import type { SelectChangeEvent } from "@mui/material/Select"; import { visitRegex } from "@diamondlightsource/sci-react-ui"; -type FormData = { visit: string; workflow: string }; +import { initialData } from "../../data/form"; +import { templateOptions } from "../../data/templates"; +import OptionSelect from "./OptionSelect"; -const initialData: FormData = { - visit: "cm23467-2", - workflow: "dpc-batch", -}; +import type { WorkflowFormData, Option } from "../../types/workflowFields"; export const WorkflowForm: FC = () => { - const [data, setData] = useState(initialData); + const techniques = ["dpc", "xanes", "xrd"] as const; + type ToggleGroup = (typeof techniques)[number]; + const getFilteredTemplates = (toggle: ToggleGroup): Option[] => { + return (templateOptions ?? []).filter((o) => o.value.includes(toggle)); + }; + + const [data, setData] = useState(() => { + const defaultTechnique = + techniques.find((t) => initialData.template.includes(t)) ?? techniques[0]; + return { + ...initialData, + technique: defaultTechnique, + }; + }); + const visitMatch = visitRegex.exec(data.visit); + const filteredTemplateOptions: Option[] = getFilteredTemplates( + data.technique + ); + + const handleToggleChange = ( + _event: React.MouseEvent, + next: ToggleGroup | null + ) => { + if (!next) return; + const filteredTemplates = getFilteredTemplates(next); + setData((prev) => ({ + ...prev, + technique: next, + template: filteredTemplates[0].value, + })); + }; + const openInNewTab = (url: string) => { const w = window.open(url, "_blank"); - if (w) w.focus(); + w?.focus(); }; - const openLink = () => { - if (!visitMatch) return; - const linkString = `https://workflows.diamond.ac.uk/templates/${data.workflow}/${data.visit}`; - openInNewTab(linkString); + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + const url = `https://workflows.diamond.ac.uk/templates/${data.template}/${data.visit}?outputFolder=${data.outpath}`; + openInNewTab(url); }; - const workflowOptions = [ - { - label: "DPC", - value: "dpc-batch", - desc: "DPC imaging produces an image of the phase shifts to the X-ray beam as a result of interaction with the sample by measuring the gradient of the phase and retrieving the phase shifts by a straightforward integration step.", - }, - { - label: "XANES Auto-processing", - value: "xanes", - desc: "XANES is a utility which attempts to stack a sequence of datasets acquired at different energy for a particular line group and perform alignment based on a line group.", - }, - { - label: "XANES Point", - value: "xanes-point", - desc: "XANES-point is a utility which takes in a scan file (inpath) and a line group (edge_element), performs windowing of this line group, and saves a two-column text file (outpath): the first column is the energy in keV, and the second column is the summed windowed MCA intensity across the 4 channels.", - }, - { - label: "XANES Sparse", - value: "xanes-sparse", - desc: "XANES-sparse is a utility which takes the last scan file of a sparse XANES scan (inpath), defines the 2D full grid, inserts the data in the correct rows, stack the images, and completes the missing data by using looped alternating steepest descent (ASD).", - }, - { - label: "XRD 1D", - value: "xrd1d-batch", - desc: "XRD can be used to spatially map changes in crystallographic direction, d-spacing or strain across a sample.", - }, - { - label: "XRD 2D", - value: "xrd2d-batch", - desc: "XRD 2D is a utility which performs Azimuthal integration (ExcaliburXRDIntegration) and saves result to a nxs file", - }, - ]; - - const option = workflowOptions.find( - (option) => option.value === data.workflow - ); - return ( - - I14 Workflows + + + I14 Workflows +
+
+ + + Technique + + {techniques.map((t) => ( + + {t.toUpperCase()} + + ))} + + + + setData((prev) => ({ ...prev, template: e.target.value })) + } + /> - { - e.preventDefault(); - openLink(); - }} - > - - - Workflow - - - - - - - - - - ) => { - const value = e.target.value; - setData((prev) => ({ ...prev, visit: value })); - }} - helperText={visitMatch ? "" : "Expected format: xx12345-1"} - error={!visitMatch} - /> + placeholder="Visit" + type="text" + value={data.visit} + onChange={(e: ChangeEvent) => { + const value = e.target.value; + setData((prev) => ({ ...prev, visit: value })); + }} + helperText={visitMatch ? "" : "Expected format: xx12345-1"} + error={!visitMatch} + /> + + ) => { + setData((prev) => ({ ...prev, outpath: e.target.value })); + }} + /> - - - -
+ +
+ + + ); }; diff --git a/frontend/i14/src/data/form.ts b/frontend/i14/src/data/form.ts new file mode 100644 index 00000000..1230af8d --- /dev/null +++ b/frontend/i14/src/data/form.ts @@ -0,0 +1,7 @@ +import type { WorkflowFormData } from "../types/workflowFields"; + +export const initialData: WorkflowFormData = { + visit: "mg23967-1", + template: "dpc-batch", + outpath: "/dls/i14/data/", +}; diff --git a/frontend/i14/src/data/templates.ts b/frontend/i14/src/data/templates.ts new file mode 100644 index 00000000..cb3df06a --- /dev/null +++ b/frontend/i14/src/data/templates.ts @@ -0,0 +1,34 @@ +import type { Option } from "../types/workflowFields"; + +export const templateOptions: Option[] = [ + { + label: "DPC", + value: "dpc-batch", + desc: "DPC imaging produces an image of the phase shifts to the X-ray beam as a result of interaction with the sample by measuring the gradient of the phase and retrieving the phase shifts by a straightforward integration step.", + }, + { + label: "XANES Auto-processing", + value: "xanes", + desc: "XANES is a utility which attempts to stack a sequence of datasets acquired at different energy for a particular line group and perform alignment based on a line group.", + }, + { + label: "XANES Point", + value: "xanes-point", + desc: "XANES-point is a utility which takes in a scan file (inpath) and a line group (edge_element), performs windowing of this line group, and saves a two-column text file (outpath): the first column is the energy in keV, and the second column is the summed windowed MCA intensity across the 4 channels.", + }, + { + label: "XANES Sparse", + value: "xanes-sparse", + desc: "XANES-sparse is a utility which takes the last scan file of a sparse XANES scan (inpath), defines the 2D full grid, inserts the data in the correct rows, stack the images, and completes the missing data by using looped alternating steepest descent (ASD).", + }, + { + label: "XRD 1D", + value: "xrd1d-batch", + desc: "XRD can be used to spatially map changes in crystallographic direction, d-spacing or strain across a sample.", + }, + { + label: "XRD 2D", + value: "xrd2d-batch", + desc: "XRD 2D is a utility which performs Azimuthal integration (ExcaliburXRDIntegration) and saves result to a nxs file", + }, +]; diff --git a/frontend/i14/src/types/workflowFields.ts b/frontend/i14/src/types/workflowFields.ts new file mode 100644 index 00000000..c0a2d1ab --- /dev/null +++ b/frontend/i14/src/types/workflowFields.ts @@ -0,0 +1,2 @@ +type WorkflowFormData = { visit: string; template: string; outpath: string }; +type Option = { label: string; value: string; desc?: string };