frontend/app/multistep/projectcreate_new/ConfigurationComponent.tsx (213 lines of code) (raw):

import React, { useEffect, useState } from "react"; import { Grid, Paper, Switch, TextField, Typography } from "@material-ui/core"; import { format } from "date-fns"; import { useGuardianStyles } from "~/misc/utils"; import { isLoggedIn } from "~/utils/api"; import ObituaryComponent from "./ObituaryComponent"; import ProductionOfficeComponent from "./ProductionOfficeComponent"; import TemplateComponent from "./TemplateComponent"; import { getProjectsDefaultStorageId } from "./ProjectStorageService"; import { SystemNotifcationKind, SystemNotification, } from "@guardian/pluto-headers"; import axios from "axios"; interface ConfigurationComponentProps { templateValue?: number; templateValueDidChange: (newValue: number) => void; projectName: string; projectNameDidChange: (newValue: string) => void; fileName: string; fileNameDidChange: (newValue: string) => void; selectedStorageId: number | undefined; storageIdDidChange: (newValue: number) => void; valueDidChange: (newValue: string) => void; checkBoxDidChange: (newValue: boolean) => void; value: string; isObituary: boolean; valueWasSet: (newValue: ProductionOffice) => void; productionOfficeValue: string; extraText?: string; } const ConfigurationComponent: React.FC<ConfigurationComponentProps> = ( props ) => { const [autoName, setAutoName] = useState(true); const [knownStorages, setKnownStorages] = useState<PlutoStorage[]>([]); const classes = useGuardianStyles(); const [isAdmin, setIsAdmin] = useState<boolean>(false); const [loading, setLoading] = useState(false); const loadStorages = async () => { console.log("Loading in storages..."); setLoading(true); const response = await axios.get<PlutoStorageListResponse>("/api/storage", { validateStatus: () => true, }); switch (response.status) { case 200: setKnownStorages(response.data.result); setLoading(false); break; default: setLoading(false); console.error( `Could not load in storages: ${response.status} ${response.statusText}`, response.data ); SystemNotification.open( SystemNotifcationKind.Error, `Could not load in storages, server error ${response.status}. More details in the browser console.` ); } }; const makeAutoFilename = (title: string) => { const sanitizer = /[^\w\d_]+/g; return ( format(new Date(), "yyyyMMdd") + "_" + title.substring(0, 32).replace(sanitizer, "_").toLowerCase() ); }; useEffect(() => { loadStorages(); }, []); useEffect(() => { if (autoName) { props.fileNameDidChange(makeAutoFilename(props.projectName)); } }, [props.projectName]); const fetchWhoIsLoggedIn = async () => { try { console.log("Checking if user is admin"); const loggedIn = await isLoggedIn(); console.log("loggedin data: ", loggedIn); setIsAdmin(loggedIn.isAdmin); } catch { console.log("User is not logged in"); setIsAdmin(false); } }; useEffect(() => { fetchWhoIsLoggedIn(); }, []); useEffect(() => { getProjectsDefaultStorageId() .then((id) => props.storageIdDidChange(id)) .catch((error) => { console.error("Could not get default storage id: ", error); if (error.response && error.response.status === 404) { SystemNotification.open( SystemNotifcationKind.Error, "No default project storage has been set" ); } else if (!error.hasOwnProperty("response")) { SystemNotification.open( SystemNotifcationKind.Error, "Could not understand response for default storage, check the console" ); } else { SystemNotification.open( SystemNotifcationKind.Error, "Server error loading the default storage id, please try again in a couple of minutes" ); } props.storageIdDidChange(knownStorages[0].id); }); }, [knownStorages]); return ( <div className={classes.common_box_size}> <Typography variant="h3">Project Configuration</Typography> <Grid container direction="column"> <Paper className={classes.paperWithPadding}> <Grid container spacing={4} alignItems="center"> <Grid item xs={6} sm={6}> <TextField style={{ width: 340 }} label="Project Title" placeholder="My project title" helperText="Enter a good descriptive project name" margin="normal" id="projectNameInput" onChange={(event) => { props.projectNameDidChange( event.target.value.replace(/[_]/g, "") ); if (event.target.value.includes("_")) { SystemNotification.open( SystemNotifcationKind.Warning, "Underscores should not be used in project titles." ); } }} value={props.projectName} FormHelperTextProps={{ style: { fontSize: "0.86rem" } }} InputLabelProps={{ shrink: true, style: { fontSize: "1.2rem" }, }} /> </Grid> {isAdmin && ( <> <Grid container item xs={6} sm={6} alignItems="center" justifyContent="flex-end" > <Grid item xs={2}> <Switch id="autoNameCheck" checked={autoName} onChange={(event) => setAutoName(event.target.checked)} /> </Grid> <Grid item xs={8}> <TextField style={{ width: "100%" }} id="fileNameInput" onChange={(event) => props.fileNameDidChange(event.target.value) } value={props.fileName} disabled={autoName} /> </Grid> </Grid> </> )} </Grid> </Paper> <Paper className={classes.paperWithPadding}> <Grid item xs={12}> <TemplateComponent templateValue={props.templateValue} templateValueDidChange={props.templateValueDidChange} /> </Grid> </Paper> <Paper className={classes.paperWithPadding}> <Grid item xs={12}> <ObituaryComponent valueDidChange={props.valueDidChange} value={props.value} isObituary={props.isObituary} checkBoxDidChange={props.checkBoxDidChange} /> </Grid> </Paper> <Paper className={classes.paperWithPadding}> <Grid item xs={12}> <ProductionOfficeComponent productionOfficeValue={props.productionOfficeValue} valueWasSet={props.valueWasSet} /> </Grid> </Paper> </Grid> </div> ); }; export default ConfigurationComponent;