diff --git a/src/components/fieldsAnswerForm/FormFieldTable.js b/src/components/fieldsAnswerForm/FormFieldTable.js new file mode 100644 index 0000000000000000000000000000000000000000..e7deb329872e1961bcc7709c7eac2545d5080e62 --- /dev/null +++ b/src/components/fieldsAnswerForm/FormFieldTable.js @@ -0,0 +1,190 @@ +import React from "react"; +import { makeStyles } from "@material-ui/core/styles"; +import Grid from "@material-ui/core/Grid"; +import Paper from "@material-ui/core/Paper"; +import Table from "material-ui/Table/Table"; +import TableBody from "material-ui/Table/TableBody"; +import { TableCell } from "@material-ui/core"; +import { TableContainer } from "@material-ui/core"; +import TableRow from "material-ui/Table/TableRow"; +import MuiThemeProvider from "material-ui/styles/MuiThemeProvider"; +import TextField from "@material-ui/core/TextField"; +import IconButton from "@material-ui/core/IconButton"; +import { Add, Remove } from "@material-ui/icons"; +import { Draggable } from "react-beautiful-dnd"; +import FieldFooterOptions from "./FieldFooterOptions"; +import DefaultField from "./DefaultField"; +import useForm from "../../contexts/useForm"; +import { Typography } from "@material-ui/core"; + +/** CSS styles used on page components. */ +const useStyles = makeStyles((theme) => ({ + paper: { + padding: theme.spacing(3), + width: theme.spacing(100), + ["@media (max-width:1050px)"]: { + width: theme.spacing(63), + ["@media (max-width:849px)"]: { + width: "85%", + }, + }, + marginBottom: "2%", + ["@media (min-width:600px)"]: { + marginLeft: "4%", + }, + }, + questionsGrid: { + marginBottom: "20px", + }, + errorGrid: { + marginTop: "1%", + color: "#ff4646", + width: "80%", + fontSize: "13px", + }, + row: { + display: "flex", + flexDirection: "row", + ["@media (max-width:600px)"]: { + flexDirection: "column", + marginTop: "5%", + }, + }, + selectFormating: { + ["@media (max-width:430px)"]: { + minWidth: "0px", + width: "85%", + }, + minWidth: "250px", + }, + subformSelect: { + ["@media (max-width:430px)"]: { + width: "70%", + fontSize: "76%", + }, + }, + excludeFormating: { + ["@media (max-width:1050px)"]: { + marginLeft: "40%", + }, + }, + excludeFormatingSmall: { + ["@media (max-width:1050px)"]: { + marginLeft: "10%", + }, + ["@media (max-width: 600px)"]: { + marginLeft: "50%", + }, + }, +})); +/** Main function that returns the content of the option 'question'. */ +function FormFieldTable(props) { + /** Style class. */ + const classes = useStyles(); + /** Importing function to set table cell field value. */ + const { setCellField, setTableColumn, setTableRow } = useForm(); + return ( + <Draggable key={props.id} draggableId={props.id} index={props.idq}> + {(provided, snapshot) => { + return ( + <Paper + className={classes.paper} + ref={provided.innerRef} + {...provided.draggableProps} + {...provided.dragHandleProps} + > + <Grid container item xs={12} justify="center"> + <h4>Tabela</h4> + </Grid> + <Grid container> + <DefaultField + question={props.question} + description={props.description} + idq={props.idq} + error={props.error} + /> + <TableContainer component={Paper}> + <MuiThemeProvider> + <Table aria-label="simple table"> + <TableBody displayRowCheckbox={false}> + {props.table.matrix.map((row, rowNumber) => ( + <TableRow + key={rowNumber + row} + sx={{ + "&:last-child td, &:last-child th": { border: 0 }, + }} + > + <TableCell style={{ width: "2%", padding: 20 }}> + <IconButton + aria-label="delete row" + type="submit" + size="small" + variant="contained" + onClick={() => + setTableRow(props.idq, rowNumber, false) + } + > + <Remove /> + </IconButton> + </TableCell> + {row.map((cell, columnNumber) => ( + <TableCell component="th" align='center' scope="row"> + <TextField + id="standard-basic" + defaultValue={cell} + autoComplete="off" + variant="outlined" + onBlur={(e) => + setCellField( + e.target.value, + props.idq, + rowNumber, + columnNumber + ) + } + /> + </TableCell> + ))} + </TableRow> + ))} + <TableRow style={{height:"1%"}} align="center"> + <TableCell colSpan={props.table.columns + 1} align='center' scope="row"> + <IconButton + aria-label="add row" + type="submit" + size="small" + variant="contained" + onClick={() => setTableRow(props.idq, null, true)} + > + <Add /> + </IconButton> + </TableCell> + </TableRow> + </TableBody> + </Table> + </MuiThemeProvider> + </TableContainer> + <Grid + item + container + direction="row" + justify="flex-end" + alignItems="flex-end" + marginTop="20" + xs={12} + sm={4} + > + <FieldFooterOptions + idq={props.idq} + required={props.validation[0].value} + /> + </Grid> + </Grid> + </Paper> + ); + }} + </Draggable> + ); +} + +export default FormFieldTable; \ No newline at end of file diff --git a/src/components/fieldsDisplayForm/DisplayForm.js b/src/components/fieldsDisplayForm/DisplayForm.js index 682db7b1ef18bc315368606aedb061e9e8de3b5d..b6d134fef679a825999309969b94f881dccfb054 100644 --- a/src/components/fieldsDisplayForm/DisplayForm.js +++ b/src/components/fieldsDisplayForm/DisplayForm.js @@ -10,6 +10,7 @@ import FormFieldRadio from "./FormFieldRadio"; import FormFieldCheckbox from "./FormFieldCheckbox"; import FormFieldTitle from "./FormFieldTitle"; import FormFieldSubForm from "./FormFieldSubform"; +import FormFieldTable from "./FormFieldTable"; import uuid from "uuid/v4"; import { verifyError } from "./utils/schemas"; import SideMenu from "./SideMenu"; @@ -219,6 +220,18 @@ function DisplayForm() { multAnswer={x.mult_answer} /> ); + else if (x.type === 5) + return ( + <FormFieldTable + question={x.question} + table={x.table} + idq={index} + description={x.description} + validation={x.validation} + id={x.id} + error={x.error} + /> + ); }) ) : ( <p> carregando... </p> diff --git a/src/components/fieldsDisplayForm/FormFieldTable.js b/src/components/fieldsDisplayForm/FormFieldTable.js new file mode 100644 index 0000000000000000000000000000000000000000..ed9d31872328422672635af46a56b55f1322eb97 --- /dev/null +++ b/src/components/fieldsDisplayForm/FormFieldTable.js @@ -0,0 +1,231 @@ +import React from "react"; +import { makeStyles } from "@material-ui/core/styles"; +import Grid from "@material-ui/core/Grid"; +import Paper from "@material-ui/core/Paper"; +import Table from "material-ui/Table/Table"; +import TableBody from "material-ui/Table/TableBody"; +import { Button, TableCell } from "@material-ui/core"; +import { TableContainer } from "@material-ui/core"; +import TableHeader from "material-ui/Table/TableHeader"; +import TableRow from "material-ui/Table/TableRow"; +import TableFooter from "material-ui/Table/TableFooter"; +import Toolbar from "material-ui/Toolbar"; +import MuiThemeProvider from "material-ui/styles/MuiThemeProvider"; +import TextField from "@material-ui/core/TextField"; +import IconButton from "@material-ui/core/IconButton"; +import Select from "@material-ui/core/Select"; +import MenuItem from "@material-ui/core/MenuItem"; +import Tooltip from "@material-ui/core/Tooltip"; +import AddCircleIcon from "@material-ui/icons/AddCircle"; +import { Add, Remove } from "@material-ui/icons"; +import FormControl from "@material-ui/core/FormControl"; +import InputLabel from "@material-ui/core/InputLabel"; +import { Draggable } from "react-beautiful-dnd"; +import FieldFooterOptions from "./FieldFooterOptions"; +import DefaultField from "./DefaultField"; +import CloseIcon from "@material-ui/icons/Close"; +import useForm from "../../contexts/useForm"; +import { Typography } from "@material-ui/core"; + +/** CSS styles used on page components. */ +const useStyles = makeStyles((theme) => ({ + paper: { + padding: theme.spacing(3), + width: theme.spacing(100), + ["@media (max-width:1050px)"]: { + width: theme.spacing(63), + ["@media (max-width:849px)"]: { + width: "85%", + }, + }, + marginBottom: "2%", + ["@media (min-width:600px)"]: { + marginLeft: "4%", + }, + }, + questionsGrid: { + marginBottom: "20px", + }, + errorGrid: { + marginTop: "1%", + color: "#ff4646", + width: "80%", + fontSize: "13px", + }, + row: { + display: "flex", + flexDirection: "row", + ["@media (max-width:600px)"]: { + flexDirection: "column", + marginTop: "5%", + }, + }, + selectFormating: { + ["@media (max-width:430px)"]: { + minWidth: "0px", + width: "85%", + }, + minWidth: "250px", + }, + subformSelect: { + ["@media (max-width:430px)"]: { + width: "70%", + fontSize: "76%", + }, + }, + excludeFormating: { + ["@media (max-width:1050px)"]: { + marginLeft: "40%", + }, + }, + excludeFormatingSmall: { + ["@media (max-width:1050px)"]: { + marginLeft: "10%", + }, + ["@media (max-width: 600px)"]: { + marginLeft: "50%", + }, + }, +})); +/** Main function that returns the content of the option 'question'. */ +function FormFieldTable(props) { + /** Style class. */ + const classes = useStyles(); + /** Importing function to set table cell field value. */ + const { setCellField, setTableColumn, setTableRow } = useForm(); + return ( + <Draggable key={props.id} draggableId={props.id} index={props.idq}> + {(provided, snapshot) => { + return ( + <Paper + className={classes.paper} + ref={provided.innerRef} + {...provided.draggableProps} + {...provided.dragHandleProps} + > + <Grid container item xs={12} justify="center"> + <h4>Tabela</h4> + </Grid> + <Grid container> + <DefaultField + question={props.question} + description={props.description} + idq={props.idq} + error={props.error} + /> + <TableContainer component={Paper}> + <MuiThemeProvider> + <Table aria-label="simple table"> + <TableBody displayRowCheckbox={false}> + <TableRow sx={{ + "&:last-child td, &:last-child th": { border: 0 }, + }}> + <TableCell style={{ width: "2%", padding: 20 }}></TableCell> + {[...Array(props.table.columns).keys()].map((column) => ( + <TableCell component="th" align='center' scope="row"> + <IconButton + aria-label="delete column" + type="submit" + size="small" + variant="contained" + onClick={() => + setTableColumn(props.idq, column, false) + } + > + <Remove /> + </IconButton> + </TableCell> + ))} + <TableCell rowSpan={props.table.rows + 2} style={{ width: "2%", padding: 20 }}> + <IconButton + aria-label="add column" + type="submit" + size="small" + variant="contained" + onClick={() => setTableColumn(props.idq, null, true)} + > + <Add /> + </IconButton> + </TableCell> + </TableRow> + {props.table.matrix.map((row, rowNumber) => ( + <TableRow + key={rowNumber + row} + sx={{ + "&:last-child td, &:last-child th": { border: 0 }, + }} + > + <TableCell style={{ width: "2%", padding: 20 }}> + <IconButton + aria-label="delete row" + type="submit" + size="small" + variant="contained" + onClick={() => + setTableRow(props.idq, rowNumber, false) + } + > + <Remove /> + </IconButton> + </TableCell> + {row.map((cell, columnNumber) => ( + <TableCell component="th" align='center' scope="row"> + <TextField + id="standard-basic" + defaultValue={cell} + autoComplete="off" + variant="outlined" + onBlur={(e) => + setCellField( + e.target.value, + props.idq, + rowNumber, + columnNumber + ) + } + /> + </TableCell> + ))} + </TableRow> + ))} + <TableRow style={{height:"1%"}} align="center"> + <TableCell colSpan={props.table.columns + 1} align='center' scope="row"> + <IconButton + aria-label="add row" + type="submit" + size="small" + variant="contained" + onClick={() => setTableRow(props.idq, null, true)} + > + <Add /> + </IconButton> + </TableCell> + </TableRow> + </TableBody> + </Table> + </MuiThemeProvider> + </TableContainer> + <Grid + item + container + direction="row" + justify="flex-end" + alignItems="flex-end" + marginTop="20" + xs={12} + sm={4} + > + <FieldFooterOptions + idq={props.idq} + required={props.validation[0].value} + /> + </Grid> + </Grid> + </Paper> + ); + }} + </Draggable> + ); +} + +export default FormFieldTable; diff --git a/src/components/fieldsDisplayForm/SideMenu.js b/src/components/fieldsDisplayForm/SideMenu.js index 0ef7863b1063c7f8bca1af076f70adc93673aae9..5a1aeee2d8207dca56038d739bd22a1ce05e8d8f 100644 --- a/src/components/fieldsDisplayForm/SideMenu.js +++ b/src/components/fieldsDisplayForm/SideMenu.js @@ -10,6 +10,7 @@ import ListAltIcon from "@material-ui/icons/ListAlt"; import TextFieldsIcon from "@material-ui/icons/TextFields"; import useForm from "../../contexts/useForm"; import Tooltip from "@material-ui/core/Tooltip"; +import { TableChart } from "@material-ui/icons"; const useStyles = makeStyles((theme) => ({ addButton: { @@ -58,6 +59,7 @@ function SideMenu(props) { addToFormRadio, addToFormCheckbox, addToFormSubform, + addToFormTable } = useForm(); const classes = useStyles(); const msg = { @@ -66,6 +68,7 @@ function SideMenu(props) { uniq: "Adicionar seleção única", mult: "Adicionar múltipla escolha", sub: "Adicionar subformulário", + tab: "Adicionar questão com tabela" }; return ( @@ -144,6 +147,20 @@ function SideMenu(props) { Subformulário </IconButton> </Tooltip> + <Tooltip title={msg.tab} aria-label={msg.tab}> + <IconButton + aria-label="add table" + type="submit" + size="medium" + className={classes.addButton} + onClick={() => { + addToFormTable(); + }} + > + <TableChart /> + Tabela + </IconButton> + </Tooltip> </Grid> </Paper> ); diff --git a/src/components/fieldsDisplayForm/utils/BackendTranslation.js b/src/components/fieldsDisplayForm/utils/BackendTranslation.js index 6e973d107fda29360300883a0a4fb721cbfed294..8d981fdeeaf2b990ea102103498dc124240def99 100644 --- a/src/components/fieldsDisplayForm/utils/BackendTranslation.js +++ b/src/components/fieldsDisplayForm/utils/BackendTranslation.js @@ -15,7 +15,8 @@ function setInput( validation, subForm, type, - id + id, + table ) { json.inputs.push({ placement: placement, @@ -26,6 +27,7 @@ function setInput( sugestions: sugestions, subForm: subForm ? subForm : null, id: id, + table: table ? table: null, }); } @@ -102,7 +104,8 @@ export default async function createBackendForm(form) { setValidation(form[i]), setSubform(form[i], i), form[i].type, - form[i].inputId + form[i].inputId, + form[i].table ); } return json; diff --git a/src/components/fieldsDisplayForm/utils/FormComposition.js b/src/components/fieldsDisplayForm/utils/FormComposition.js index 6ba781622b676840c86bec0178be0851c3a3c49f..427f990e74861f45db75f4a239a2a969b9c33047 100644 --- a/src/components/fieldsDisplayForm/utils/FormComposition.js +++ b/src/components/fieldsDisplayForm/utils/FormComposition.js @@ -202,3 +202,40 @@ export function pushSubform( }, }); } + +/** Function that pushes a 'table' object into the form array. + * @param form - the form where the field will be pushed; + * @param question - the question; + * @param description - the description of the question; + * @param table - the table object; + * @param validation - optional validation the question may have. + */ + export function pushTable( + form, + question, + description, + table, + validation, + id +) { + let value = { + type: 5, + question: question ? question : "", + validation: validation ? validation : [{ type: "required", value: false }], + table: table ? table : { + rows: 2, + columns: 2, + matrix : [["1", "2"], ["3", "4"]] + }, + description: description ? description : "", + id: uuid(), + inputId: id ? id : null, + error: { + errorMsg: { + question: question ? "" : "Este campo é obrigatório!", + description: "", + }, + }, + }; + return form.push(value); +} diff --git a/src/components/fieldsDisplayForm/utils/FrontEndTranslation.js b/src/components/fieldsDisplayForm/utils/FrontEndTranslation.js index 66b6fa70fda8c9b84060273e043bc94acd05b915..741f5c1e46a10dcf3e57f3d9c00be1fd9eb536eb 100644 --- a/src/components/fieldsDisplayForm/utils/FrontEndTranslation.js +++ b/src/components/fieldsDisplayForm/utils/FrontEndTranslation.js @@ -5,6 +5,7 @@ import { pushRadio, pushCheckbox, pushSubform, + pushTable } from "./FormComposition"; /** Function that recieves the validation from the backend to translate it to the frontend. @@ -88,6 +89,16 @@ export function createFrontendForm(formData) { validationTranslate(option.validation), option.id ); + break; + case 5: + pushTable( + json, + option.question, + option.description, + option.table, + validationTranslate(option.validation), + option.id + ); default: } }); diff --git a/src/components/fieldsGetForm/JornalFolder/FormFieldTable.js b/src/components/fieldsGetForm/JornalFolder/FormFieldTable.js new file mode 100644 index 0000000000000000000000000000000000000000..53da2680eea1b48f78a407f083b4e92517fe6aa7 --- /dev/null +++ b/src/components/fieldsGetForm/JornalFolder/FormFieldTable.js @@ -0,0 +1,104 @@ +import React, { useEffect } from "react"; +import { makeStyles } from "@material-ui/core/styles"; +import Grid from "@material-ui/core/Grid"; +import Paper from "@material-ui/core/Paper"; +import Typography from "@material-ui/core/Typography"; +import Checkbox from "@material-ui/core/Checkbox"; +import Table from "material-ui/Table"; +import TableBody from "material-ui/Table/TableBody"; +import { TableCell, TableRow } from "@material-ui/core"; +import { TableContainer } from "@material-ui/core"; +import MuiThemeProvider from "material-ui/styles/MuiThemeProvider"; + + +const useStyles = makeStyles((theme) => ({ + paper: { + padding: theme.spacing(3), + width: theme.spacing(100), + marginBottom: "2%", + ["@media (max-width: 896px)"]: { + width: "300px", + }, + }, + questionsGrid: { + marginBottom: "20px", + }, + text: { + color: "black", + }, +})); + +function FormFieldTable(props) { + const classes = useStyles(); + console.log(props.answer); + let table; + if (props.answer) + table = props.answer[0].value; + console.log("table: ",table); + + /** + * Function to check if an index has a true value. + * @param index - Index of a given value. + */ + + /** HTML to be displayed. */ + const table_display = (() => { + return ( + <Grid container> + <TableContainer component={Paper}> + <MuiThemeProvider> + <Table aria-label="simple table"> + <TableBody displayRowCheckbox={false}> + {table? table.matrix.map((row, rowNumber) => ( + <TableRow + key={rowNumber} + sx={{ + "&:last-child td, &:last-child th": { border: 0 }, + }} + > + {row.map((cell, columnNumber) => ( + <TableCell component="th" scope="row"> + {cell} + </TableCell> + ))} + </TableRow> + )) : ""} + </TableBody> + </Table> + </MuiThemeProvider> + </TableContainer> + <Grid + item + container + direction="row" + justify="flex-end" + alignItems="flex-end" + xs={3} + ></Grid> + </Grid> + ); + }); + + return ( + <Paper className={classes.paper}> + <Grid container> + <Grid item xs={12} className={classes.questionsGrid}> + <Typography>id: {Number(props.place)}</Typography> + <Typography + style={{ wordWrap: "break-word" }} + className={classes.text} + variant="h6" + > + {props.question} + </Typography> + <Typography style={{ wordWrap: "break-word" }} variant="h8"> + {props.description} + </Typography> + </Grid> + {table_display()} + </Grid> + </Paper> + ); +} + +export default FormFieldTable; \ No newline at end of file diff --git a/src/components/fieldsGetForm/JornalFolder/FormJornal.js b/src/components/fieldsGetForm/JornalFolder/FormJornal.js index 7a5db6ae67e0ba4eb2de39546a5f2708d8a34c66..826320d73d5981f11a3c91964d8545cb4115353c 100644 --- a/src/components/fieldsGetForm/JornalFolder/FormJornal.js +++ b/src/components/fieldsGetForm/JornalFolder/FormJornal.js @@ -8,6 +8,7 @@ import FormFieldText from "./FormFieldText"; import FormFieldSelect from "./FormFieldSelect"; import FormFieldRadio from "./FormFieldRadio"; import FormFieldCheckbox from "./FormFieldCheckbox"; +import FormFieldTable from "./FormFieldTable"; import FormFieldTitle from "./FormFieldTitle"; import FormFieldSubform from "./FormFieldSubform"; import JornalTab from "./JornalTab"; @@ -83,6 +84,7 @@ function Jornal(props) { ); } } + console.log(props.formArray[selectedForm].inputAnswers); /** * Function to change the current page to a new one. @@ -176,6 +178,18 @@ function Jornal(props) { place={input.placement - 1} /> ); + else if (input.type === 5) + return ( + <FormFieldTable + question={input.question} + description={input.description} + options={input.sugestions} + id={input.id} + answer={findAnswer(input.id)} + place={input.placement} + /> + ); + })} </div> </Grid> diff --git a/src/components/fieldsGetForm/SummaryFolder/FormFieldTable.js b/src/components/fieldsGetForm/SummaryFolder/FormFieldTable.js new file mode 100644 index 0000000000000000000000000000000000000000..de43443bae184b5b0583a46351cc487f2164e97e --- /dev/null +++ b/src/components/fieldsGetForm/SummaryFolder/FormFieldTable.js @@ -0,0 +1,117 @@ +import React, { useEffect } from "react"; +import { makeStyles } from "@material-ui/core/styles"; +import Grid from "@material-ui/core/Grid"; +import Paper from "@material-ui/core/Paper"; +import Typography from "@material-ui/core/Typography"; +import Checkbox from "@material-ui/core/Checkbox"; +import Table from "material-ui/Table"; +import TableBody from "material-ui/Table/TableBody"; +import { TableCell, TableRow } from "@material-ui/core"; +import { TableContainer } from "@material-ui/core"; +import MuiThemeProvider from "material-ui/styles/MuiThemeProvider"; +import { useState } from "react"; +import { Button } from "@material-ui/core"; +import { Collapse } from "@material-ui/core"; + +const useStyles = makeStyles((theme) => ({ + paper: { + padding: theme.spacing(3), + width: theme.spacing(100), + marginBottom: "2%", + ["@media (max-width: 896px)"]: { + width: "300px", + }, + }, + questionsGrid: { + marginBottom: "20px", + }, + text: { + color: "black", + }, + button: { + background: "#05a5dd", + color: "white", + }, +})); + +function FormFieldTable(props) { + const classes = useStyles(); + const [indexState, setIndexState] = useState({}); + console.log(props.answers); + + const handleClick = (index) => { + if (indexState[index] == true) + setIndexState({ ...indexState, [index]: false }); + else setIndexState({ ...indexState, [index]: true }); + console.log(indexState); + }; + + return ( + <Paper className={classes.paper}> + <Grid container> + <Grid item xs={12} className={classes.questionsGrid}> + <Typography>id: {Number(props.place)}</Typography> + <Typography + style={{ wordWrap: "break-word" }} + className={classes.text} + variant="h6" + > + {props.question} + </Typography> + <Typography style={{ wordWrap: "break-word" }} variant="h8"> + {props.description} + </Typography> + </Grid> + {props.answers.map((table, index) => ( + <Grid style={{ marginBottom: "10px" }} container> + <Button + className={classes.button} + variant="contained" + onClick={() => handleClick(index)} + fullWidth + > + Tabela {index} + </Button> + <Collapse in={indexState[index]}> + <TableContainer component={Paper}> + <MuiThemeProvider> + <Table aria-label="simple table" key={index}> + <TableBody displayRowCheckbox={false}> + {table.matrix ? ( + table.matrix.map((row, rowNumber) => ( + <TableRow + key={100 * table.id + rowNumber} + sx={{ + "&:last-child td, &:last-child th": { border: 0 }, + }} + > + {row.map((cell, columnNumber) => ( + <TableCell component="th" scope="row"> + {cell} + </TableCell> + ))} + </TableRow> + )) + ) : ( + <Grid style={{ padding: "10px" }}> + <Typography + style={{ wordWrap: "break-word" }} + variant="h8" + > + Sem resposta! + </Typography> + </Grid> + )} + </TableBody> + </Table> + </MuiThemeProvider> + </TableContainer> + </Collapse> + </Grid> + ))} + </Grid> + </Paper> + ); +} + +export default FormFieldTable; diff --git a/src/components/fieldsGetForm/SummaryFolder/FormSummary.js b/src/components/fieldsGetForm/SummaryFolder/FormSummary.js index 54144a98218b56cbb98f99881ac4fbd30cd064c1..8da6fd8b191ec21228106548c813a434cfd09fbb 100644 --- a/src/components/fieldsGetForm/SummaryFolder/FormSummary.js +++ b/src/components/fieldsGetForm/SummaryFolder/FormSummary.js @@ -8,6 +8,7 @@ import FormFieldSelect from "./FormFieldSelect"; import FormFieldRadio from "./FormFieldRadio"; import FormFieldCheckbox from "./FormFieldCheckbox"; import FormFieldSubform from "./FormFieldSubform"; +import FormFieldTable from "./FormFieldTable"; const useStyles = makeStyles(theme => ({ menu: { @@ -164,6 +165,16 @@ function Summary(props) { findAnswer={findAnswer} /> ); + else if (input.type === 5) + return ( + <FormFieldTable + question={input.question} + description={input.description} + id={input.id} + place={input.placement} + answers={findAnswer(input.id)} + /> + ); })} </div> </Grid> diff --git a/src/components/fieldsVisualizeForm/FormFieldTable.js b/src/components/fieldsVisualizeForm/FormFieldTable.js new file mode 100644 index 0000000000000000000000000000000000000000..abe4a1ad16db5fd6da4fc7113a562e12d2a9b76d --- /dev/null +++ b/src/components/fieldsVisualizeForm/FormFieldTable.js @@ -0,0 +1,89 @@ +import React, { useState, useEffect } from "react"; +import { makeStyles } from "@material-ui/core/styles"; +import Grid from "@material-ui/core/Grid"; +import Paper from "@material-ui/core/Paper"; +import TextField from "@material-ui/core/TextField"; +import Typography from "@material-ui/core/Typography"; +import Table from "material-ui/Table/Table"; +import TableBody from "material-ui/Table/TableBody"; +import { Button, TableCell } from "@material-ui/core"; +import { TableContainer } from "@material-ui/core"; +import TableRow from "material-ui/Table/TableRow"; +import MuiThemeProvider from "material-ui/styles/MuiThemeProvider"; + +const useStyles = makeStyles((theme) => ({ + paper: { + padding: theme.spacing(3), + width: theme.spacing(100), + height: "15%", + ["@media (max-width:827px)"]: { + width: "85%", + }, + marginBottom: "12px", + }, + questionsGrid: { + marginBottom: "20px", + }, + text: { + color: "black", + }, + validation: { + fontSize: "14px", + color: "red", + }, +})); + +function FormFieldTable(props) { + const classes = useStyles(); + + return ( + <Paper className={classes.paper}> + <Grid container> + <Grid item xs={12} className={classes.questionsGrid}> + <Typography + style={{ wordWrap: "break-word" }} + className={classes.text} + variant="h6" + > + {props.question} + </Typography> + <Typography style={{ wordWrap: "break-word" }} variant="h8"> + {props.description} + </Typography> + </Grid> + <TableContainer component={Paper}> + <MuiThemeProvider> + <Table aria-label="simple table"> + <TableBody displayRowCheckbox={false}> + {props.table.matrix.map((row, rowNumber) => ( + <TableRow + key={rowNumber} + sx={{ + "&:last-child td, &:last-child th": { border: 0 }, + }} + > + {row.map((cell, columnNumber) => ( + <TableCell component="th" scope="row"> + {cell} + </TableCell> + ))} + </TableRow> + ))} + </TableBody> + </Table> + </MuiThemeProvider> + </TableContainer> + <Grid + item + container + direction="row" + justify="flex-end" + alignItems="flex-end" + xs={3} + ></Grid> + </Grid> + </Paper> + ); +} + +export default FormFieldTable; \ No newline at end of file diff --git a/src/contexts/useForm.js b/src/contexts/useForm.js index 32675ebb847044c37165631bb7850d267a980dce..5e82cacddca179789f729936f8022a8166a89896 100644 --- a/src/contexts/useForm.js +++ b/src/contexts/useForm.js @@ -17,6 +17,7 @@ import { pushRadio, pushCheckbox, pushSubform, + pushTable } from "../components/fieldsDisplayForm/utils/FormComposition"; import api from "../api"; @@ -84,6 +85,17 @@ const useForm = () => { pushSubform(form, question, description, subformId, validation); setForm([...form]); } + /** Function that adds a 'table' object into the form array. + * Its parameters are used on the translation of the backend data. + * @param question - the question; + * @param description - the description of the question; + * @param table - the table object; + * @param validation - optional validation the question may have. + */ + function addToFormTable(question, description, table, validation) { + pushTable(form, question, description, table, validation); + setForm([...form]); + } /** Function used on FormFieldRadio, FormFieldCheckbox and FormFieldSelect, it adds a new option field for those types of questions. * @param index - the position on the array that the operation needs to be done. @@ -189,6 +201,51 @@ const useForm = () => { setForm([...form]); } + /** Function used on FormFieldTable, it updates the value of a table cell. + * @param value - the value being typed by the user; + * @param index - the position on the array that the operation needs to be done. + * @param row - the row of the cell. + * @param column - the column of the cell. + */ + async function setCellField(value, index, row, column) { + form[index].table.matrix[row][column] = value; + setForm([...form]); + } + + /** Function used on FormFieldTable, it updates the value of a table's column count. + * @param index - the position on the array that the operation needs to be done. + * @param operation - the operation to be performed (adding or deleting). + */ + async function setTableColumn(index, column, operation) { + if (operation){ + form[index].table.matrix.map((row) => row.push("")); + form[index].table.columns++; + } + else if (form[index].table.columns > 1){ + form[index].table.matrix.map((row) => row.splice(column, 1)); + form[index].table.columns--; + } + setForm([...form]); + } + + /** Function used on FormFieldTable, it updates the value of a table's row count. + * @param index - the position on the array that the operation needs to be done. + * @param operation - the operation to be performed (adding or deleting). + */ + async function setTableRow(index, row, operation) { + if (operation){ + let temp = new Array(form[index].table.columns).fill(""); + form[index].table.matrix.push(temp); + form[index].table.rows++; + } + else if (form[index].table.rows > 1){ + form[index].table.matrix.splice(row, 1); + console.log("removed line ", row); + form[index].table.rows--; + } + setForm([...form]); + } + /** Function used on FormFieldText to remove the validaiton. * @param index - the position on the array that the operation needs to be done. */ @@ -338,6 +395,7 @@ const useForm = () => { addToFormRadio, addToFormCheckbox, addToFormSubform, + addToFormTable, addSelectOption, removeSelectOption, deleteFromForm, @@ -349,6 +407,9 @@ const useForm = () => { setSubformId, setValidationType, setValidationValue, + setCellField, + setTableColumn, + setTableRow, removeValidation, setMultipleAnswer, onDragEnd, diff --git a/src/pages/AnswerForm.js b/src/pages/AnswerForm.js index 85d69f860964e84d8f93ec7a77609a37efe8cedd..51295486e1e74fdf0af11345ff6f827faa10fad8 100644 --- a/src/pages/AnswerForm.js +++ b/src/pages/AnswerForm.js @@ -136,6 +136,7 @@ function AnwserForm() { } } + console.log("retVal: ", retVal); return retVal; } diff --git a/src/pages/VisualizeForm.js b/src/pages/VisualizeForm.js index b77e4915a64dc06d4440057a31a743aa4545077d..0e98f3ed8ff330dcb6f96e0b8f69336078beef62 100644 --- a/src/pages/VisualizeForm.js +++ b/src/pages/VisualizeForm.js @@ -14,6 +14,7 @@ import FormFieldRadio from "../components/fieldsVisualizeForm/FormFieldRadio"; import FormFieldCheckbox from "../components/fieldsVisualizeForm/FormFieldCheckbox"; import FormFieldTitle from "../components/fieldsVisualizeForm/FormFieldTitle"; import FormFieldSubform from "../components/fieldsVisualizeForm/FormFieldSubform"; +import FormFieldTable from '../components/fieldsVisualizeForm/FormFieldTable'; const useStyles = makeStyles(theme => ({ button: { @@ -189,6 +190,16 @@ function VisualizeForm() { id={input.subForm.contentFormId} /> ); + else if (input.type === 5) + return ( + <FormFieldTable + question={input.question} + description={input.description} + options={input.sugestions} + id={input.id} + table={input.table} + /> + ); })} <Grid container justify="center"> <Button