From 152c6bb153b0a762b3dd271d40f1c5a21d3a9701 Mon Sep 17 00:00:00 2001 From: Luis Felipe Risch <lfr20@inf.ufpr.br> Date: Fri, 26 Feb 2021 12:08:39 -0300 Subject: [PATCH] Problems to update user --- src/Admin/Pages/Pages/SubPages/Users.js | 439 ++++++++++++++++++++++++ 1 file changed, 439 insertions(+) create mode 100644 src/Admin/Pages/Pages/SubPages/Users.js diff --git a/src/Admin/Pages/Pages/SubPages/Users.js b/src/Admin/Pages/Pages/SubPages/Users.js new file mode 100644 index 00000000..d26d0347 --- /dev/null +++ b/src/Admin/Pages/Pages/SubPages/Users.js @@ -0,0 +1,439 @@ +/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre +Departamento de Informatica - Universidade Federal do Parana + +This file is part of Plataforma Integrada MEC. + +Plataforma Integrada MEC is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Plataforma Integrada MEC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ +import React, { useEffect, useState } from 'react'; +//Material ui componets +import { withStyles } from '@material-ui/core/styles'; +import TableBody from '@material-ui/core/TableBody'; +import Grid from "@material-ui/core/Grid"; +import Paper from "@material-ui/core/Paper"; +import TableCell from '@material-ui/core/TableCell'; +import TableRow from '@material-ui/core/TableRow'; +import IconButton from '@material-ui/core/IconButton'; +import VisibilityIcon from '@material-ui/icons/Visibility'; +import { Button, Typography, Chip } from '@material-ui/core'; +import CircularProgress from '@material-ui/core/CircularProgress'; +import AddRoundedIcon from '@material-ui/icons/AddRounded'; +import TextField from '@material-ui/core/TextField'; +import UpdateRoundedIcon from '@material-ui/icons/UpdateRounded' +//Local files +import TableData from '../../../Components/Components/Table'; +import SnackBar from '../../../../Components/SnackbarComponent'; +import LoadingSpinner from '../../../../Components/LoadingSpinner'; +//Services +import { getRequest, putRequest } from '../../../../Components/HelperFunctions/getAxiosConfig' +import { Url } from '../../../Filters'; +//routers +import { Link } from 'react-router-dom'; +import moment from 'moment'; +import styled from 'styled-components' + +let currPage = 0; //var that controlls the current page that we are +let transformListToAsc = false; +let nameFilter = ""; +let emailFilter = ""; +const StyledTableCell = withStyles((theme) => ({ + head: { + backgroundColor: theme.palette.common.black, + color: theme.palette.common.white, + }, + body: { + fontSize: 14, + }, +}))(TableCell); + +const StyledTableRow = withStyles((theme) => ({ + root: { + '&:nth-of-type(odd)': { + backgroundColor: theme.palette.action.hover, + }, + }, +}))(TableRow); + +const Users = () => { + const AddOneLenght = ['']; + + const [error, setError] = useState(null); //Necessary to consult the API, catch errors + const [isLoaded, setIsLoaded] = useState(false); //Necessary to consult the API, wait until complete + const [items, setItems] = useState([]); //Necessary to consult the API, data + const [isLoadingMoreItems, setIsLoadingMoreItems] = useState(false) + const [isUpdating, setIsUpdating] = useState(false) + const [showFilter, setShowFilter] = useState(false) + + const [name, setName] = useState(""); + const [email, setEmail] = useState(""); + + const [snackInfo, setSnackInfo] = useState({ + message: '', + icon: '', + open: false, + color: '', + }) + + // Handle snack infos + const HandleSnack = (message, state, icon, color) => { + setSnackInfo({ + message: message, + icon: icon, + open: state, + color: color + }) + } + + const NameHandler = (event) => { + currPage = 0 + setName(event.target.value) + nameFilter = event.target.value + getRequest( + Url('users', `"name" : "${nameFilter}", "email" : "${emailFilter}"`, `${currPage}`, 'DESC'), + (data, header) => { + const arrData = [...data] + setItems(arrData.concat(AddOneLenght)) + HandleSnack('Filtro aplicado com sucesso', true, 'success', '#228B22') + }, + (error) => { + HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') + } + ) + + } + + const EmailHandler = (event) => { + currPage = 0 + setEmail(event.target.value) + emailFilter = event.target.value + getRequest( + Url('users', `"name" : "${nameFilter}", "email" : "${emailFilter}"`, `${currPage}`, 'DESC'), + (data, header) => { + const arrData = [...data] + setItems(arrData.concat(AddOneLenght)) + HandleSnack('Filtro aplicado com sucesso', true, 'success', '#228B22') + }, + (error) => { + HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') + } + ) + } + + const LoadMoreItens = async (api) => { + setIsLoadingMoreItems(true) + getRequest( + api, + (data, header) => { + const arrData = [...data] + if (arrData.length === 0) { + HandleSnack('Não há mais dados para serem carregados', true, 'warning', '#FFC125') + } else { + const arrItems = [...items] + arrItems.pop(); //Deleting the last position, that was used to display the button of load more items + const arrResult = arrItems.concat(arrData) + setItems(arrResult.concat(AddOneLenght)) + } + setIsLoadingMoreItems(false) + }, + (error) => { + HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') + setIsLoadingMoreItems(false) + } + ) + } + + const InvertList = async () => { + transformListToAsc = !transformListToAsc + currPage = 0 + if (transformListToAsc) { + getRequest( + Url('users', `"name" : "${nameFilter}", "email" : "${emailFilter}"`, `${currPage}`, 'ASC'), + (data, header) => { + const arrData = [...data] + setItems(arrData.concat(AddOneLenght)) + }, + (error) => { + HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') + } + ) + } else { + getRequest( + Url('users', `"name" : "${nameFilter}", "email" : "${emailFilter}"`, `${currPage}`, 'DESC'), + (data, header) => { + const arrData = [...data] + setItems(arrData.concat(AddOneLenght)) + }, + (error) => { + HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') + } + ) + } + } + + const DisplayDate = (date) => { + const convertedData = moment.utc(date); + return moment(convertedData) + .format("LLL") + .toString(); + }; + + const IsUserSubmitter = (userRolesId) => { + const index = userRolesId.indexOf(11); + + if (index > -1) + return <Chip label="submitter" /> + return + } + + const UpdateHandler = async (api) => { + setIsUpdating(true) + getRequest( + api, + (data, header) => { + HandleSnack('A lista de dados foi atualizada', true, 'success', '#228B22') + const arrData = [...data] + setItems(arrData.concat(AddOneLenght)) + setIsUpdating(false) + }, + (error) => { + HandleSnack('Erro ao carregar os dados', true, 'warning', '#FA8072') + setIsUpdating(false) + } + ) + } + + const isUserPublisher = (userRolesId) => { + const index = userRolesId.indexOf(10) + if(index > -1) + return true; + return false; + } + + const turnUserPublisher = (userRolesId, userId) => { + userRolesId.push(10); + const body = { + "user": { + "user": { + "role_ids": userRolesId + }, + } + } + putRequest( + `/users/${userId}`, + body, + (data) => { + currPage = 0; + HandleSnack(`O usuário ${userId}, agora é publicador`, true, 'success', '#228B22') + UpdateHandler(Url('users', `"name" : "${nameFilter}", "email" : "${emailFilter}"`, `${currPage}`, 'DESC')) + }, + (error) => { + HandleSnack('Ocorreu algum erro', true, 'warning', '#FA8072') + } + ) + } + + useEffect(() => { + getRequest( + Url('users', `"name" : "${nameFilter}", "email" : "${emailFilter}"`, '0', 'DESC'), + (data, header) => { + setIsLoaded(true); + setItems(data.concat(AddOneLenght)); + }, + (error) => { + setError(true); + } + ) + }, []); + + + if (error) { + return <div>Error: {error.message}</div>; + } else if (!isLoaded) { + return <LoadingSpinner text="Carregando..." /> + } else { + + //Words in the top part of the table + const topTable = ['ID', 'NOME', 'EMAIL', 'CRIADO EM', 'SCORE', 'PERMISSÃO', 'AÇÃO', "VISUALIZAR"]; + + return ( + <div> + <SnackBar + severity={snackInfo.icon} + text={snackInfo.message} + snackbarOpen={snackInfo.open} + color={snackInfo.color} + handleClose={() => setSnackInfo({ + message: '', + icon: '', + open: false, + color: '' + })} + /> + <Paper style={{ padding: '1em' }}> + <Grid container spacing={3} direction="row" alignItems="center"> + <Grid item xs={6}> + <Typography variant="h4"> + Variáveis de nota + </Typography> + </Grid> + <Grid + item + xs={6} + > + <Grid container justify="flex-end" spacing={3}> + <Grid item> + <Button + variant="contained" + color="secondary" + disabled={isUpdating} + onClick={() => { + currPage = 0 + transformListToAsc = false + UpdateHandler(Url('users', `"name" : "${nameFilter}", "email" : "${emailFilter}"`, `${currPage}`, 'DESC')) + }} + startIcon={<UpdateRoundedIcon />} + > + { + isUpdating ? <CircularProgress size={24} /> : 'Atualizar' + } + </Button> + </Grid> + <Grid item> + <Button + variant="contained" + color="secondary" + onClick={() => { + setShowFilter(!showFilter) + }} + startIcon={<UpdateRoundedIcon />} + > + filtrar + </Button> + </Grid> + <Grid item> + <Button + variant="contained" + color="secondary" + startIcon={<AddRoundedIcon />} + > + Novo + </Button> + </Grid> + </Grid> + </Grid> + </Grid> + { + showFilter ? ( + <Grid container direction="row" justify="space-between" alignItems="center"> + <Grid item> + <TextField + label="Name" + value={name} + onChange={(e) => { NameHandler(e) }} + /> + </Grid> + <Grid item> + <TextField + label="Email" + value={email} + onChange={(e) => { EmailHandler(e) }} + /> + </Grid> + </Grid> + ) : null + } + </Paper> + + <div style={{ height: '2em' }}></div> + + <TableData + top={topTable} + onIconPressed={InvertList} + > + <TableBody> + {items.map((row, index) => ( + index === items.length - 1 ? + <StyledTableRow key={index}> + {/* Button to load more data */} + <StyledTableCell> + <Button + color='primary' + variant='text' + disabled={isLoadingMoreItems} + startIcon={<AddRoundedIcon />} + onClick={() => { + currPage++ + if (transformListToAsc) { + LoadMoreItens(Url('users', `"name" : "${nameFilter}", "email" : "${emailFilter}"`, `${currPage}`, 'ASC')) + } else { + LoadMoreItens(Url('users', `"name" : "${nameFilter}", "email" : "${emailFilter}"`, `${currPage}`, 'DESC')) + } + }} + > + { + isLoadingMoreItems ? <CircularProgress size={24} /> : 'Carregar mais itens' + } + </Button> + </StyledTableCell> + </StyledTableRow> + + : + + <StyledTableRow key={index}> + <StyledTableCell component="th" scope="row">{row.id}</StyledTableCell> + <StyledTableCell align="right">{row.name}</StyledTableCell> + <StyledTableCell align="right">{row.email ? row.email : ""}</StyledTableCell> + <StyledTableCell align="right"> + {DisplayDate(row.created_at)} + </StyledTableCell> + <StyledTableCell align="right">{row.score}</StyledTableCell> + <StyledTableCell align="right"> + { + row.roles.map((chip) => ( + <ChipDiv> + <Chip label={chip.name} key={chip.id}/> + </ChipDiv> + )) + } + </StyledTableCell> + <StyledTableCell align="right"> + <Button + variant="contained" + color="primary" + disabled={isUserPublisher(row.role_ids)} + onClick={() => {turnUserPublisher(row.role_ids, row.id)}} + > + Tornar publicador + </Button> + </StyledTableCell> + <StyledTableCell align="right"> + <Link to={`/admin/user/${row.id}`}> + <IconButton onClick={() => {currPage = 0; transformListToAsc = false}}> + <VisibilityIcon style={{ fill: '#00bcd4' }} /> + </IconButton> + </Link> + </StyledTableCell> + </StyledTableRow> + ))} + </TableBody> + </TableData> + </div> + ) + } +} + +export default Users; + +const ChipDiv = styled.div` + margin-top : 0.5em; +` \ No newline at end of file -- GitLab