103 lines
4.6 KiB
TypeScript
103 lines
4.6 KiB
TypeScript
import React from "react";
|
|
import { ReportFieldDefinition, reportFieldTypes } from "@/data/report";
|
|
import { identityTransformer, Transformer } from "@/serialization";
|
|
import { useTranslation } from "react-i18next";
|
|
import { useSpacing } from "@/styles";
|
|
import { Field, FieldArray, FieldProps, useFormikContext } from "formik";
|
|
import { TextField as TextFieldFormik, Select } from "formik-material-ui";
|
|
import { FormControl, InputLabel, Typography, MenuItem, Card, Box, Button, CardContent, CardHeader, IconButton } from "@material-ui/core";
|
|
import { CKEditorField } from "@/forms/ckeditor";
|
|
import { Multilingual } from "@/data";
|
|
import { Actions } from "@/components";
|
|
import { Add } from "@material-ui/icons";
|
|
import { TrashCan } from "mdi-material-ui";
|
|
import { FieldPreview } from "@/management/report/fields/list";
|
|
import { createStyles, makeStyles, Theme } from "@material-ui/core/styles";
|
|
|
|
export type FieldDefinitionFormValues = ReportFieldDefinition | { type: string };
|
|
|
|
export const initialFieldFormValues: FieldDefinitionFormValues = {
|
|
type: "short-text",
|
|
description: {
|
|
pl: "",
|
|
en: "",
|
|
},
|
|
label: {
|
|
pl: "",
|
|
en: "",
|
|
},
|
|
choices: [],
|
|
}
|
|
|
|
export const fieldFormValuesTransformer: Transformer<ReportFieldDefinition, FieldDefinitionFormValues> = identityTransformer;
|
|
export type ChoiceFieldProps = { name: string };
|
|
|
|
const ChoiceField = ({ field, form, meta }: FieldProps) => {
|
|
const { name } = field;
|
|
const { t } = useTranslation("management");
|
|
const spacing = useSpacing(2);
|
|
|
|
return <div className={ spacing.vertical }>
|
|
<Field label={ t("translation:language.pl") } name={`${name}.pl`} fullWidth component={ TextFieldFormik }/>
|
|
<Field label={ t("translation:language.en") } name={`${name}.en`} fullWidth component={ TextFieldFormik }/>
|
|
</div>
|
|
}
|
|
|
|
const useStyles = makeStyles((theme: Theme) => createStyles({
|
|
preview: {
|
|
padding: theme.spacing(2),
|
|
backgroundColor: "#e9f0f5",
|
|
},
|
|
}))
|
|
|
|
export function FieldDefinitionForm() {
|
|
const { t } = useTranslation("management");
|
|
const spacing = useSpacing(2);
|
|
const { values } = useFormikContext<any>();
|
|
const classes = useStyles();
|
|
|
|
return <div className={ spacing.vertical }>
|
|
<FormControl variant="outlined">
|
|
<InputLabel htmlFor="report-field-type">{ t("report-field.field.type") }</InputLabel>
|
|
<Field
|
|
component={Select}
|
|
name="type"
|
|
label={ t("report-field.field.name") }
|
|
inputProps={{ id: 'report-field-type', }}
|
|
>
|
|
{ reportFieldTypes.map(type => <MenuItem value={ type }>{ t(`report-field.type.${type}`) }</MenuItem>)}
|
|
</Field>
|
|
</FormControl>
|
|
<Typography variant="subtitle2">{ t("report-field.field.label") }</Typography>
|
|
<Field label={ t("translation:language.pl") } name="label.pl" fullWidth component={ TextFieldFormik }/>
|
|
<Field label={ t("translation:language.en") } name="label.en" fullWidth component={ TextFieldFormik }/>
|
|
<Typography variant="subtitle2">{ t("report-field.field.description") }</Typography>
|
|
<Field label={ t("translation:language.pl") } name="description.pl" fullWidth component={ CKEditorField }/>
|
|
<Field label={ t("translation:language.en") } name="description.en" fullWidth component={ CKEditorField }/>
|
|
|
|
{ ["radio", "select", "checkbox"].includes(values.type) && <>
|
|
<Typography variant="subtitle2">{ t("report-field.field.choices") }</Typography>
|
|
<FieldArray name="choices" render={ helper => <>
|
|
{ values.choices.map((value: Multilingual<string>, index: number) => <Card>
|
|
<CardHeader subheader={ t("report-field.field.choice", { index: index + 1 }) } action={ <>
|
|
<IconButton onClick={ () => helper.remove(index) }>
|
|
<TrashCan />
|
|
</IconButton>
|
|
</> }/>
|
|
<CardContent>
|
|
<Field name={`choices[${index}]`} component={ ChoiceField } />
|
|
</CardContent>
|
|
</Card>) }
|
|
<Actions>
|
|
<Button variant="contained" startIcon={ <Add /> } color="primary" onClick={() => helper.push({ pl: "", en: "" })}>{ t("actions.add") }</Button>
|
|
</Actions>
|
|
</> } />
|
|
</> }
|
|
|
|
<div className={ classes.preview }>
|
|
<Typography variant="subtitle2">{ t("report-field.preview") }</Typography>
|
|
<FieldPreview field={ fieldFormValuesTransformer.reverseTransform(values) }/>
|
|
</div>
|
|
</div>
|
|
}
|