feat: extrair docencias PPG e simplificar blocos de pontuacao
Backend: - Adicionar entidade DocenciaPPG para dados de docencia - Extrair docencias do Elasticsearch (tipo "Docência") - Serializar docencias no JSON de detalhes do consultor - Aumentar batch size de 500 para 2000 para melhor performance Frontend: - Remover Bloco B (Coord. PPG) - reservado para V2 - Simplificar formula para: Bloco A + Bloco C + Bloco D - Filtrar orientacoes/bancas da listagem (sao apenas selos) - Atualizar Header com nota que PPG_COORD e apenas indicador - Exibir pontuacao base nos modais de orientacao/banca
This commit is contained in:
@@ -107,15 +107,13 @@ const CompararModal = ({ consultor1, consultor2, onClose }) => {
|
||||
|
||||
const blocoA1 = p1.bloco_a || { total: consultor1.bloco_a || 0 };
|
||||
const blocoA2 = p2.bloco_a || { total: consultor2.bloco_a || 0 };
|
||||
const blocoB1 = p1.bloco_b || { total: consultor1.bloco_b || 0 };
|
||||
const blocoB2 = p2.bloco_b || { total: consultor2.bloco_b || 0 };
|
||||
const blocoC1 = p1.bloco_c || { total: consultor1.bloco_c || 0 };
|
||||
const blocoC2 = p2.bloco_c || { total: consultor2.bloco_c || 0 };
|
||||
const blocoD1 = p1.bloco_d || { total: consultor1.bloco_d || 0 };
|
||||
const blocoD2 = p2.bloco_d || { total: consultor2.bloco_d || 0 };
|
||||
|
||||
const total1 = (blocoA1.total || 0) + (blocoB1.total || 0) + (blocoC1.total || 0) + (blocoD1.total || 0);
|
||||
const total2 = (blocoA2.total || 0) + (blocoB2.total || 0) + (blocoC2.total || 0) + (blocoD2.total || 0);
|
||||
const total1 = Number(consultor1.pontuacao_total ?? 0);
|
||||
const total2 = Number(consultor2.pontuacao_total ?? 0);
|
||||
|
||||
const c1 = consultor1.consultoria;
|
||||
const c2 = consultor2.consultoria;
|
||||
@@ -193,11 +191,6 @@ const CompararModal = ({ consultor1, consultor2, onClose }) => {
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="comparacao-secao">
|
||||
<h3 style={{ color: 'var(--accent)' }}>B - Coordenacao PPG</h3>
|
||||
{renderLinhaComparacao('Total', blocoB1.total, blocoB2.total, 'var(--accent)')}
|
||||
</div>
|
||||
|
||||
<div className="comparacao-secao">
|
||||
<h3 style={{ color: 'var(--gold)' }}>C - Consultoria</h3>
|
||||
{renderLinhaComparacao('Total', blocoC1.total, blocoC2.total, 'var(--gold)')}
|
||||
|
||||
@@ -1010,6 +1010,12 @@
|
||||
color: #f9a8d4;
|
||||
}
|
||||
|
||||
.tipo-docente {
|
||||
background: linear-gradient(135deg, rgba(20, 184, 166, 0.2), rgba(20, 184, 166, 0.08));
|
||||
border-color: rgba(20, 184, 166, 0.35);
|
||||
color: #5eead4;
|
||||
}
|
||||
|
||||
.tipo-default {
|
||||
background: rgba(148, 163, 184, 0.12);
|
||||
border-color: rgba(148, 163, 184, 0.25);
|
||||
|
||||
@@ -818,8 +818,8 @@ const ItemDetalheModal = ({ item, tipo, onClose }) => {
|
||||
</div>
|
||||
)}
|
||||
<div className="modal-detalhe-row">
|
||||
<span className="modal-detalhe-label">Pontuação</span>
|
||||
<span className="modal-detalhe-value muted">Apenas selo (sem pontuação)</span>
|
||||
<span className="modal-detalhe-label">Pontuação Base</span>
|
||||
<span className="modal-detalhe-value pontos">{PONTOS_BASE[item.codigo] || 0} pts</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -853,17 +853,13 @@ const FORMULAS = {
|
||||
titulo: 'Coordenacao CAPES',
|
||||
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: {
|
||||
titulo: 'Coordenacao PPG',
|
||||
descricao: 'Reservado no V1: PPG_COORD base=0 | teto=0 (dados incompletos no ATUACAPES para pontuar).',
|
||||
},
|
||||
bloco_c: {
|
||||
titulo: 'Consultoria',
|
||||
descricao: 'CONS_ATIVO=150 | CONS_HIST=100 | CONS_FALECIDO=100\nTempo: 5 pts/ano (max 50)\nContinuidade: 3a=+5, 5a=+10, 8a+=+20 (escalonado)\nRetorno (reativação): +15 (uma vez)',
|
||||
},
|
||||
bloco_d: {
|
||||
titulo: 'Premiacoes/Avaliacoes',
|
||||
descricao: 'Premiações: GP=100 (teto 300) | Prêmio=50 (teto 150) | Menção=30 (teto 90)\nBolsas: BPQ=30 (teto 60)\nInscrições/Avaliações/Comissões/Participações (com tetos por código)\nOrientações/Bancas: apenas selos (0 pts)',
|
||||
descricao: 'Premiações: GP=100 (teto 300) | Prêmio=50 (teto 150) | Menção=30 (teto 90)\nBolsas: BPQ=30 (teto 60)\nInscrições/Avaliações/Comissões/Participações (com tetos por código)\nOrientações e Bancas: apenas selos (sem pontuação)',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -876,9 +872,6 @@ const PONTOS_BASE = {
|
||||
PREMIACAO_GP_AUTOR: 100, PREMIACAO_AUTOR: 50, MENCAO_AUTOR: 30,
|
||||
BOL_BPQ_NIVEL: 30,
|
||||
EVENTO: 1, PROJ: 10,
|
||||
ORIENT_POS_DOC: 0, ORIENT_TESE: 0, ORIENT_DISS: 0,
|
||||
CO_ORIENT_POS_DOC: 0, CO_ORIENT_TESE: 0, CO_ORIENT_DISS: 0,
|
||||
MB_BANCA_POS_DOC: 0, MB_BANCA_TESE: 0, MB_BANCA_DISS: 0,
|
||||
};
|
||||
|
||||
const TETOS = {
|
||||
@@ -894,15 +887,6 @@ const TETOS = {
|
||||
EVENTO: { teto: 5, doc: '3.5 Participações Acadêmicas', bonus: '+1/participação (max 10)' },
|
||||
PROJ: { teto: 30, doc: '3.5 Participações Acadêmicas', bonus: '+2/participação (max 10)' },
|
||||
BOL_BPQ_NIVEL: { teto: 60, doc: '3.4 Premiações e Bolsas' },
|
||||
ORIENT_POS_DOC: { teto: 0, doc: 'Selo (sem pontuação)' },
|
||||
ORIENT_TESE: { teto: 0, doc: 'Selo (sem pontuação)' },
|
||||
ORIENT_DISS: { teto: 0, doc: 'Selo (sem pontuação)' },
|
||||
CO_ORIENT_POS_DOC: { teto: 0, doc: 'Selo (sem pontuação)' },
|
||||
CO_ORIENT_TESE: { teto: 0, doc: 'Selo (sem pontuação)' },
|
||||
CO_ORIENT_DISS: { teto: 0, doc: 'Selo (sem pontuação)' },
|
||||
MB_BANCA_POS_DOC: { teto: 0, doc: 'Selo (sem pontuação)' },
|
||||
MB_BANCA_TESE: { teto: 0, doc: 'Selo (sem pontuação)' },
|
||||
MB_BANCA_DISS: { teto: 0, doc: 'Selo (sem pontuação)' },
|
||||
};
|
||||
|
||||
const PontuacaoModal = ({ dados, onClose }) => {
|
||||
@@ -1054,7 +1038,7 @@ const PontuacaoModal = ({ dados, onClose }) => {
|
||||
<div className="modal-formula-section">
|
||||
<span className="modal-detalhe-label">Fórmula</span>
|
||||
<div className="modal-formula-box">
|
||||
<div className="modal-formula-line">Bloco A + Bloco B + Bloco C + Bloco D</div>
|
||||
<div className="modal-formula-line">Bloco A + Bloco C + Bloco D</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1132,10 +1116,9 @@ const ConsultorCard = memo(({ consultor, highlight, selecionado, onToggleSelecio
|
||||
|
||||
const { consultoria, pontuacao } = consultor;
|
||||
const blocoA = pontuacao?.bloco_a || { total: consultor.bloco_a || 0 };
|
||||
const blocoB = pontuacao?.bloco_b || { total: consultor.bloco_b || 0 };
|
||||
const blocoC = pontuacao?.bloco_c || { total: consultor.bloco_c || 0 };
|
||||
const blocoD = pontuacao?.bloco_d || { total: consultor.bloco_d || 0 };
|
||||
const pontuacaoTotal = (blocoA.total || 0) + (blocoB.total || 0) + (blocoC.total || 0) + (blocoD.total || 0);
|
||||
const pontuacaoTotal = Number(consultor.pontuacao_total ?? 0);
|
||||
|
||||
const selos = useMemo(() => gerarSelos(consultor), [consultor]);
|
||||
|
||||
@@ -1246,18 +1229,6 @@ const ConsultorCard = memo(({ consultor, highlight, selecionado, onToggleSelecio
|
||||
bloco: blocoA
|
||||
})}
|
||||
/>
|
||||
<ScoreItemClickable
|
||||
value={blocoB.total}
|
||||
label="BLOCO B"
|
||||
style={{ color: blocoB.total > 0 ? 'var(--accent)' : 'var(--muted)' }}
|
||||
onClick={() => setPontuacaoModal({
|
||||
tipo: 'bloco',
|
||||
label: 'BLOCO B - Coordenação PPG',
|
||||
value: blocoB.total,
|
||||
formula: FORMULAS.bloco_b.descricao,
|
||||
bloco: blocoB
|
||||
})}
|
||||
/>
|
||||
<ScoreItemClickable
|
||||
value={blocoC.total}
|
||||
label="BLOCO C"
|
||||
@@ -1299,10 +1270,6 @@ const ConsultorCard = memo(({ consultor, highlight, selecionado, onToggleSelecio
|
||||
<BlocoDetalhes titulo="A - Coordenacao CAPES" bloco={blocoA} cor="var(--accent-2)" onItemClick={setPontuacaoModal} />
|
||||
)}
|
||||
|
||||
{(blocoB.total > 0 || (blocoB.atuacoes && blocoB.atuacoes.length > 0)) && (
|
||||
<BlocoDetalhes titulo="B - Coordenacao PPG" bloco={blocoB} cor="var(--accent)" onItemClick={setPontuacaoModal} />
|
||||
)}
|
||||
|
||||
{blocoC.atuacoes && blocoC.atuacoes.length > 0 && (
|
||||
<BlocoDetalhes titulo="C - Consultoria" bloco={blocoC} cor="var(--gold)" onItemClick={setPontuacaoModal} />
|
||||
)}
|
||||
@@ -1571,11 +1538,23 @@ const ConsultorCard = memo(({ consultor, highlight, selecionado, onToggleSelecio
|
||||
|
||||
ConsultorCard.displayName = 'ConsultorCard';
|
||||
|
||||
const BlocoDetalhes = memo(({ titulo, bloco, cor, onItemClick }) => (
|
||||
const CODIGOS_APENAS_SELO = [
|
||||
'ORIENT_POS_DOC', 'ORIENT_TESE', 'ORIENT_DISS',
|
||||
'CO_ORIENT_POS_DOC', 'CO_ORIENT_TESE', 'CO_ORIENT_DISS',
|
||||
'MB_BANCA_POS_DOC', 'MB_BANCA_TESE', 'MB_BANCA_DISS',
|
||||
'ORIENT_POS_DOC_PREM', 'ORIENT_TESE_PREM', 'ORIENT_DISS_PREM',
|
||||
'CO_ORIENT_POS_DOC_PREM', 'CO_ORIENT_TESE_PREM', 'CO_ORIENT_DISS_PREM',
|
||||
'MB_BANCA_POS_DOC_PREM', 'MB_BANCA_TESE_PREM', 'MB_BANCA_DISS_PREM',
|
||||
];
|
||||
|
||||
const BlocoDetalhes = memo(({ titulo, bloco, cor, onItemClick }) => {
|
||||
const atuacoesFiltradas = bloco.atuacoes?.filter(at => !CODIGOS_APENAS_SELO.includes(at.codigo)) || [];
|
||||
|
||||
return (
|
||||
<div className="detail-section">
|
||||
<h4 style={{ color: cor }}>{titulo}</h4>
|
||||
<div className="score-breakdown">
|
||||
{bloco.atuacoes?.map((at, idx) => (
|
||||
{atuacoesFiltradas.map((at, idx) => (
|
||||
<div
|
||||
key={idx}
|
||||
className="score-item-wrapper score-item-clicavel"
|
||||
@@ -1608,7 +1587,8 @@ const BlocoDetalhes = memo(({ titulo, bloco, cor, onItemClick }) => (
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
));
|
||||
);
|
||||
});
|
||||
|
||||
BlocoDetalhes.displayName = 'BlocoDetalhes';
|
||||
|
||||
|
||||
@@ -64,17 +64,9 @@ const Header = ({ total }) => {
|
||||
<div className="criteria-section bloco-e">
|
||||
<div className="section-header">
|
||||
<h4>E - Coord. PPG</h4>
|
||||
<span className="max-pts">V2</span>
|
||||
<span className="max-pts">indicador</span>
|
||||
</div>
|
||||
<table className="criteria-table">
|
||||
<thead>
|
||||
<tr><th>Cod</th><th>Base</th><th>Teto</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>PPG_COORD</td><td>0</td><td>0</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div className="criteria-note">Dados incompletos no V1</div>
|
||||
<div className="criteria-note">Nao entra no score (apenas selo/indicador no perfil)</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user