Skip to content

Commit

Permalink
Merge pull request #12 from CinCoders/develop
Browse files Browse the repository at this point in the history
Version 1.1.0
  • Loading branch information
dcruzb authored Jan 25, 2024
2 parents 83c7534 + 41a50b4 commit 4ee996f
Show file tree
Hide file tree
Showing 8 changed files with 249 additions and 82 deletions.
45 changes: 34 additions & 11 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "research-front",
"version": "1.0.0",
"version": "1.1.0",
"description": "Research Dashboard - System to display information extracted from professors' Lattes curriculum.",
"license": "MIT",
"author": "CInCoders <[email protected]> (https://cincoders.cin.ufpe.br)",
Expand All @@ -24,7 +24,7 @@
"@mui/icons-material": "^5.4.1",
"@mui/material": "^5.5.0",
"@mui/x-data-grid": "^5.12.1",
"axios": "^0.24.0",
"axios": "^1.6.5",
"keycloak-js": "^18.0.0",
"oidc-client-ts": "^2.2.4",
"react": "18.1",
Expand Down
176 changes: 116 additions & 60 deletions src/pages/ImportXml/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,77 +2,27 @@ import { DataGrid, GridColDef, ptBR } from '@mui/x-data-grid';
import { toast, useNavbar } from '@cincoders/cinnamon';
import { useState, useEffect, useCallback } from 'react';
import { Modal, Grow } from '@mui/material';
import { XMLDiv, DataDiv, ButtonsDiv, ImportButton, CardType } from './styles';
import RefreshIcon from '@mui/icons-material/Refresh';
import { XMLDiv, DataDiv, ButtonsDiv, ImportButton, CardType, AnimatedRefreshButton } from './styles';
import { ImportXmlService } from '../../services/ImportXmlService';
import { renderImportStatus } from '../../components/ImportStatus';
import ImportCard from '../../components/ImportCard';
import { ImportXmlRows } from '../../types/Xml.d';

const columns: GridColDef[] = [
{
field: 'name',
headerName: 'Arquivo',
headerAlign: 'center',
align: 'center',
description: 'Nome do arquivo',
flex: 7,
},
{
field: 'professor',
headerName: 'Professor',
headerAlign: 'center',
align: 'center',
description: 'Professor cujo XML foi importado',
flex: 11,
type: 'string',
},
{
field: 'status',
headerName: 'Status',
renderCell: renderImportStatus,
headerAlign: 'center',
align: 'center',
description: 'Status da importação',
flex: 6,
},
{
field: 'importTime',
headerName: 'Tempo da importação',
headerAlign: 'center',
align: 'center',
description: 'Duração de tempo que o XML foi importado',
flex: 7,
type: 'string',
},
{
field: 'includedAt',
headerName: 'Data da importação',
headerAlign: 'center',
align: 'center',
description: 'Data que o XML foi importado',
flex: 10,
},
{
field: 'user',
headerName: 'Usuário',
headerAlign: 'center',
align: 'center',
description: 'Usuário que realizou a importação',
flex: 10,
},
];
import ImportCard from '../../components/ImportCard';
import { ImportXmlDto } from '../../types/Xml.d';

function ImportXml() {
const navbar = useNavbar();
const [loading, setLoading] = useState<boolean>(true);
const [rows, setRows] = useState<ImportXmlRows[]>([]);
const [rows, setRows] = useState<ImportXmlDto[]>([]);
const [open, setOpen] = useState<boolean>(false);
const [pageState, setPageState] = useState({
page: 1,
total: 0,
isLoading: false,
pageSize: 25,
});
const [rotatingButtons, setRotatingButtons] = useState<{ [xmlId: string]: boolean }>({});

function dateInFull(date: Date) {
const fullDate = date.toLocaleString(undefined, {
year: 'numeric',
Expand All @@ -84,22 +34,27 @@ function ImportXml() {
});
return fullDate;
}

const loadPaginatedData = useCallback(async (page: number, pageSize: number) => {
setRows([]);
setLoading(true);

try {
const { data } = await ImportXmlService.findAllImportedXmls(pageSize, page - 1);
const xmls = data.data.map((elem, i) => ({
id: i,

const xmls = data.data.map(elem => ({
id: elem.id,
professor: elem.professor,
name: elem.name,
status: elem.status,
includedAt: dateInFull(new Date(elem.includedAt)),
importTime: elem.importTime ? `${elem.importTime}s` : '',
user: elem.user,
storedXml: elem.storedXml,
}));
setPageState(currentValue => ({ ...currentValue, total: data.totalElements }));

setRows(xmls);
setPageState(currentValue => ({ ...currentValue, total: data.totalElements }));
} catch {
toast.error('Não foi possível carregar o histórico de importações. Tente novamente mais tarde.', {
containerId: 'page',
Expand All @@ -109,6 +64,106 @@ function ImportXml() {
}
}, []);

const handleReprocessClick = async (xmlId: string) => {
setRotatingButtons(prevState => ({ ...prevState, [xmlId]: true }));
try {
await ImportXmlService.reprocessXML(xmlId);
await loadPaginatedData(1, pageState.pageSize);
} catch (error) {
toast.error('Não foi possível reprocessar o XML. Tente novamente mais tarde.', {
containerId: 'page',
});
} finally {
setRotatingButtons(prevState => ({ ...prevState, [xmlId]: false }));
}
};

const columns: GridColDef[] = [
{
field: 'name',
headerName: 'Arquivo',
headerAlign: 'center',
align: 'center',
description: 'Nome do arquivo',
flex: 7,
},
{
field: 'professor',
headerName: 'Professor',
headerAlign: 'center',
align: 'center',
description: 'Professor cujo XML foi importado',
flex: 11,
type: 'string',
},
{
field: 'status',
headerName: 'Status',
renderCell: renderImportStatus,
headerAlign: 'center',
align: 'center',
description: 'Status da importação',
flex: 6,
},
{
field: 'importTime',
headerName: 'Tempo da importação',
headerAlign: 'center',
align: 'center',
description: 'Duração de tempo que o XML foi importado',
flex: 7,
type: 'string',
},
{
field: 'includedAt',
headerName: 'Data da importação',
headerAlign: 'center',
align: 'center',
description: 'Data que o XML foi importado',
flex: 10,
},
{
field: 'user',
headerName: 'Usuário',
headerAlign: 'center',
align: 'center',
description: 'Usuário que realizou a i mportação',
flex: 10,
},
{
field: 'reload',
headerName: '',
headerAlign: 'center',
align: 'center',
flex: 2,
renderCell: params => {
const { status, storedXml, id } = params.row;
if (storedXml) {
return (
<AnimatedRefreshButton
isrotating={status === 'In Progress' || status === 'Pending' || rotatingButtons[id]}
onClick={() => handleReprocessClick(id)}
variant='text'
style={{
pointerEvents:
status === 'In Progress' || status === 'Pending' || rotatingButtons[id] ? 'none' : 'auto',
}}
sx={{
'&:hover': {
backgroundColor: 'initial',
},
}}
disableRipple
>
<RefreshIcon />
</AnimatedRefreshButton>
);
}
return null;
},
},
];

useEffect(() => {
navbar?.setTitle('Importação de XML');
}, [navbar]);
Expand Down Expand Up @@ -147,6 +202,7 @@ function ImportXml() {
},
},
}}
key={pageState.page}
/>
</DataDiv>
<ButtonsDiv>
Expand Down
28 changes: 27 additions & 1 deletion src/pages/ImportXml/styles.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,30 @@
import { Box, Button, Card, styled } from '@mui/material';
import { Box, Button, Card } from '@mui/material';
import styled, { keyframes, css } from 'styled-components';

interface CustomButtonProps {
isrotating: boolean;
}

const spin = keyframes`
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
`;

export const AnimatedRefreshButton = styled(Button)<CustomButtonProps>`
background: none;
border: none;
cursor: pointer;
${(props: CustomButtonProps) =>
props.isrotating &&
css`
animation: ${spin} 1s linear infinite;
`}
`;

export const XMLDiv = styled(Box)({
display: 'flex',
Expand Down
Loading

0 comments on commit 4ee996f

Please sign in to comment.