Skip to content

Commit

Permalink
Merge pull request #31 from fga-eps-mds/feature/29-auditoria-contagem
Browse files Browse the repository at this point in the history
Feature/29 auditoria contagem
  • Loading branch information
DanielViniciusAlves authored Aug 19, 2024
2 parents d8b5ef2 + 0b4946a commit 2042edc
Show file tree
Hide file tree
Showing 24 changed files with 1,038 additions and 95 deletions.
38 changes: 21 additions & 17 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@
const isCoverageEnabled = process.argv.includes('--coverage');

module.exports = {
setupFilesAfterEnv: ['./src/setupTests.js'],
testMatch: ["**/__tests__/**/*.js", "**/?(*.)+(spec|test).js"],
testPathIgnorePatterns: ["/node_modules/"],
transform: {
"^.+\\.(js|jsx)$": "babel-jest",
"^.+\\.svg$": "<rootDir>/fileTransform.js", // Adicione esta linha
"^.+\\.(js|jsx)$": "babel-jest",
"^.+\\.svg$": "<rootDir>/fileTransform.js", // Adicione esta linha
},
moduleFileExtensions: ["js", "json", "jsx", "node"],
moduleNameMapper: {
"^@/(.*)$": "<rootDir>/src/$1",
"\\.(css|less|scss)$": "identity-obj-proxy",
'^axios$': require.resolve('axios'),
"^@/(.*)$": "<rootDir>/src/$1",
"\\.(css|less|scss)$": "identity-obj-proxy",
'^axios$': require.resolve('axios'),
},
testEnvironment: "jsdom",

collectCoverage: isCoverageEnabled,
collectCoverageFrom: isCoverageEnabled ? ['src/**/*.{js,jsx}'] : [],

reporters: [
'default',
[
'jest-sonar',
{
outputDirectory: 'reports',
outputName: 'sonar-report.xml'
}
]
]
};
'default',
[
'jest-sonar',
{
outputDirectory: 'reports',
outputName: 'sonar-report.xml'
}
]
]
};

7 changes: 7 additions & 0 deletions package-lock.json

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

6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"body-parser": "^1.20.2",
"dotenv": "^16.3.1",
"express": "^4.18.2",
"papaparse": "^5.4.1",
"pg": "^8.11.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down Expand Up @@ -60,6 +61,7 @@
"@babel/plugin-proposal-unicode-property-regex": "^7.18.6",
"@babel/preset-env": "^7.23.2",
"@babel/preset-react": "^7.22.15",
"@testing-library/jest-dom": "^6.4.8",
"babel-jest": "^29.7.0",
"eslint": "^8.52.0",
"eslint-plugin-import": "^2.28.1",
Expand All @@ -71,8 +73,8 @@
"jest-sonar": "^0.2.16",
"jest-sonar-reporter": "^2.0.0",
"jsdom": "^22.1.0",
"nodemon": "^2.0.0",
"react-router-dom": "^6.17.0",
"react-test-renderer": "^18.2.0",
"nodemon": "^2.0.0"
"react-test-renderer": "^18.2.0"
}
}
10 changes: 6 additions & 4 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import ContractForm from "./components/forms/ContractForm";
import EditContractForm from "./components/forms/EditContractForm";
import ContractList from "./pages/ContractList";
import ViewContract from "./pages/ViewContract";
import AuditPrinter from "./pages/AuditPrinter";
import AddContador from "./pages/AddContador";

function App() {
Expand All @@ -34,11 +35,12 @@ function App() {
<BrowserRouter>
<Routes>
<Route element={<PrivateRoutes />}>
<Route path="/editarusuario/:id" element={<EditUserPage/>}/>
<Route path="/editimpressora/:id" element={<EditPrinter/>}/>
<Route path="/visualizarimpressora/:id" element={<ViewPrinter/>}/>
<Route path="/editarusuario/:id" element={<EditUserPage />} />
<Route path="/editimpressora/:id" element={<EditPrinter />} />
<Route path="/visualizarimpressora/:id" element={<ViewPrinter />} />
<Route path="/mudarsenha" element={<ChangePassword />} />
<Route path="/cadastroimpressora" element={<RegisterPrinter />} />
<Route path="/auditoria" element={<AuditPrinter />} />
<Route path="/padraoimpressora" element={<PatternPrinter />} />
<Route path="/editarpadrao" element={<EditPattern />} />
<Route path="/impressorascadastradas" element={<ListEquipment />} />
Expand All @@ -59,7 +61,7 @@ function App() {
<Route path="/" element={<Home />} />
<Route path="/contato" element={<Contact />} />
<Route path="/quemsomos" element={<AboutUs />} />
<Route path="/recuperarSenha" element={<RecoverPasswordPage/>} />
<Route path="/recuperarSenha" element={<RecoverPasswordPage />} />
<Route path="/esqueciMinhaSenha" element={<ForgottenPasswordPage />} />
</Routes>
</BrowserRouter>
Expand Down
2 changes: 2 additions & 0 deletions src/__mocks__/fileMock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// src/__mocks__/fileMock.js
module.exports = '';
Binary file added src/assets/report.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 8 additions & 5 deletions src/components/Button.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import '../style/components/button.css';

const Button = ({ type, size, text, onClick, bgColor }) => {
const Button = ({ type, size, text, onClick, bgColor, disabled }) => {
const typeClasses = {
success: 'button-success',
error: 'button-error',
Expand All @@ -15,29 +15,32 @@ const Button = ({ type, size, text, onClick, bgColor }) => {
small: 'button-small',
medium: 'button-medium',
large: 'button-large',
adaptive: 'button-adaptive',
};

const buttonClass = `button ${typeClasses[type] || 'button-info'} ${sizeClasses[size] || 'button-medium'}`;
const buttonClass = `button ${typeClasses[type] || 'button-info'} ${sizeClasses[size] || 'button-medium'} ${disabled ? "disabled" : ' '}`;

return (
<button className={buttonClass} onClick={onClick}
style={ {background: bgColor}}>
<button className={buttonClass} onClick={onClick}
style={{ background: bgColor }}>
{text}
</button>
);
};

Button.propTypes = {
type: PropTypes.oneOf(['success', 'error', 'info', 'warning', 'icon']),
size: PropTypes.oneOf(['small', 'medium', 'large']),
size: PropTypes.oneOf(['small', 'medium', 'large', 'adaptive']),
text: PropTypes.string.isRequired,
bgColor: PropTypes.string.isRequired,
onClick: PropTypes.func.isRequired,
disabled: PropTypes.bool.isRequired,
};

Button.defaultProps = {
type: 'info',
size: 'medium',
disabled: false
};

export default Button;
138 changes: 138 additions & 0 deletions src/components/UploadReport.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import React from 'react';
import PropTypes from 'prop-types';
import '../style/components/UploadReport.css';
import Button from './Button.js';
import { toast } from "react-toastify";
import Papa from 'papaparse';

function UploadReport({ isOpen, onClose, onUpload }) {
if (!isOpen) return null;

const toCamelCase = (str) => {
return str
.toLowerCase()
.replace(/(?:^\w|[A-Z]|\b\w|\s+)/g, (match, index) =>
index === 0 ? match.toLowerCase() : match.toUpperCase()
).replace(/\s+/g, '');
};

const schema = {
actualColorCounter: "number",
actualMonoCounter: "number",
brand: "string",
customerDescription: "string",
endTotalCounter: "number",
lastUpdateTime: "string",
model: "string",
serialnumber: "string",
};

const validateObjectStructure = (obj, schema) => {
for (const key in schema) {
if (!Object.prototype.hasOwnProperty.call(obj, key)) {
console.error(`Erro: Faltando o campo ${key} no objeto.`);
return false;
}
}
return true;
};

const handleFileUpload = (event) => {
const file = event.target.files[0];
if (file) {
if (file.name.split('.').pop() !== 'csv') {
toast.error('Arquivo inválido! Por favor, selecione um arquivo .csv');
return;
}

const reader = new FileReader();
reader.onload = (e) => {
const csvText = e.target.result;

const parsedData = Papa.parse(csvText, {
header: true,
skipEmptyLines: true,
dynamicTyping: true,
});

const cleanedData = parsedData.data.map(item => {
const cleanedItem = {};
Object.keys(item).forEach(key => {
const cleanedKey = toCamelCase(key.replace(/\[|\]/g, '').trim());
cleanedItem[cleanedKey] = item[key];
});

if (validateObjectStructure(cleanedItem, schema)) {
return cleanedItem;
} else {
toast.error('Erro na estrutura dos dados do CSV.');
return null;
}
}).filter(item => item !== null);

onUpload(cleanedData);
};
reader.readAsText(file);
}
};

const handleDownloadTemplate = async () => {
try {
const response = await fetch('https://raw.githubusercontent.com/fga-eps-mds/2024.1-PrintGo-FrontEnd/dev/public/Modelo_Relatorio.csv');
if (!response.ok) throw new Error('Erro ao buscar o arquivo');

const csvContent = await response.text();
console.log(csvContent);
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
const link = document.createElement('a');
const url = URL.createObjectURL(blob);

link.setAttribute('href', url);
link.setAttribute('download', 'Modelo_Relatorio.csv');
link.style.visibility = 'hidden';

document.body.appendChild(link);
link.click();
document.body.removeChild(link);
} catch (error) {
console.error('Erro ao baixar o arquivo:', error);
}
};

return (
<div className="modal-overlay">
<div className="modal-content">
<h2>Upload do Relatório</h2>
<input className='modal-input' type="file" accept=".xls,.xlsx,.xml,.csv" onChange={handleFileUpload} data-testid="upload" />

<div className="modal-info">
<Button
text="Baixar Modelo de Relatório"
onClick={handleDownloadTemplate}
type="success"
/>
<Button
text="Fechar"
onClick={onClose}
type="info"
/>
</div>
</div>
</div>
);
}

UploadReport.defaultProps = {
isOpen: false,
onClose: () => { },
onUpload: () => { }
};

UploadReport.propTypes = {
isOpen: PropTypes.bool.isRequired,
onClose: PropTypes.func.isRequired,
onUpload: PropTypes.func.isRequired
};

export default UploadReport;

54 changes: 54 additions & 0 deletions src/components/containers/AuditBox.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React from "react";
import PropTypes from "prop-types";
import "../../style/components/auditBox.css";
import imageButton from "../../assets/report.png"

const AuditBox = ({ equipamento, contadorCor, contadorPB, contadorLocPB, contadorLocCor, totPrintgo, totLoc, onClick, marginError }) => {
let errorClass = "";
if (Math.abs(contadorCor - contadorLocCor) > marginError || Math.abs(contadorPB - contadorLocPB) > marginError || Math.abs(totPrintgo - totLoc) > marginError) {
errorClass = "box-error";
}

return (
<div className={`box ${errorClass}`}>
<h2 className="audit-box-element">{equipamento}</h2>
<h2 className="audit-box-element">{contadorCor}</h2>
<h2 className="audit-box-element">{contadorPB}</h2>
<h2 className="audit-box-element">{contadorLocCor}</h2>
<h2 className="audit-box-element">{contadorLocPB}</h2>
<h2 className="audit-box-element">{totPrintgo}</h2>
<h2 className="audit-box-element">{totLoc}</h2>
<div className="audit-box-element-report">
<button className="report" onClick={onClick} data-testid="report-image" >
<img src={imageButton} alt="Button" className="report-image" />
</button>
</div>
</div>

);
};

AuditBox.propTypes = {
equipamento: PropTypes.string,
contadorCor: PropTypes.number,
contadorPB: PropTypes.number,
contadorLocPB: PropTypes.number,
contadorLocCor: PropTypes.number,
totPrintgo: PropTypes.number,
totLoc: PropTypes.number,
ativo: PropTypes.bool,
onClick: PropTypes.func,
marginError: PropTypes.number,
};

AuditBox.defaultProps = {
contadorCor: 0,
contadorPB: 0,
contadorLocPB: 0,
contadorLocCor: 0,
totPrintgo: 0,
totLoc: 0,
marginError: 0,
};

export default AuditBox;
1 change: 1 addition & 0 deletions src/components/containers/NumberContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const NumberContainer = ({ id, name, value, onChange, className, label, disabled
onChange={onChange}
disabled={disabled}
placeholder="Insira"
min="0"
/>
</div>
</div>
Expand Down
Loading

0 comments on commit 2042edc

Please sign in to comment.