frontend/app/CreateDeliverable.tsx (187 lines of code) (raw):
import React, { useState, useEffect } from "react";
import axios from "axios";
import {
Redirect,
RouteComponentProps,
useHistory,
useLocation,
useParams,
} from "react-router-dom";
import Paper from "@material-ui/core/Paper";
import {
Button,
FormControl,
InputLabel,
TextField,
Typography,
} from "@material-ui/core";
import { makeStyles } from "@material-ui/core/styles";
import Cookies from "js-cookie";
const useStyles = makeStyles({
root: {
display: "flex",
flexDirection: "column",
padding: "1rem",
"& form": {
width: "400px",
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
margin: "0.625rem 0 0 0",
},
"& .MuiTextField-root": {
width: "100%",
marginBottom: "1rem",
},
"& .MuiFormControl-root": {
width: "100%",
marginBottom: "1rem",
},
},
formButtons: {
display: "flex",
marginTop: "2.5rem",
"& .cancel": {
marginLeft: "1rem",
},
},
});
const digitTester = RegExp("^\\d+$");
const CreateDeliverable: React.FC<RouteComponentProps> = () => {
const [projectName, setProjectName] = useState("");
const [projectIdInput, setProjectIdInput] = useState("");
const [projectIdInputError, setProjectIdInputError] = useState<
string | undefined
>(undefined);
const [commissionIdInput, setCommissionIdInput] = useState("");
const [commissionIdInputError, setCommissionIdInputError] = useState<
string | undefined
>(undefined);
const [canEditProjectId, setCanEditProjectId] = useState(true);
const [isSaving, setIsSaving] = useState(false);
const [lastError, setLastError] = useState({});
const [saveCompleted, setSaveCompleted] = useState(false);
// @ts-ignore
const { projectId } = useParams();
const classes = useStyles();
useEffect(() => {
if (projectId) {
setProjectIdInput(projectId);
setCanEditProjectId(false);
}
}, []);
useEffect(() => {
if (digitTester.test(projectIdInput)) {
setProjectIdInputError(undefined);
} else {
setProjectIdInputError("You must enter a valid ID number");
}
}, [projectIdInput]);
useEffect(() => {
if (digitTester.test(commissionIdInput)) {
setCommissionIdInputError(undefined);
} else {
setCommissionIdInputError("You must enter a valid ID number");
}
}, [commissionIdInput]);
const doCreateProject = async () => {
const csrftoken = Cookies.get("csrftoken");
if (!csrftoken) {
console.warn("Could not find a csrf token! Request will probably fail");
}
setIsSaving(true);
try {
const result = await axios.post(
"/api/bundle/new",
{
pluto_core_project_id: projectIdInput,
commission_id: commissionIdInput,
name: projectName,
},
{
headers: {
"X-CSRFToken": csrftoken,
},
}
);
setIsSaving(false);
if (result.status == 200) {
setSaveCompleted(true);
} else {
setLastError(`Could not save: server returned ${result.status}`);
}
} catch (err) {
console.error(err);
setIsSaving(false);
setLastError(err.toString());
}
};
if (saveCompleted) return <Redirect to={`/project/${projectIdInput}`} />;
return (
<>
<Typography variant="h2">Create new bundle</Typography>
<Paper elevation={3} className={classes.root}>
<Typography>
The simpler, and recommended way to create a deliverable bundle is to
go to your project page and create it from there. This page only
exists for technical administration.
</Typography>
<FormControl>
{/*<InputLabel htmlFor="name-input">Deliverable bundle name</InputLabel>*/}
<TextField
required
id="name-input"
label="Deliverable bundle name"
value={projectName}
onChange={(evt) => setProjectName(evt.target.value)}
InputProps={{
readOnly: isSaving,
}}
/>
</FormControl>
<FormControl>
<TextField
required
id="project-id-input"
error={!!projectIdInputError}
helperText={projectIdInputError}
label="Project ID"
value={projectIdInput}
onChange={(evt) => setProjectIdInput(evt.target.value)}
InputProps={{
readOnly: !canEditProjectId || isSaving,
}}
/>
</FormControl>
<FormControl>
<TextField
required
id="commission-id-input"
error={!!commissionIdInputError}
helperText={commissionIdInputError}
label="Commission ID"
value={commissionIdInput}
onChange={(evt) => setCommissionIdInput(evt.target.value)}
InputProps={{
readOnly: !canEditProjectId || isSaving,
}}
/>
</FormControl>
<Button
variant="outlined"
onClick={doCreateProject}
disabled={isSaving}
>
Create
</Button>
<Button
variant="outlined"
onClick={() => history.back()}
disabled={isSaving}
>
Cancel
</Button>
</Paper>
</>
);
};
export default CreateDeliverable;