diff --git a/src/Components/SearchExpansionPanel/SearchEPCompCurriculum.js b/src/Components/SearchExpansionPanel/SearchEPCompCurriculum.js index 180eaeef90d4ec92d3c6fa367cb0eb22489d3ef9..8d5e231289fe42eb471729934770451a1864f5e8 100644 --- a/src/Components/SearchExpansionPanel/SearchEPCompCurriculum.js +++ b/src/Components/SearchExpansionPanel/SearchEPCompCurriculum.js @@ -19,28 +19,29 @@ const useStyles = makeStyles(theme => ({ export default function SearchEPCompCurriculum(props) { const classes = useStyles(); - const [checked, setChecked] = React.useState([0]); + const [checked, setChecked] = React.useState([]); + const [checkedWithLabel, setCheckedWithLabel] = React.useState([]); - const handleToggle = value => () => { + const handleToggle = (value, label) => () => { const currentIndex = checked.indexOf(value); const newChecked = [...checked]; + const newCheckedWithLabel = [...checkedWithLabel]; if (currentIndex === -1) { newChecked.push(value); + newCheckedWithLabel.push({ + label: label, + value: value, + }); } else { newChecked.splice(currentIndex, 1); + newCheckedWithLabel.splice(currentIndex, 1); } - let filterString = ""; - setChecked(newChecked); - for(let i = 0; i < newChecked.length; i++){ - if(newChecked[i] !== 0){ - filterString = filterString + `&subjects[]=${newChecked[i]}` - console.log(filterString) - } - } - props.onChange("LearningObject", filterString) + setCheckedWithLabel(newCheckedWithLabel) + + props.onChange("curriculum", newCheckedWithLabel) }; const filtrosComponente = [ { exemplo: "Arte", value: "3" }, @@ -81,7 +82,7 @@ export default function SearchEPCompCurriculum(props) { role={undefined} dense button - onClick={handleToggle(item.value)} + onClick={handleToggle(item.value, item.exemplo)} > <ListItemIcon> <Checkbox diff --git a/src/Components/SearchExpansionPanel/SearchEPIdiomas.js b/src/Components/SearchExpansionPanel/SearchEPIdiomas.js index b32f032cbce2efcdb4c5e791582c0a3561683560..94b36f12102457c618aa9f2bf3216b72ebbda72e 100644 --- a/src/Components/SearchExpansionPanel/SearchEPIdiomas.js +++ b/src/Components/SearchExpansionPanel/SearchEPIdiomas.js @@ -19,28 +19,29 @@ const useStyles = makeStyles(theme => ({ export default function SearchEPIdiomas(props) { const classes = useStyles(); - const [checked, setChecked] = React.useState([0]); + const [checked, setChecked] = React.useState([]); + const [checkedWithLabel, setCheckedWithLabel] = React.useState([]); - const handleToggle = value => () => { + const handleToggle = (value, label) => () => { const currentIndex = checked.indexOf(value); const newChecked = [...checked]; + const newCheckedWithLabel = [...checkedWithLabel]; if (currentIndex === -1) { newChecked.push(value); + newCheckedWithLabel.push({ + label: label, + value: value, + }); } else { newChecked.splice(currentIndex, 1); + newCheckedWithLabel.splice(currentIndex, 1); } setChecked(newChecked); - let filterString = ""; - - for(let i = 0; i < newChecked.length; i++){ - if(newChecked[i] !== 0){ - filterString = filterString + `&languages[]=${newChecked[i]}` - console.log(filterString) - } - } - props.onChange("LearningObject", filterString) + setCheckedWithLabel(newCheckedWithLabel) + + props.onChange("languages", newCheckedWithLabel) }; const filtrosIdiomas = [ { value: "5", exemplo: "Alemão" }, @@ -67,7 +68,7 @@ export default function SearchEPIdiomas(props) { role={undefined} dense button - onClick={handleToggle(item.value)} + onClick={handleToggle(item.value, item.exemplo)} > <ListItemIcon> <Checkbox diff --git a/src/Components/SearchExpansionPanel/SearchEPTiposRec.js b/src/Components/SearchExpansionPanel/SearchEPTiposRec.js index 8dc4fcf6782641ca5bee2916a75c75050f6f298c..85c4a0bc9eddc153a1c291628f15832922fe0707 100644 --- a/src/Components/SearchExpansionPanel/SearchEPTiposRec.js +++ b/src/Components/SearchExpansionPanel/SearchEPTiposRec.js @@ -19,28 +19,29 @@ const useStyles = makeStyles(theme => ({ export default function SearchEPTiposRec(props) { const classes = useStyles(); - const [checked, setChecked] = React.useState([0]); + const [checked, setChecked] = React.useState([]); + const [checkedWithLabel, setCheckedWithLabel] = React.useState([]); - const handleToggle = value => () => { + const handleToggle = (value, label) => () => { const currentIndex = checked.indexOf(value); const newChecked = [...checked]; + const newCheckedWithLabel = [...checkedWithLabel]; if (currentIndex === -1) { newChecked.push(value); + newCheckedWithLabel.push({ + label: label, + value: value, + }); } else { newChecked.splice(currentIndex, 1); + newCheckedWithLabel.splice(currentIndex, 1); } - let filterString = ""; - setChecked(newChecked); - for(let i = 0; i < newChecked.length; i++){ - if(newChecked[i] !== 0){ - filterString = filterString + `&object_types[]=${newChecked[i]}` - console.log(filterString) - } - } - props.onChange("LearningObject", filterString) + setCheckedWithLabel(newCheckedWithLabel) + + props.onChange("types", newCheckedWithLabel) }; const filtrosTipos = [ { value: "5", exemplo: "Animação" }, @@ -72,7 +73,7 @@ export default function SearchEPTiposRec(props) { role={undefined} dense button - onClick={handleToggle(item.value)} + onClick={handleToggle(item.value, item.exemplo)} > <ListItemIcon> <Checkbox diff --git a/src/Components/SearchExpansionPanel/SearchExpansionPanel.js b/src/Components/SearchExpansionPanel/SearchExpansionPanel.js index 7ebfc2c9e26e3ddb29e7445fe46f3df6bf090ce7..7d8e07d14d59a843e5e1f79d2bc1ea217fea15ff 100644 --- a/src/Components/SearchExpansionPanel/SearchExpansionPanel.js +++ b/src/Components/SearchExpansionPanel/SearchExpansionPanel.js @@ -12,6 +12,8 @@ import SearchEPIdiomas from "./SearchEPIdiomas"; import { TextField } from "@material-ui/core"; import Grid from '@material-ui/core/Grid'; import CircularProgress from '@material-ui/core/CircularProgress'; +import Paper from '@material-ui/core/Paper'; +import styled from 'styled-components'; import './ExpansionPanel.css' @@ -77,7 +79,6 @@ export default function SearchExpansionPanel(props) { const onKeyPressed = (e) => { if (e.key === "Enter") { - const filterString = "&tags[]=" + keyWords if (keyWords.length === 0) { setErrorInKeyWord({ state: true, @@ -85,7 +86,7 @@ export default function SearchExpansionPanel(props) { }) } else - props.onChange("LearningObject", filterString) + props.onChange("tag", keyWords) } } @@ -99,7 +100,7 @@ export default function SearchExpansionPanel(props) { } return ( - <div> + <MainPaper square elevation={4}> <link href="https://fonts.googleapis.com/css?family=Roboto:400,500&display=swap" rel="stylesheet" @@ -136,7 +137,7 @@ export default function SearchExpansionPanel(props) { </ExpansionPanel> <ExpansionPanel square> - <ExpansionPanelSummary + <ExpansionPanelSummary expandIcon={<ExpandMoreIcon />} aria-controls="panel2d-content" @@ -210,6 +211,18 @@ export default function SearchExpansionPanel(props) { /> </ExpansionPanelDetails> </ExpansionPanel> - </div> + </MainPaper> ); } + +const MainPaper = styled(Paper)` + /* height: 150px; */ + text-align: center; + background-color: #fff; + margin-top: 5px; + margin-bottom: 30px; + color: #666; + .textInfo{ + text-align: start; + } +`; diff --git a/src/Components/SearchExpansionPanel/SesrchEPEtapasEns.js b/src/Components/SearchExpansionPanel/SesrchEPEtapasEns.js index b08fdb680ae4e0e7be65c4c327adf8b34b96b39c..5848efe7b9beaa6c324a038d128d721855789bad 100644 --- a/src/Components/SearchExpansionPanel/SesrchEPEtapasEns.js +++ b/src/Components/SearchExpansionPanel/SesrchEPEtapasEns.js @@ -19,30 +19,29 @@ const useStyles = makeStyles(theme => ({ export default function SearchEPEtapasEns(props) { const classes = useStyles(); - const [checked, setChecked] = React.useState([0]); + const [checked, setChecked] = React.useState([]); + const [checkedWithLabel, setCheckedWithLabel] = React.useState([]); - const handleToggle = value => () => { + const handleToggle = (value, label) => () => { const currentIndex = checked.indexOf(value); const newChecked = [...checked]; + const newCheckedWithLabel = [...checkedWithLabel]; if (currentIndex === -1) { newChecked.push(value); + newCheckedWithLabel.push({ + label: label, + value: value, + }); } else { newChecked.splice(currentIndex, 1); + newCheckedWithLabel.splice(currentIndex, 1); } setChecked(newChecked); - let filterString = ""; + setCheckedWithLabel(newCheckedWithLabel) - for(let i = 0; i < newChecked.length; i++){ - if(newChecked[i] !== 0){ - filterString = filterString + `&educational_stages[]=${newChecked[i]}` - } - } - if(filterString) - props.onChange("LearningObject", filterString) - else - props.onChange("LearningObject", "") + props.onChange("stages", newCheckedWithLabel) }; const filtrosEtapas = [ { value: "1", exemplo: "Educação Infantil" }, @@ -64,7 +63,7 @@ export default function SearchEPEtapasEns(props) { role={undefined} dense button - onClick={handleToggle(item.value)} + onClick={handleToggle(item.value, item.exemplo)} > <ListItemIcon> <Checkbox diff --git a/src/Components/SearchPageComponents/CollectionTemplate.js b/src/Components/SearchPageComponents/CollectionTemplate.js index 5d1b3ffe72fec0bfdbbd36d7057f49a2ddc53325..4b14e6b03166631dfbc9d04076ba80048cd471af 100644 --- a/src/Components/SearchPageComponents/CollectionTemplate.js +++ b/src/Components/SearchPageComponents/CollectionTemplate.js @@ -10,7 +10,7 @@ import ArrowBackIcon from '@material-ui/icons/ArrowBack'; import ArrowForwardIcon from '@material-ui/icons/ArrowForward'; export default function ResourceTemplate({ isLoading, resources, totalResources, currPage, handlePreviousPage, handleNextPage }) { - const totalPages = Math.ceil(totalResources / 12); //Dividing by 12 because i want to cath total pages, and results per page is 12 + const totalPages = Math.ceil(totalResources / 12) - 1; //Dividing by 12 because i want to cath total pages, and results per page is 12 const topRef = React.useRef(); useEffect(() => { @@ -88,6 +88,8 @@ export default function ResourceTemplate({ isLoading, resources, totalResources, }; const Title = styled.h4` + text-transform: uppercase; + font-weight: 500; text-align: left; color: #673ab7; ` diff --git a/src/Components/SearchPageComponents/FilterSummary.js b/src/Components/SearchPageComponents/FilterSummary.js new file mode 100644 index 0000000000000000000000000000000000000000..3b67e58fe83dfe218e6c24882e56ee77198e49ca --- /dev/null +++ b/src/Components/SearchPageComponents/FilterSummary.js @@ -0,0 +1,192 @@ +import React from 'react'; +import styled from 'styled-components'; +import Paper from '@material-ui/core/Paper'; +import Grid from '@material-ui/core/Grid'; +import Chip from '@material-ui/core/Chip'; +import Button from "@material-ui/core/Button"; + +export default function FilterSummary + ({ curriculumComponents, typeOfResources, languages, teachingStage, tag, onButtonClicked }) { + return ( + <FilterSummaryPaper square elevation={4}> + <h3 className="title"> + Resumo dos filtros colocados + </h3> + <Grid container direction='column' spacing={2}> + { + curriculumComponents.length >= 1 ? + <Grid item> + <Grid container direction='row' spacing={1} alignItems='center'> + <Grid item> + Componentes curriculares: + </Grid> + <Grid item> + { + curriculumComponents.map((item) => { + return ( + <StyledChip key={new Date().toISOString() + item.value} size="small" label={item.label} /> + ) + }) + } + </Grid> + </Grid> + </Grid> + : + <Grid item> + <Grid container direction='row' spacing={1} alignItems='center'> + <Grid item> + Componentes curriculares: + </Grid> + <Grid item> + <StyledChip size="small" label="Nenhum selecionado" /> + </Grid> + </Grid> + </Grid> + } + { + typeOfResources.length >= 1 ? + <Grid item> + <Grid container direction='row' spacing={1} alignItems='center'> + <Grid item> + Tipos de recursos: + </Grid> + <Grid item> + { + typeOfResources.map((item) => { + return ( + <StyledChip key={new Date().toISOString() + item.value} size="small" label={item.label} /> + ) + }) + } + </Grid> + </Grid> + </Grid> + : + <Grid item> + <Grid container direction='row' spacing={1} alignItems='center'> + <Grid item> + Tipos de recursos: + </Grid> + <Grid item> + <StyledChip size="small" label="Nenhum selecionado" /> + </Grid> + </Grid> + </Grid> + } + { + teachingStage.length >= 1 ? + <Grid item> + <Grid container direction='row' spacing={1} alignItems='center'> + <Grid item> + Etapas de ensino: + </Grid> + <Grid item> + { + teachingStage.map((item) => { + return ( + <StyledChip key={new Date().toISOString() + item.value} size="small" label={item.label} /> + ) + }) + } + </Grid> + </Grid> + </Grid> + : + <Grid item> + <Grid container direction='row' spacing={1} alignItems='center'> + <Grid item> + Etapas de ensino: + </Grid> + <Grid item> + <StyledChip size="small" label="Nenhum selecionado" /> + </Grid> + </Grid> + </Grid> + } + { + languages.length >= 1 ? + <Grid item> + <Grid container direction='row' spacing={1} alignItems='center'> + <Grid item> + Idiomas: + </Grid> + <Grid item> + { + languages.map((item) => { + return ( + <StyledChip key={new Date().toISOString() + item.value} size="small" label={item.label} /> + ) + }) + } + </Grid> + </Grid> + </Grid> + : + <Grid item> + <Grid container direction='row' spacing={1} alignItems='center'> + <Grid item> + Idiomas: + </Grid> + <Grid item> + <StyledChip size="small" label="Nenhum selecionado" /> + </Grid> + </Grid> + </Grid> + } + { + tag.length >= 1 ? + <Grid item> + <Grid container direction='row' spacing={1} alignItems='center'> + <Grid item> + Palavra chave: + </Grid> + <Grid item> + <StyledChip size="small" label={tag} /> + </Grid> + </Grid> + </Grid> + : + <Grid item> + <Grid container direction='row' spacing={1} alignItems='center'> + <Grid item> + Palavra chave: + </Grid> + <Grid item> + <StyledChip size="small" label="Nenhum selecionado" /> + </Grid> + </Grid> + </Grid> + } + <Grid item> + <StyledButton variant="contained" onClick={onButtonClicked}> + <span className="text"> + Aplicar filtro + </span> + </StyledButton> + </Grid> + </Grid> + </FilterSummaryPaper> + ) +} + +const FilterSummaryPaper = styled(Paper)` + background-color: #fff; + margin-top: 5px; + margin-bottom: 30px; + padding: 0.5em 1em; + .title{ + text-transform: uppercase; + color: #666; + font-weight: 500; + } +` +const StyledButton = styled(Button)` + background-color: #ff7f00 !important; + .text{ + color: white; + } +` + +const StyledChip = styled(Chip)` + margin: 0.2em +` diff --git a/src/Components/SearchPageComponents/ResourceTemplate.js b/src/Components/SearchPageComponents/ResourceTemplate.js index 7a2b6da0b2bb24ceff68d19e2ff14f5bf17b71dd..28651ca064265c08b16c6b5e03c0b3002df84e03 100644 --- a/src/Components/SearchPageComponents/ResourceTemplate.js +++ b/src/Components/SearchPageComponents/ResourceTemplate.js @@ -10,7 +10,7 @@ import ArrowBackIcon from '@material-ui/icons/ArrowBack'; import ArrowForwardIcon from '@material-ui/icons/ArrowForward'; export default function ResourceTemplate({ isLoading, resources, totalResources, currPage, handlePreviousPage, handleNextPage }) { - const totalPages = Math.ceil(totalResources / 12); //Dividing by 12 because i want to cath total pages, and results per page is 12 + const totalPages = Math.ceil(totalResources / 12) - 1; //Dividing by 12 because i want to cath total pages, and results per page is 12 const topRef = React.useRef(); useEffect(() => { @@ -88,6 +88,8 @@ export default function ResourceTemplate({ isLoading, resources, totalResources, }; const Title = styled.h4` + text-transform: uppercase; + font-weight: 500; text-align: left; color: #ff7f00; ` diff --git a/src/Components/SearchPageComponents/UserTemplate.js b/src/Components/SearchPageComponents/UserTemplate.js index c92296f7c20ceaa39ef78ffed4c4ba3d4cd79c84..45ebb66f0bc44cfb63b5b79355edea99feded22a 100644 --- a/src/Components/SearchPageComponents/UserTemplate.js +++ b/src/Components/SearchPageComponents/UserTemplate.js @@ -10,7 +10,7 @@ import ArrowForwardIcon from '@material-ui/icons/ArrowForward'; import { apiDomain } from '../../env'; export default function ResourceTemplate({ isLoading, resources, totalResources, currPage, handlePreviousPage, handleNextPage }) { - const totalPages = Math.ceil(totalResources / 12); //Dividing by 12 because i want to cath total pages, and results per page is 12 + const totalPages = Math.ceil(totalResources / 12) - 1; //Dividing by 12 because i want to cath total pages, and results per page is 12 const topRef = React.useRef(); useEffect(() => { @@ -83,6 +83,8 @@ export default function ResourceTemplate({ isLoading, resources, totalResources, }; const Title = styled.h4` + text-transform: uppercase; + font-weight: 500; text-align: left; color: #00bcd4; ` diff --git a/src/Pages/Search.js b/src/Pages/Search.js index 3e657bf888a1591c53f0f3221ee943841229768f..d58b73a78cd61cc628eb9f0040b5007783772a72 100644 --- a/src/Pages/Search.js +++ b/src/Pages/Search.js @@ -17,7 +17,7 @@ // along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useState, Fragment } from 'react'; import styled from 'styled-components'; import { Link } from 'react-router-dom'; import Breadcrumbs from '@material-ui/core/Breadcrumbs'; @@ -27,6 +27,8 @@ import CollectionTemplate from '../Components/SearchPageComponents/CollectionTem import UserTemplate from '../Components/SearchPageComponents/UserTemplate'; import { getRequest } from '../Components/HelperFunctions/getAxiosConfig'; import { useHistory } from 'react-router-dom'; +import SearchExpansionPanel from '../Components/SearchExpansionPanel/SearchExpansionPanel'; +import FilterSummary from '../Components/SearchPageComponents/FilterSummary'; export default function Search() { const history = useHistory(); @@ -37,6 +39,12 @@ export default function Search() { const [currPage, setCurrPage] = useState(0); const [isLoading, setIsLoading] = useState(false); + const [curriculumComponents, setCurriculumComponents] = useState([]); + const [typeOfResources, setTypeOfResources] = useState([]); + const [teachingStage, setTeachingStage] = useState([]); + const [languages, setLanguages] = useState([]); + const [tag, setTag] = useState(''); + const [resourcesArray, setResourcesArray] = useState([]); const [totalResources, setTotalResources] = useState(0); @@ -60,6 +68,60 @@ export default function Search() { { value: 'Ordem Alfabética', name: 'title' }, ]; + function onButtonClicked() { + const curriculumValues = []; + const typeOfResourcesValues = []; + const teachingStageValues = []; + const languagesValues = []; + const tagsValue = []; + + for (let index = 0; index < curriculumComponents.length; index++) { + const element = curriculumComponents[index]; + curriculumValues.push(element.value); + } + + for (let index = 0; index < typeOfResources.length; index++) { + const element = typeOfResources[index]; + typeOfResourcesValues.push(element.value); + } + + for (let index = 0; index < teachingStage.length; index++) { + const element = teachingStage[index]; + teachingStageValues.push(element.value); + } + + for (let index = 0; index < languages.length; index++) { + const element = languages[index]; + languagesValues.push(element.value); + } + tagsValue.push(tag) + const url = `/busca?page=0&results_per_page=12&order=${currOrder}&query=${currQuery}&search_class=${currOption}&subjects=${curriculumValues}&object_types=${typeOfResourcesValues}&educational_stages=${teachingStageValues}&languages=${languagesValues}&tags=${tagsValue}` + + history.push(url) + } + + function onChangeFilter(type, content) { + switch (type) { + case "curriculum": + setCurriculumComponents(content) + break; + case "languages": + setLanguages(content) + break; + case "stages": + setTeachingStage(content) + break; + case "types": + setTypeOfResources(content) + break; + case "tag": + setTag(content) + break; + default: + break; + } + } + function handleChangeOption(e) { const value = e.target.value; setCurrOption(value); @@ -74,7 +136,17 @@ export default function Search() { } function handleChangeOrder(e) { - serCurrOrder(e.target.value); + const value = e.target.value; + serCurrOrder(value); + + let url; + + if (currOption !== 'User') + url = `/busca?page=0&results_per_page=12&order=${value}&query=${currQuery}&search_class=${currOption}` + else + url = `/busca?page=0&results_per_page=12&query=${currQuery}&search_class=${currOption}` + + history.push(url); } function handleNextPage() { @@ -90,7 +162,6 @@ export default function Search() { } function handleSuccess(data, headers, option) { - console.log(option) if (option === 'LearningObject') { setResourcesArray(data) if (headers.has('X-Total-Count')) { @@ -124,18 +195,36 @@ export default function Search() { const searchClass = urlParams.get("search_class"); const page = parseInt(urlParams.get("page")); const order = urlParams.get("order"); + const subjects = urlParams.get("subjects"); + const objectTypes = urlParams.get("object_types"); + const educationalStages = urlParams.get("educational_stages"); + const languages = urlParams.get("languages"); + const tags = urlParams.get("tags"); + + console.log(subjects) setCurrOption(searchClass); setCurrQuery(query); setCurrPage(page); serCurrOrder(order); - let url - - if (searchClass !== 'User') - url = `/search?page=${page}&results_per_page=12&order=${order}&query=${query}&search_class=${searchClass}` - else - url = `/search?page=${page}&results_per_page=12&query=${query}&search_class=${searchClass}` + let url = `/search?page=${page}&results_per_page=12&query=${query}&search_class=${searchClass}` + + if (searchClass !== 'User') { + url = url + `&order=${order}` + if (searchClass === 'LearningObject') { + if (subjects) + url = url + `&subjects[]=${subjects}` + if (objectTypes) + url = url + `&object_types[]=${objectTypes}` + if (educationalStages) + url = url + `&educational_stages[]=${educationalStages}` + if (languages) + url = url + `&languages[]=${languages}` + if (tags) + url = url + `&tags[]=${tags}` + } + } getRequest( url, @@ -160,14 +249,27 @@ export default function Search() { /> { currOption === 'LearningObject' && - <ResourceTemplate - handleNextPage={handleNextPage} - handlePreviousPage={handlePreviousPage} - isLoading={isLoading} - currPage={currPage} - resources={resourcesArray} - totalResources={totalResources} - /> + <Fragment> + <SearchExpansionPanel onChange={onChangeFilter} /> + { + <FilterSummary + curriculumComponents={curriculumComponents} + typeOfResources={typeOfResources} + languages={languages} + teachingStage={teachingStage} + tag={tag} + onButtonClicked={onButtonClicked} + /> + } + <ResourceTemplate + handleNextPage={handleNextPage} + handlePreviousPage={handlePreviousPage} + isLoading={isLoading} + currPage={currPage} + resources={resourcesArray} + totalResources={totalResources} + /> + </Fragment> } { currOption === 'Collection' && diff --git a/src/env.js b/src/env.js index 7284c42754e5c679138196c2bae2a2f128779c2b..95815e96e0a4b6d934c32704a85f04284e77d16e 100644 --- a/src/env.js +++ b/src/env.js @@ -17,7 +17,7 @@ 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/>.*/ -var apiDomain = 'https://api.portalmectest.c3sl.ufpr.br', +var apiDomain = 'https://api.portalmec.c3sl.ufpr.br', apiVersion = 'v1', apiUrl = apiDomain + '/' + apiVersion;