feat(frontend): alinhar critérios e selos/hints
This commit is contained in:
@@ -9,6 +9,8 @@ function App() {
|
|||||||
const [consultores, setConsultores] = useState([]);
|
const [consultores, setConsultores] = useState([]);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [error, setError] = useState(null);
|
const [error, setError] = useState(null);
|
||||||
|
const [processing, setProcessing] = useState(false);
|
||||||
|
const [processMessage, setProcessMessage] = useState('');
|
||||||
const [total, setTotal] = useState(0);
|
const [total, setTotal] = useState(0);
|
||||||
const [page, setPage] = useState(1);
|
const [page, setPage] = useState(1);
|
||||||
const [pageSize, setPageSize] = useState(50);
|
const [pageSize, setPageSize] = useState(50);
|
||||||
@@ -45,12 +47,44 @@ function App() {
|
|||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setError(null);
|
setError(null);
|
||||||
|
setProcessMessage('');
|
||||||
const response = await rankingService.getRanking(page, pageSize);
|
const response = await rankingService.getRanking(page, pageSize);
|
||||||
setConsultores(response.consultores);
|
setConsultores(response.consultores);
|
||||||
setTotal(response.total);
|
setTotal(response.total);
|
||||||
setTotalPages(response.total_pages || 0);
|
setTotalPages(response.total_pages || 0);
|
||||||
setPage(response.page || page);
|
setPage(response.page || page);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
const status = err?.response?.status;
|
||||||
|
if (status === 503) {
|
||||||
|
try {
|
||||||
|
setProcessing(true);
|
||||||
|
setProcessMessage('Ranking ainda não processado. Iniciando processamento...');
|
||||||
|
await rankingService.processarRanking(true);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
const st = await rankingService.getStatus();
|
||||||
|
setProcessMessage(st.mensagem || `Processando... ${st.progress || 0}%`);
|
||||||
|
if (!st.running) {
|
||||||
|
if (st.erro) throw new Error(st.erro);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
await new Promise((r) => setTimeout(r, 4000));
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await rankingService.getRanking(page, pageSize);
|
||||||
|
setConsultores(response.consultores);
|
||||||
|
setTotal(response.total);
|
||||||
|
setTotalPages(response.total_pages || 0);
|
||||||
|
setPage(response.page || page);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Erro ao processar ranking:', e);
|
||||||
|
setError('Erro ao processar ranking. Verifique a conexão com o Elasticsearch.');
|
||||||
|
} finally {
|
||||||
|
setProcessing(false);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
console.error('Erro ao carregar ranking:', err);
|
console.error('Erro ao carregar ranking:', err);
|
||||||
setError('Erro ao carregar ranking. Verifique se a API está rodando.');
|
setError('Erro ao carregar ranking. Verifique se a API está rodando.');
|
||||||
} finally {
|
} finally {
|
||||||
@@ -88,7 +122,9 @@ function App() {
|
|||||||
if (loading) {
|
if (loading) {
|
||||||
return (
|
return (
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<div className="loading">Carregando ranking...</div>
|
<div className="loading">
|
||||||
|
{processing ? (processMessage || 'Processando ranking...') : 'Carregando ranking...'}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ import React, { useState, useRef, useEffect } from 'react';
|
|||||||
import './ConsultorCard.css';
|
import './ConsultorCard.css';
|
||||||
|
|
||||||
const SELOS = {
|
const SELOS = {
|
||||||
COORD_PPG: { label: 'Coord. PPG', cor: 'selo-coord', icone: '🎓' },
|
PRESID_CAMARA: { label: 'Presidente Câmara Temática', cor: 'selo-camara', icone: '🏛️' },
|
||||||
PRESID_CAMARA: { label: 'Presid. Câmara', cor: 'selo-camara', icone: '🏛️' },
|
COORD_PPG: { label: 'Coordenador de PPG', cor: 'selo-coord', icone: '🎓' },
|
||||||
BPQ: { label: 'Bolsista PQ', cor: 'selo-bpq', icone: '🔬' },
|
BPQ: { label: 'BPQ', cor: 'selo-bpq', icone: '🔬' },
|
||||||
GRANDE_PREMIO: { label: 'Grande Prêmio', cor: 'selo-gp', icone: '🏆' },
|
AUTOR_GP: { label: 'Autor - Grande Prêmio', cor: 'selo-gp', icone: '🏆' },
|
||||||
PREMIO: { label: 'Prêmio', cor: 'selo-premio', icone: '🥇' },
|
AUTOR_PREMIO: { label: 'Autor - Prêmio', cor: 'selo-premio', icone: '🥇' },
|
||||||
MENCAO: { label: 'Menção Honrosa', cor: 'selo-mencao', icone: '🎖️' },
|
AUTOR_MENCAO: { label: 'Autor - Menção Honrosa', cor: 'selo-mencao', icone: '🎖️' },
|
||||||
ORIENT_POS_DOC: { label: 'Orient. Pós-Doc', cor: 'selo-orient', icone: '📚' },
|
ORIENT_POS_DOC: { label: 'Orient. Pós-Doc', cor: 'selo-orient', icone: '📚' },
|
||||||
ORIENT_POS_DOC_PREM: { label: 'Orient. Pós-Doc Premiada', cor: 'selo-orient-prem', icone: '📚🏆' },
|
ORIENT_POS_DOC_PREM: { label: 'Orient. Pós-Doc Premiada', cor: 'selo-orient-prem', icone: '📚🏆' },
|
||||||
ORIENT_TESE: { label: 'Orient. Tese', cor: 'selo-orient', icone: '📖' },
|
ORIENT_TESE: { label: 'Orient. Tese', cor: 'selo-orient', icone: '📖' },
|
||||||
@@ -25,42 +25,86 @@ const SELOS = {
|
|||||||
const gerarSelos = (consultor) => {
|
const gerarSelos = (consultor) => {
|
||||||
const selos = [];
|
const selos = [];
|
||||||
|
|
||||||
if (consultor.coordenacoes_capes?.some(c => c.codigo === 'CAM' && c.presidente)) {
|
const isPresidCamaraVigente = consultor.coordenacoes_capes?.some(
|
||||||
selos.push({ ...SELOS.PRESID_CAMARA, qtd: 1 });
|
(c) => c.codigo === 'CAM' && c.presidente && (c.ativo ?? !c.fim)
|
||||||
|
);
|
||||||
|
if (isPresidCamaraVigente) {
|
||||||
|
selos.push({ ...SELOS.PRESID_CAMARA, qtd: 1, hint: 'Presidente Câmara Temática: mandato vigente como presidente.' });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (consultor.coordenador_ppg) {
|
if (consultor.coordenador_ppg) {
|
||||||
selos.push({ ...SELOS.COORD_PPG, qtd: 1 });
|
selos.push({ ...SELOS.COORD_PPG, qtd: 1, hint: 'Coordenador de PPG: possui perfil/atuação de coordenação de programa no ATUACAPES.' });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (consultor.bolsas_cnpq?.length > 0) {
|
const bolsas = Array.isArray(consultor.bolsas_cnpq) ? consultor.bolsas_cnpq : [];
|
||||||
selos.push({ ...SELOS.BPQ, qtd: consultor.bolsas_cnpq.length });
|
if (bolsas.length > 0) {
|
||||||
|
const porNivel = {};
|
||||||
|
for (const b of bolsas) {
|
||||||
|
const nivel = (b.nivel || 'N/A').toString().trim();
|
||||||
|
porNivel[nivel] = (porNivel[nivel] || 0) + 1;
|
||||||
|
}
|
||||||
|
const niveis = Object.keys(porNivel);
|
||||||
|
const label = niveis.length === 1 ? `BPQ ${niveis[0]}` : 'BPQ';
|
||||||
|
const breakdown = niveis
|
||||||
|
.sort()
|
||||||
|
.map((n) => `${n}=${porNivel[n]}`)
|
||||||
|
.join(' | ');
|
||||||
|
selos.push({ ...SELOS.BPQ, label, qtd: bolsas.length, hint: `BPQ NIVEL: ${breakdown}` });
|
||||||
}
|
}
|
||||||
|
|
||||||
const gp = consultor.premiacoes?.filter(p => p.codigo === 'PREMIACAO')?.length || 0;
|
const premiacoes = Array.isArray(consultor.premiacoes) ? consultor.premiacoes : [];
|
||||||
const premio = consultor.premiacoes?.filter(p => p.codigo === 'PREMIACAO_GP')?.length || 0;
|
const premiacoesAutor = premiacoes.filter((p) => (p.papel || '').toString().toLowerCase() === 'autor');
|
||||||
const mencao = consultor.premiacoes?.filter(p => p.codigo === 'MENCAO')?.length || 0;
|
const autorGp = premiacoesAutor.filter((p) => p.codigo === 'PREMIACAO').length;
|
||||||
|
const autorPremio = premiacoesAutor.filter((p) => p.codigo === 'PREMIACAO_GP').length;
|
||||||
|
const autorMencao = premiacoesAutor.filter((p) => p.codigo === 'MENCAO').length;
|
||||||
|
|
||||||
if (gp > 0) selos.push({ ...SELOS.GRANDE_PREMIO, qtd: gp });
|
if (autorGp > 0) selos.push({ ...SELOS.AUTOR_GP, qtd: autorGp, hint: `Autor - Grande Prêmio: ${autorGp} ocorrência(s).` });
|
||||||
if (premio > 0) selos.push({ ...SELOS.PREMIO, qtd: premio });
|
if (autorPremio > 0) selos.push({ ...SELOS.AUTOR_PREMIO, qtd: autorPremio, hint: `Autor - Prêmio: ${autorPremio} ocorrência(s).` });
|
||||||
if (mencao > 0) selos.push({ ...SELOS.MENCAO, qtd: mencao });
|
if (autorMencao > 0) selos.push({ ...SELOS.AUTOR_MENCAO, qtd: autorMencao, hint: `Autor - Menção Honrosa: ${autorMencao} ocorrência(s).` });
|
||||||
|
|
||||||
const orientPosDoc = consultor.orientacoes?.filter(o => o.codigo === 'ORIENT_POS_DOC')?.length || 0;
|
const orientacoes = Array.isArray(consultor.orientacoes) ? consultor.orientacoes : [];
|
||||||
const orientTese = consultor.orientacoes?.filter(o => o.codigo === 'ORIENT_TESE')?.length || 0;
|
const contarPremiadas = (lista) => {
|
||||||
const orientDiss = consultor.orientacoes?.filter(o => o.codigo === 'ORIENT_DISS')?.length || 0;
|
const acc = { GP: 0, PREMIO: 0, MENCAO: 0 };
|
||||||
|
for (const o of lista) {
|
||||||
|
if (!o?.premiada) continue;
|
||||||
|
const t = (o.premiacao_tipo || '').toString().toUpperCase();
|
||||||
|
if (t.includes('GP')) acc.GP += 1;
|
||||||
|
else if (t.includes('MENCAO')) acc.MENCAO += 1;
|
||||||
|
else acc.PREMIO += 1;
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
};
|
||||||
|
const hintPremiadas = (labelBase, counts) =>
|
||||||
|
`${labelBase} (GP / Prêmio / Menção): GP=${counts.GP} | Prêmio=${counts.PREMIO} | Menção=${counts.MENCAO}`;
|
||||||
|
|
||||||
const orientPosDocPrem = consultor.orientacoes?.filter(o => o.codigo === 'ORIENT_POS_DOC' && o.premiada)?.length || 0;
|
const selosOrientacao = (codigo, seloNormal, seloPrem) => {
|
||||||
const orientTesePrem = consultor.orientacoes?.filter(o => o.codigo === 'ORIENT_TESE' && o.premiada)?.length || 0;
|
const base = orientacoes.filter((o) => o.codigo === codigo && !o.coorientacao);
|
||||||
const orientDissPrem = consultor.orientacoes?.filter(o => o.codigo === 'ORIENT_DISS' && o.premiada)?.length || 0;
|
const prem = base.filter((o) => o.premiada);
|
||||||
|
const naoPrem = base.filter((o) => !o.premiada);
|
||||||
|
if (prem.length > 0) {
|
||||||
|
selos.push({ ...seloPrem, qtd: prem.length, hint: hintPremiadas(seloPrem.label, contarPremiadas(prem)) });
|
||||||
|
} else if (naoPrem.length > 0) {
|
||||||
|
selos.push({ ...seloNormal, qtd: naoPrem.length, hint: `${seloNormal.label}: ${naoPrem.length} ocorrência(s).` });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (orientPosDocPrem > 0) selos.push({ ...SELOS.ORIENT_POS_DOC_PREM, qtd: orientPosDocPrem });
|
const selosCoorientacao = (codigo, seloNormal, seloPrem) => {
|
||||||
else if (orientPosDoc > 0) selos.push({ ...SELOS.ORIENT_POS_DOC, qtd: orientPosDoc });
|
const base = orientacoes.filter((o) => o.codigo === codigo && o.coorientacao);
|
||||||
|
const prem = base.filter((o) => o.premiada);
|
||||||
|
const naoPrem = base.filter((o) => !o.premiada);
|
||||||
|
if (prem.length > 0) {
|
||||||
|
selos.push({ ...seloPrem, qtd: prem.length, hint: hintPremiadas(seloPrem.label, contarPremiadas(prem)) });
|
||||||
|
} else if (naoPrem.length > 0) {
|
||||||
|
selos.push({ ...seloNormal, qtd: naoPrem.length, hint: `${seloNormal.label}: ${naoPrem.length} ocorrência(s).` });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (orientTesePrem > 0) selos.push({ ...SELOS.ORIENT_TESE_PREM, qtd: orientTesePrem });
|
selosOrientacao('ORIENT_POS_DOC', SELOS.ORIENT_POS_DOC, SELOS.ORIENT_POS_DOC_PREM);
|
||||||
else if (orientTese > 0) selos.push({ ...SELOS.ORIENT_TESE, qtd: orientTese });
|
selosOrientacao('ORIENT_TESE', SELOS.ORIENT_TESE, SELOS.ORIENT_TESE_PREM);
|
||||||
|
selosOrientacao('ORIENT_DISS', SELOS.ORIENT_DISS, SELOS.ORIENT_DISS_PREM);
|
||||||
if (orientDissPrem > 0) selos.push({ ...SELOS.ORIENT_DISS_PREM, qtd: orientDissPrem });
|
selosCoorientacao('CO_ORIENT_POS_DOC', SELOS.CO_ORIENT_POS_DOC, SELOS.CO_ORIENT_POS_DOC_PREM);
|
||||||
else if (orientDiss > 0) selos.push({ ...SELOS.ORIENT_DISS, qtd: orientDiss });
|
selosCoorientacao('CO_ORIENT_TESE', SELOS.CO_ORIENT_TESE, SELOS.CO_ORIENT_TESE_PREM);
|
||||||
|
selosCoorientacao('CO_ORIENT_DISS', SELOS.CO_ORIENT_DISS, SELOS.CO_ORIENT_DISS_PREM);
|
||||||
|
|
||||||
return selos;
|
return selos;
|
||||||
};
|
};
|
||||||
@@ -77,7 +121,7 @@ const SelosBadges = ({ selos, compacto = false }) => {
|
|||||||
<span
|
<span
|
||||||
key={idx}
|
key={idx}
|
||||||
className={`selo ${selo.cor}`}
|
className={`selo ${selo.cor}`}
|
||||||
title={`${selo.label}${selo.qtd > 1 ? ` (${selo.qtd}x)` : ''}`}
|
title={selo.hint || `${selo.label}${selo.qtd > 1 ? ` (${selo.qtd}x)` : ''}`}
|
||||||
>
|
>
|
||||||
<span className="selo-icone">{selo.icone}</span>
|
<span className="selo-icone">{selo.icone}</span>
|
||||||
{!compacto && <span className="selo-label">{selo.label}</span>}
|
{!compacto && <span className="selo-label">{selo.label}</span>}
|
||||||
@@ -94,19 +138,19 @@ const SelosBadges = ({ selos, compacto = false }) => {
|
|||||||
const FORMULAS = {
|
const FORMULAS = {
|
||||||
bloco_a: {
|
bloco_a: {
|
||||||
titulo: 'Coordenacao CAPES',
|
titulo: 'Coordenacao CAPES',
|
||||||
descricao: 'CA=200 | CAJ=150 | CAJ_MP=120 | CAM=100\nTempo: multiplicador por ano\nBonus atualidade + Retorno (V2)',
|
descricao: 'CA=200 | CAJ=150 | CAJ_MP=120 | CAM=100\nTempo: multiplicador por ano (anos completos)\nBônus atualidade (mandato vigente) + Retorno (mandato anterior)',
|
||||||
},
|
},
|
||||||
bloco_b: {
|
bloco_b: {
|
||||||
titulo: 'Coordenacao PPG',
|
titulo: 'Coordenacao PPG',
|
||||||
descricao: 'Base=70 | Tempo=5 pts/ano (max 50)\nExtras por programas distintos (max 40)\nBonus por maior nota do programa (max 20)',
|
descricao: 'Reservado no V1: PPG_COORD base=0 | teto=0 (dados incompletos no ATUACAPES para pontuar).',
|
||||||
},
|
},
|
||||||
bloco_c: {
|
bloco_c: {
|
||||||
titulo: 'Consultoria',
|
titulo: 'Consultoria',
|
||||||
descricao: 'CONS_ATIVO=150 | CONS_HIST=100 | CONS_FALECIDO=100\nTempo: 5 pts/ano (max 50)\nContinuidade 8a+=20 | Retorno=15 (V2)',
|
descricao: 'CONS_ATIVO=150 | CONS_HIST=100 | CONS_FALECIDO=100\nTempo: 5 pts/ano (max 50)\nContinuidade (escalonado): 3a=+5 | 5a=+10 | 8a+=+15\nRetorno (reativação): +15 (uma vez)',
|
||||||
},
|
},
|
||||||
bloco_d: {
|
bloco_d: {
|
||||||
titulo: 'Premiacoes/Avaliacoes',
|
titulo: 'Premiacoes/Avaliacoes',
|
||||||
descricao: 'GP=100 | Premio=50 | Mencao=30\nAVAL_COMIS=30-50 | COORD_COMIS=50-60\nINSC_AUTOR=10 | INSC_INST=30 (V2)',
|
descricao: 'Premiações: GP=150 (teto 180) | Prêmio=30 (teto 60) | Menção=10 (teto 20)\nBolsas: BPQ_SUP=30 (teto 60) | BPQ_INT=50 (teto 100)\nInscrições/Avaliações/Comissões/Participações/Orientações/Bancas (com tetos por código)',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -116,8 +160,9 @@ const PONTOS_BASE = {
|
|||||||
INSC_AUTOR: 10, INSC_INST: 30,
|
INSC_AUTOR: 10, INSC_INST: 30,
|
||||||
AVAL_COMIS_PREMIO: 30, AVAL_COMIS_GP: 50,
|
AVAL_COMIS_PREMIO: 30, AVAL_COMIS_GP: 50,
|
||||||
COORD_COMIS_PREMIO: 50, COORD_COMIS_GP: 60,
|
COORD_COMIS_PREMIO: 50, COORD_COMIS_GP: 60,
|
||||||
PREMIACAO: 100, PREMIACAO_GP: 50, MENCAO: 30,
|
PREMIACAO: 150, PREMIACAO_GP: 30, MENCAO: 10,
|
||||||
BOL_BPQ_SUPERIOR: 30, BOL_BPQ_INTERMEDIARIO: 30,
|
BOL_BPQ_SUP: 30, BOL_BPQ_INT: 50,
|
||||||
|
BOL_BPQ_SUPERIOR: 30, BOL_BPQ_INTERMEDIARIO: 50,
|
||||||
EVENTO: 1, PROJ: 10,
|
EVENTO: 1, PROJ: 10,
|
||||||
ORIENT_POS_DOC: 15, ORIENT_TESE: 10, ORIENT_DISS: 5,
|
ORIENT_POS_DOC: 15, ORIENT_TESE: 10, ORIENT_DISS: 5,
|
||||||
CO_ORIENT_POS_DOC: 7, CO_ORIENT_TESE: 5, CO_ORIENT_DISS: 3,
|
CO_ORIENT_POS_DOC: 7, CO_ORIENT_TESE: 5, CO_ORIENT_DISS: 3,
|
||||||
@@ -128,25 +173,27 @@ const TETOS = {
|
|||||||
INSC_AUTOR: { teto: 20, doc: '3.3 Inscrições' },
|
INSC_AUTOR: { teto: 20, doc: '3.3 Inscrições' },
|
||||||
INSC_INST: { teto: 60, doc: '3.3 Inscrições' },
|
INSC_INST: { teto: 60, doc: '3.3 Inscrições' },
|
||||||
AVAL_COMIS_PREMIO: { teto: 60, doc: '3.4 Avaliação/Comissão', bonus: '+2/ano (max 15)' },
|
AVAL_COMIS_PREMIO: { teto: 60, doc: '3.4 Avaliação/Comissão', bonus: '+2/ano (max 15)' },
|
||||||
AVAL_COMIS_GP: { teto: 80, doc: '3.4 Avaliação/Comissão', bonus: '+3/ano (max 20)' },
|
AVAL_COMIS_GP: { teto: 100, doc: '3.4 Avaliação/Comissão', bonus: '+3/ano (max 20)' },
|
||||||
COORD_COMIS_PREMIO: { teto: 100, doc: '3.4 Avaliação/Comissão', bonus: '+4/ano (max 20)' },
|
COORD_COMIS_PREMIO: { teto: 100, doc: '3.4 Avaliação/Comissão', bonus: '+4/ano (max 20)' },
|
||||||
COORD_COMIS_GP: { teto: 120, doc: '3.4 Avaliação/Comissão', bonus: '+6/ano (max 20)' },
|
COORD_COMIS_GP: { teto: 120, doc: '3.4 Avaliação/Comissão', bonus: '+6/ano (max 20)' },
|
||||||
PREMIACAO: { teto: 180, doc: '3.6 Grande Prêmio' },
|
PREMIACAO: { teto: 180, doc: '3.4 Premiações e Bolsas' },
|
||||||
PREMIACAO_GP: { teto: 60, doc: '3.6 Prêmio' },
|
PREMIACAO_GP: { teto: 60, doc: '3.4 Premiações e Bolsas' },
|
||||||
MENCAO: { teto: 20, doc: '3.6 Menção Honrosa' },
|
MENCAO: { teto: 20, doc: '3.4 Premiações e Bolsas' },
|
||||||
EVENTO: { teto: 5, doc: '3.7 Participações' },
|
EVENTO: { teto: 5, doc: '3.5 Participações Acadêmicas' },
|
||||||
PROJ: { teto: 40, doc: '3.7 Participações' },
|
PROJ: { teto: 40, doc: '3.5 Participações Acadêmicas' },
|
||||||
BOL_BPQ_SUPERIOR: { teto: 60, doc: '3.5 Bolsas CNPQ' },
|
BOL_BPQ_SUP: { teto: 60, doc: '3.4 Premiações e Bolsas' },
|
||||||
BOL_BPQ_INTERMEDIARIO: { teto: 60, doc: '3.5 Bolsas CNPQ' },
|
BOL_BPQ_INT: { teto: 100, doc: '3.4 Premiações e Bolsas' },
|
||||||
ORIENT_POS_DOC: { teto: 0, doc: '3.8 Orientação (sem limite)' },
|
BOL_BPQ_SUPERIOR: { teto: 60, doc: '3.4 Premiações e Bolsas' },
|
||||||
ORIENT_TESE: { teto: 0, doc: '3.8 Orientação (sem limite)' },
|
BOL_BPQ_INTERMEDIARIO: { teto: 100, doc: '3.4 Premiações e Bolsas' },
|
||||||
ORIENT_DISS: { teto: 0, doc: '3.8 Orientação (sem limite)' },
|
ORIENT_POS_DOC: { teto: 100, doc: '3.5 Participações Acadêmicas' },
|
||||||
CO_ORIENT_POS_DOC: { teto: 0, doc: '3.9 Co-Orientação (sem limite)' },
|
ORIENT_TESE: { teto: 50, doc: '3.5 Participações Acadêmicas' },
|
||||||
CO_ORIENT_TESE: { teto: 0, doc: '3.9 Co-Orientação (sem limite)' },
|
ORIENT_DISS: { teto: 25, doc: '3.5 Participações Acadêmicas' },
|
||||||
CO_ORIENT_DISS: { teto: 0, doc: '3.9 Co-Orientação (sem limite)' },
|
CO_ORIENT_POS_DOC: { teto: 35, doc: '3.5 Participações Acadêmicas' },
|
||||||
MB_BANCA_POS_DOC: { teto: 0, doc: '3.10 Banca (sem limite)' },
|
CO_ORIENT_TESE: { teto: 25, doc: '3.5 Participações Acadêmicas' },
|
||||||
MB_BANCA_TESE: { teto: 0, doc: '3.10 Banca (sem limite)' },
|
CO_ORIENT_DISS: { teto: 15, doc: '3.5 Participações Acadêmicas' },
|
||||||
MB_BANCA_DISS: { teto: 0, doc: '3.10 Banca (sem limite)' },
|
MB_BANCA_POS_DOC: { teto: 15, doc: '3.5 Participações Acadêmicas' },
|
||||||
|
MB_BANCA_TESE: { teto: 15, doc: '3.5 Participações Acadêmicas' },
|
||||||
|
MB_BANCA_DISS: { teto: 10, doc: '3.5 Participações Acadêmicas' },
|
||||||
};
|
};
|
||||||
|
|
||||||
const ScoreItemWithTooltip = ({ value, label, formula, style }) => (
|
const ScoreItemWithTooltip = ({ value, label, formula, style }) => (
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ const Header = ({ total }) => {
|
|||||||
<tr><td>CA</td><td>200</td><td>10/ano (max 100)</td><td>30</td></tr>
|
<tr><td>CA</td><td>200</td><td>10/ano (max 100)</td><td>30</td></tr>
|
||||||
<tr><td>CAJ</td><td>150</td><td>8/ano (max 80)</td><td>20</td></tr>
|
<tr><td>CAJ</td><td>150</td><td>8/ano (max 80)</td><td>20</td></tr>
|
||||||
<tr><td>CAJ_MP</td><td>120</td><td>6/ano (max 60)</td><td>15</td></tr>
|
<tr><td>CAJ_MP</td><td>120</td><td>6/ano (max 60)</td><td>15</td></tr>
|
||||||
<tr><td>CAM</td><td>100</td><td>5/ano (max 50)</td><td>10</td></tr>
|
<tr><td>CAM</td><td>100</td><td>5/ano (max 50)</td><td>20</td></tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div className="criteria-note">+ Retorno (20)</div>
|
<div className="criteria-note">+ Retorno (20)</div>
|
||||||
@@ -53,6 +53,8 @@ const Header = ({ total }) => {
|
|||||||
<tr><td>CONS_HIST</td><td className="pts-value">100 pts</td></tr>
|
<tr><td>CONS_HIST</td><td className="pts-value">100 pts</td></tr>
|
||||||
<tr><td>CONS_FALECIDO</td><td className="pts-value">100 pts</td></tr>
|
<tr><td>CONS_FALECIDO</td><td className="pts-value">100 pts</td></tr>
|
||||||
<tr><td>Tempo</td><td className="pts-value">5 pts/ano (max 50)</td></tr>
|
<tr><td>Tempo</td><td className="pts-value">5 pts/ano (max 50)</td></tr>
|
||||||
|
<tr><td>Continuidade 3a</td><td className="pts-value">+5 pts</td></tr>
|
||||||
|
<tr><td>Continuidade 5a</td><td className="pts-value">+10 pts</td></tr>
|
||||||
<tr><td>Continuidade 8a+</td><td className="pts-value">+15 pts</td></tr>
|
<tr><td>Continuidade 8a+</td><td className="pts-value">+15 pts</td></tr>
|
||||||
<tr><td>Retorno</td><td className="pts-value">+15 pts</td></tr>
|
<tr><td>Retorno</td><td className="pts-value">+15 pts</td></tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
@@ -67,9 +69,9 @@ const Header = ({ total }) => {
|
|||||||
<tr><td>PREMIACAO (GP)</td><td className="pts-value">150 pts (max 180)</td></tr>
|
<tr><td>PREMIACAO (GP)</td><td className="pts-value">150 pts (max 180)</td></tr>
|
||||||
<tr><td>PREMIACAO_GP</td><td className="pts-value">30 pts (max 60)</td></tr>
|
<tr><td>PREMIACAO_GP</td><td className="pts-value">30 pts (max 60)</td></tr>
|
||||||
<tr><td>MENCAO</td><td className="pts-value">10 pts (max 20)</td></tr>
|
<tr><td>MENCAO</td><td className="pts-value">10 pts (max 20)</td></tr>
|
||||||
<tr><td>COORD_COMIS_GP</td><td className="pts-value">60 pts (max 120)</td></tr>
|
|
||||||
<tr><td>AVAL_COMIS_GP</td><td className="pts-value">50 pts (max 100)</td></tr>
|
|
||||||
<tr><td>INSC_INST</td><td className="pts-value">30 pts (max 60)</td></tr>
|
<tr><td>INSC_INST</td><td className="pts-value">30 pts (max 60)</td></tr>
|
||||||
|
<tr><td>AVAL_COMIS_GP</td><td className="pts-value">50 pts (max 100)</td></tr>
|
||||||
|
<tr><td>COORD_COMIS_GP</td><td className="pts-value">60 pts (max 120)</td></tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ export const rankingService = {
|
|||||||
ativo: c.ativo,
|
ativo: c.ativo,
|
||||||
anos_atuacao: anos,
|
anos_atuacao: anos,
|
||||||
veterano: anos >= 10,
|
veterano: anos >= 10,
|
||||||
|
coordenador_ppg: Boolean(c.coordenador_ppg),
|
||||||
pontuacao: c.pontuacao || {
|
pontuacao: c.pontuacao || {
|
||||||
pontuacao_total: c.pontuacao_total,
|
pontuacao_total: c.pontuacao_total,
|
||||||
bloco_a: { total: c.bloco_a, atuacoes: [] },
|
bloco_a: { total: c.bloco_a, atuacoes: [] },
|
||||||
@@ -100,6 +101,16 @@ export const rankingService = {
|
|||||||
const response = await api.get('/ranking/busca', { params: { nome, limit } });
|
const response = await api.get('/ranking/busca', { params: { nome, limit } });
|
||||||
return response.data;
|
return response.data;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async processarRanking(limpar_antes = true) {
|
||||||
|
const response = await api.post('/ranking/processar', { limpar_antes });
|
||||||
|
return response.data;
|
||||||
|
},
|
||||||
|
|
||||||
|
async getStatus() {
|
||||||
|
const response = await api.get('/ranking/status');
|
||||||
|
return response.data;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default api;
|
export default api;
|
||||||
|
|||||||
Reference in New Issue
Block a user