feat(ui): expandir modal de dados e melhorar template PDF
- Expandir RawDataModal com mais funcionalidades de visualização - Ajustar template HTML da ficha do consultor - Adicionar configuração MCP do projeto - Atualizar gitignore para ignorar arquivos locais
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -31,3 +31,9 @@ node_modules/
|
|||||||
*.csv
|
*.csv
|
||||||
backend/logs/
|
backend/logs/
|
||||||
.cache/
|
.cache/
|
||||||
|
|
||||||
|
# LibreOffice profile (local)
|
||||||
|
.lo_profile/
|
||||||
|
|
||||||
|
# XDG config (local)
|
||||||
|
.xdg/
|
||||||
|
|||||||
15
.mcp.json
Normal file
15
.mcp.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"atuacapes": {
|
||||||
|
"command": "/home/fred/MCPs-Central/mcp-atuacapes/venv/bin/python",
|
||||||
|
"args": ["-m", "atuacapes_mcp.server"],
|
||||||
|
"cwd": "/home/fred/MCPs-Central/mcp-atuacapes",
|
||||||
|
"env": {
|
||||||
|
"ES_HOST": "http://elastic-atuacapes.hom.capes.gov.br:9200",
|
||||||
|
"ES_USER": "admin-atuacapes",
|
||||||
|
"ES_PASS": "O}!S0bj%FhJ:",
|
||||||
|
"ES_INDEX": "atuacapes"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,6 +15,7 @@ class PDFService:
|
|||||||
)
|
)
|
||||||
self.env.filters['format_date'] = self._format_date
|
self.env.filters['format_date'] = self._format_date
|
||||||
self.env.filters['format_date_short'] = self._format_date_short
|
self.env.filters['format_date_short'] = self._format_date_short
|
||||||
|
self.env.filters['sort_by_date'] = self._sort_by_date
|
||||||
self.template = self.env.get_template("ficha_consultor.html")
|
self.template = self.env.get_template("ficha_consultor.html")
|
||||||
|
|
||||||
def _format_date(self, date_str: str) -> str:
|
def _format_date(self, date_str: str) -> str:
|
||||||
@@ -46,6 +47,68 @@ class PDFService:
|
|||||||
except (ValueError, AttributeError, IndexError):
|
except (ValueError, AttributeError, IndexError):
|
||||||
return str(date_str)[:10] if date_str else "-"
|
return str(date_str)[:10] if date_str else "-"
|
||||||
|
|
||||||
|
def _sort_by_date(self, items, *fields):
|
||||||
|
if not items or not fields:
|
||||||
|
return items
|
||||||
|
|
||||||
|
def extract_field(value, field):
|
||||||
|
for part in field.split("."):
|
||||||
|
if value is None:
|
||||||
|
return None
|
||||||
|
if isinstance(value, DictWrapper):
|
||||||
|
value = value.get(part)
|
||||||
|
elif isinstance(value, dict):
|
||||||
|
value = value.get(part)
|
||||||
|
else:
|
||||||
|
value = getattr(value, part, None)
|
||||||
|
return value
|
||||||
|
|
||||||
|
def parse_date(value):
|
||||||
|
if value is None:
|
||||||
|
return None
|
||||||
|
if isinstance(value, datetime):
|
||||||
|
return value
|
||||||
|
if isinstance(value, (int, float)):
|
||||||
|
year = int(value)
|
||||||
|
return datetime(year, 1, 1)
|
||||||
|
if not isinstance(value, str):
|
||||||
|
return None
|
||||||
|
text = value.strip()
|
||||||
|
if not text:
|
||||||
|
return None
|
||||||
|
if text.isdigit() and len(text) == 4:
|
||||||
|
return datetime(int(text), 1, 1)
|
||||||
|
if "/" in text:
|
||||||
|
parts = text.split("/")
|
||||||
|
try:
|
||||||
|
if len(parts) == 3:
|
||||||
|
day = int(parts[0])
|
||||||
|
month = int(parts[1])
|
||||||
|
year = int(parts[2])
|
||||||
|
return datetime(year, month, day)
|
||||||
|
if len(parts) == 2:
|
||||||
|
month = int(parts[0])
|
||||||
|
year = int(parts[1])
|
||||||
|
return datetime(year, month, 1)
|
||||||
|
except ValueError:
|
||||||
|
return None
|
||||||
|
try:
|
||||||
|
return datetime.fromisoformat(text.replace("Z", "+00:00"))
|
||||||
|
except ValueError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def sort_key(item):
|
||||||
|
value = None
|
||||||
|
for field in fields:
|
||||||
|
value = parse_date(extract_field(item, field))
|
||||||
|
if value is not None:
|
||||||
|
break
|
||||||
|
if value is None:
|
||||||
|
return (0, datetime.min)
|
||||||
|
return (1, value)
|
||||||
|
|
||||||
|
return sorted(items, key=sort_key, reverse=True)
|
||||||
|
|
||||||
def _consultor_to_dict(self, consultor: Any) -> Dict:
|
def _consultor_to_dict(self, consultor: Any) -> Dict:
|
||||||
if is_dataclass(consultor) and not isinstance(consultor, type):
|
if is_dataclass(consultor) and not isinstance(consultor, type):
|
||||||
return asdict(consultor)
|
return asdict(consultor)
|
||||||
|
|||||||
@@ -195,7 +195,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for e in emails %}
|
{% for e in emails|sort_by_date('ultimaAlteracao') %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ e.email }}</td>
|
<td>{{ e.email }}</td>
|
||||||
<td>{{ e.tipo or '-' }}</td>
|
<td>{{ e.tipo or '-' }}</td>
|
||||||
@@ -275,7 +275,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for i in identificadores %}
|
{% for i in identificadores|sort_by_date('fimValidade', 'inicioValidade') %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ i.tipo or '-' }}</td>
|
<td>{{ i.tipo or '-' }}</td>
|
||||||
<td>{{ i.descricao or '-' }}</td>
|
<td>{{ i.descricao or '-' }}</td>
|
||||||
@@ -291,7 +291,7 @@
|
|||||||
<td>{{ identificador_lattes.inicioValidade or '-' }}{% if identificador_lattes.fimValidade %} a {{ identificador_lattes.fimValidade }}{% endif %}</td>
|
<td>{{ identificador_lattes.inicioValidade or '-' }}{% if identificador_lattes.fimValidade %} a {{ identificador_lattes.fimValidade }}{% endif %}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% for d in documentos %}
|
{% for d in documentos|sort_by_date('fimValidade', 'inicioValidade') %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ d.tipo or '-' }}</td>
|
<td>{{ d.tipo or '-' }}</td>
|
||||||
<td>{{ d.descricao or '-' }}</td>
|
<td>{{ d.descricao or '-' }}</td>
|
||||||
@@ -322,7 +322,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for t in titulacoes %}
|
{% for t in titulacoes|sort_by_date('fim', 'inicio') %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ t.grauAcademico.nome if t.grauAcademico else '-' }}</td>
|
<td>{{ t.grauAcademico.nome if t.grauAcademico else '-' }}</td>
|
||||||
<td>{{ t.ies.nome if t.ies else '-' }}{% if t.ies and t.ies.sigla %} ({{ t.ies.sigla }}){% endif %}</td>
|
<td>{{ t.ies.nome if t.ies else '-' }}{% if t.ies and t.ies.sigla %} ({{ t.ies.sigla }}){% endif %}</td>
|
||||||
@@ -370,7 +370,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for b in bolsas %}
|
{% for b in bolsas|sort_by_date('fim', 'inicio') %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ b.programa or b.tipo or '-' }}</td>
|
<td>{{ b.programa or b.tipo or '-' }}</td>
|
||||||
<td>{{ b.ies.nome if b.ies else '-' }}</td>
|
<td>{{ b.ies.nome if b.ies else '-' }}</td>
|
||||||
@@ -475,7 +475,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for v in consultor.consultoria.vinculos %}
|
{% for v in consultor.consultoria.vinculos|sort_by_date('periodo.fim', 'periodo.inicio') %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ v.ies.nome if v.ies else '-' }}{% if v.ies and v.ies.sigla %} ({{ v.ies.sigla }}){% endif %}</td>
|
<td>{{ v.ies.nome if v.ies else '-' }}{% if v.ies and v.ies.sigla %} ({{ v.ies.sigla }}){% endif %}</td>
|
||||||
<td>{{ v.periodo.inicio|format_date_short if v.periodo else '-' }} a {{ v.periodo.fim|format_date_short if v.periodo and v.periodo.fim else 'Atual' }}</td>
|
<td>{{ v.periodo.inicio|format_date_short if v.periodo else '-' }} a {{ v.periodo.fim|format_date_short if v.periodo and v.periodo.fim else 'Atual' }}</td>
|
||||||
@@ -549,7 +549,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for coord in consultor.coordenacoes_capes %}
|
{% for coord in consultor.coordenacoes_capes|sort_by_date('periodo.fim', 'periodo.inicio') %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ coord.codigo }}</td>
|
<td>{{ coord.codigo }}</td>
|
||||||
<td>{{ coord.area_avaliacao or '-' }}</td>
|
<td>{{ coord.area_avaliacao or '-' }}</td>
|
||||||
@@ -630,7 +630,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for v in consultor.consultoria.vinculos %}
|
{% for v in consultor.consultoria.vinculos|sort_by_date('periodo.fim', 'periodo.inicio') %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ v.ies.nome if v.ies else '-' }}{% if v.ies and v.ies.sigla %} ({{ v.ies.sigla }}){% endif %}</td>
|
<td>{{ v.ies.nome if v.ies else '-' }}{% if v.ies and v.ies.sigla %} ({{ v.ies.sigla }}){% endif %}</td>
|
||||||
<td>{{ v.periodo.inicio|format_date_short if v.periodo else '-' }} a {{ v.periodo.fim|format_date_short if v.periodo and v.periodo.fim else 'Atual' }}</td>
|
<td>{{ v.periodo.inicio|format_date_short if v.periodo else '-' }} a {{ v.periodo.fim|format_date_short if v.periodo and v.periodo.fim else 'Atual' }}</td>
|
||||||
@@ -689,7 +689,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for a in consultor.avaliacoes_comissao %}
|
{% for a in consultor.avaliacoes_comissao|sort_by_date('ano') %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ a.codigo }}</td>
|
<td>{{ a.codigo }}</td>
|
||||||
<td>{{ a.tipo }}</td>
|
<td>{{ a.tipo }}</td>
|
||||||
@@ -715,7 +715,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for p in consultor.premiacoes %}
|
{% for p in consultor.premiacoes|sort_by_date('ano') %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ p.codigo }}</td>
|
<td>{{ p.codigo }}</td>
|
||||||
<td>{{ p.tipo }}</td>
|
<td>{{ p.tipo }}</td>
|
||||||
@@ -741,7 +741,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for i in consultor.inscricoes %}
|
{% for i in consultor.inscricoes|sort_by_date('ano') %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ i.codigo }}</td>
|
<td>{{ i.codigo }}</td>
|
||||||
<td>{{ i.tipo }}</td>
|
<td>{{ i.tipo }}</td>
|
||||||
@@ -768,7 +768,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for o in consultor.orientacoes %}
|
{% for o in consultor.orientacoes|sort_by_date('ano') %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ o.codigo }}</td>
|
<td>{{ o.codigo }}</td>
|
||||||
<td>{{ o.tipo }}</td>
|
<td>{{ o.tipo }}</td>
|
||||||
@@ -794,7 +794,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for b in consultor.membros_banca %}
|
{% for b in consultor.membros_banca|sort_by_date('ano') %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ b.codigo }}</td>
|
<td>{{ b.codigo }}</td>
|
||||||
<td>{{ b.tipo }}</td>
|
<td>{{ b.tipo }}</td>
|
||||||
@@ -818,7 +818,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for p in consultor.participacoes %}
|
{% for p in consultor.participacoes|sort_by_date('ano') %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ p.codigo }}</td>
|
<td>{{ p.codigo }}</td>
|
||||||
<td>{{ p.tipo }}</td>
|
<td>{{ p.tipo }}</td>
|
||||||
@@ -873,7 +873,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for a in atuacoes_raw %}
|
{% for a in atuacoes_raw|sort_by_date('fim', 'inicio') %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ a.tipo or '-' }}</td>
|
<td>{{ a.tipo or '-' }}</td>
|
||||||
<td>{{ a.descricao or a.nome or '-' }}</td>
|
<td>{{ a.descricao or a.nome or '-' }}</td>
|
||||||
|
|||||||
@@ -481,15 +481,38 @@
|
|||||||
min-width: 35px;
|
min-width: 35px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.atuacao-tipo {
|
.atuacao-main {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.15rem;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.atuacao-tipo {
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
color: #e2e8f0;
|
color: #e2e8f0;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.atuacao-summary {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: #94a3b8;
|
||||||
|
line-height: 1.3;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.atuacao-meta {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-end;
|
||||||
|
gap: 0.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
.atuacao-periodo {
|
.atuacao-periodo {
|
||||||
font-size: 0.8rem;
|
font-size: 0.75rem;
|
||||||
color: #94a3b8;
|
color: #94a3b8;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -501,6 +524,16 @@
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.atuacao-meta-line {
|
||||||
|
font-size: 0.72rem;
|
||||||
|
color: #7dd3fc;
|
||||||
|
text-align: right;
|
||||||
|
max-width: 260px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
.atuacao-toggle {
|
.atuacao-toggle {
|
||||||
color: #64748b;
|
color: #64748b;
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
@@ -611,7 +644,7 @@
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.atuacao-tipo {
|
.atuacao-main {
|
||||||
order: 1;
|
order: 1;
|
||||||
flex: 1 1 100%;
|
flex: 1 1 100%;
|
||||||
}
|
}
|
||||||
@@ -620,9 +653,10 @@
|
|||||||
order: 2;
|
order: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.atuacao-periodo {
|
.atuacao-meta {
|
||||||
order: 3;
|
order: 3;
|
||||||
flex: 1;
|
align-items: flex-start;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.atuacao-toggle {
|
.atuacao-toggle {
|
||||||
|
|||||||
@@ -61,6 +61,33 @@ const LABEL_MAP = {
|
|||||||
colegio: 'Colégio',
|
colegio: 'Colégio',
|
||||||
ies: 'IES',
|
ies: 'IES',
|
||||||
programa: 'Programa',
|
programa: 'Programa',
|
||||||
|
nomeEmpregador: 'Empregador',
|
||||||
|
emprego: 'Vínculo',
|
||||||
|
atividade: 'Atividade',
|
||||||
|
dtAdmissao: 'Admissão',
|
||||||
|
dtDesligamento: 'Desligamento',
|
||||||
|
cnpjEmpregador: 'CNPJ Empregador',
|
||||||
|
profissao: 'Profissão',
|
||||||
|
matricula: 'Matrícula',
|
||||||
|
vinculo: 'Vínculo',
|
||||||
|
historico: 'Histórico',
|
||||||
|
inicioRelacionamento: 'Início Relacionamento',
|
||||||
|
fimRelacionamento: 'Fim Relacionamento',
|
||||||
|
categoria: 'Categoria',
|
||||||
|
tipoVinculo: 'Tipo de Vínculo',
|
||||||
|
vinculoTrabalho: 'Vínculo de Trabalho',
|
||||||
|
regimeTrabalho: 'Regime de Trabalho',
|
||||||
|
cargaHoraria: 'Carga Horária',
|
||||||
|
linhaPesquisa: 'Linha de Pesquisa',
|
||||||
|
areaConcentracao: 'Área de Concentração',
|
||||||
|
areaPesquisa: 'Área de Pesquisa',
|
||||||
|
consultorResponsavel: 'Consultor Responsável',
|
||||||
|
unidadeOrganizacional: 'Unidade Organizacional',
|
||||||
|
localEvento: 'Local do Evento',
|
||||||
|
nrProcesso: 'Número do Processo',
|
||||||
|
idProcesso: 'ID do Processo',
|
||||||
|
anoInicio: 'Ano de Início',
|
||||||
|
tipoTrabalho: 'Tipo de Trabalho',
|
||||||
inicioVinculacao: 'Início Vinculação',
|
inicioVinculacao: 'Início Vinculação',
|
||||||
fimVinculacao: 'Fim Vinculação',
|
fimVinculacao: 'Fim Vinculação',
|
||||||
inicioSituacao: 'Início Situação',
|
inicioSituacao: 'Início Situação',
|
||||||
@@ -78,6 +105,11 @@ const LABEL_MAP = {
|
|||||||
nivel: 'Nível',
|
nivel: 'Nível',
|
||||||
modalidade: 'Modalidade',
|
modalidade: 'Modalidade',
|
||||||
camaraTematica: 'Câmara Temática',
|
camaraTematica: 'Câmara Temática',
|
||||||
|
totalOrientacaoFinalizadaMestrado: 'Orientações Finalizadas (Mestrado)',
|
||||||
|
totalOrientacaoFinalizadaDoutorado: 'Orientações Finalizadas (Doutorado)',
|
||||||
|
totalOrientacaoAndamentoMestrado: 'Orientações em Andamento (Mestrado)',
|
||||||
|
totalOrientacaoAndamentoDoutorado: 'Orientações em Andamento (Doutorado)',
|
||||||
|
totalAcompanhamentoPosDoutorado: 'Acompanhamentos Pós-Doutorado',
|
||||||
};
|
};
|
||||||
|
|
||||||
const formatLabel = (key) => LABEL_MAP[key] || key.replace(/([A-Z])/g, ' $1').replace(/^./, s => s.toUpperCase());
|
const formatLabel = (key) => LABEL_MAP[key] || key.replace(/([A-Z])/g, ' $1').replace(/^./, s => s.toUpperCase());
|
||||||
@@ -154,6 +186,122 @@ const AtuacaoCard = ({ atuacao, index }) => {
|
|||||||
const [expanded, setExpanded] = useState(false);
|
const [expanded, setExpanded] = useState(false);
|
||||||
const tipo = atuacao.tipo || 'Tipo não informado';
|
const tipo = atuacao.tipo || 'Tipo não informado';
|
||||||
|
|
||||||
|
const getNestedValue = (obj, path) => {
|
||||||
|
if (!obj || !path) return undefined;
|
||||||
|
return path.split('.').reduce((acc, key) => (acc ? acc[key] : undefined), obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
const joinParts = (parts) => parts.filter(Boolean).join(' · ');
|
||||||
|
|
||||||
|
const buildSummary = () => {
|
||||||
|
const tipoLower = tipo.toLowerCase();
|
||||||
|
const dadosDocencia = atuacao.dadosDocencia || {};
|
||||||
|
const dadosEmprego = atuacao.dadosEmprego || {};
|
||||||
|
const dadosEvento = atuacao.dadosEvento || atuacao.dadosParticipacaoEvento || {};
|
||||||
|
const dadosProjeto = atuacao.dadosProjeto || {};
|
||||||
|
const dadosProcesso = atuacao.dadosProcesso || {};
|
||||||
|
const dadosOrientacaoDiscente = atuacao.dadosOrientacaoDiscente || {};
|
||||||
|
|
||||||
|
if (tipoLower.includes('docência') || tipoLower.includes('docencia')) {
|
||||||
|
const ies = dadosDocencia.ies?.sigla
|
||||||
|
? `${dadosDocencia.ies.sigla} — ${dadosDocencia.ies.nome}`
|
||||||
|
: dadosDocencia.ies?.nome;
|
||||||
|
const primary = joinParts([
|
||||||
|
dadosDocencia.programa?.nome || dadosDocencia.areaConhecimento?.nome || atuacao.descricao,
|
||||||
|
ies,
|
||||||
|
dadosDocencia.categoria,
|
||||||
|
]);
|
||||||
|
const secondary = joinParts([
|
||||||
|
dadosDocencia.tipoVinculo,
|
||||||
|
dadosDocencia.regimeTrabalho,
|
||||||
|
dadosDocencia.cargaHoraria ? `${dadosDocencia.cargaHoraria}h` : null,
|
||||||
|
]);
|
||||||
|
return { primary, secondary };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tipoLower.includes('emprego')) {
|
||||||
|
const primary = joinParts([
|
||||||
|
dadosEmprego.nomeEmpregador || atuacao.descricao,
|
||||||
|
dadosEmprego.emprego || dadosEmprego.vinculo,
|
||||||
|
dadosEmprego.atividade,
|
||||||
|
]);
|
||||||
|
const secondary = joinParts([
|
||||||
|
dadosEmprego.dtAdmissao,
|
||||||
|
dadosEmprego.dtDesligamento ? `até ${dadosEmprego.dtDesligamento}` : null,
|
||||||
|
dadosEmprego.profissao,
|
||||||
|
]);
|
||||||
|
return { primary, secondary };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tipoLower.includes('evento')) {
|
||||||
|
const primary = joinParts([
|
||||||
|
dadosEvento.nome || atuacao.descricao,
|
||||||
|
dadosEvento.unidadeOrganizacional,
|
||||||
|
dadosEvento.localEvento,
|
||||||
|
]);
|
||||||
|
const secondary = joinParts([
|
||||||
|
dadosEvento.atividade,
|
||||||
|
dadosEvento.tipo,
|
||||||
|
dadosEvento.codigo ? `Código ${dadosEvento.codigo}` : null,
|
||||||
|
]);
|
||||||
|
return { primary, secondary };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tipoLower.includes('projeto')) {
|
||||||
|
const primary = joinParts([
|
||||||
|
dadosProjeto.nome || atuacao.descricao,
|
||||||
|
dadosProjeto.programa?.nome,
|
||||||
|
dadosProjeto.ies?.sigla || dadosProjeto.ies?.nome,
|
||||||
|
]);
|
||||||
|
const secondary = joinParts([
|
||||||
|
dadosProjeto.situacao,
|
||||||
|
dadosProjeto.linhaPesquisa,
|
||||||
|
dadosProjeto.anoInicio ? `Início ${dadosProjeto.anoInicio}` : null,
|
||||||
|
]);
|
||||||
|
return { primary, secondary };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tipoLower.includes('orientação de discentes') || tipoLower.includes('orientacao de discentes')) {
|
||||||
|
const mestradoParts = [];
|
||||||
|
if (dadosOrientacaoDiscente.totalOrientacaoFinalizadaMestrado) {
|
||||||
|
mestradoParts.push(`Finalizadas ${dadosOrientacaoDiscente.totalOrientacaoFinalizadaMestrado}`);
|
||||||
|
}
|
||||||
|
if (dadosOrientacaoDiscente.totalOrientacaoAndamentoMestrado) {
|
||||||
|
mestradoParts.push(`Andamento ${dadosOrientacaoDiscente.totalOrientacaoAndamentoMestrado}`);
|
||||||
|
}
|
||||||
|
const doutoradoParts = [];
|
||||||
|
if (dadosOrientacaoDiscente.totalOrientacaoFinalizadaDoutorado) {
|
||||||
|
doutoradoParts.push(`Finalizadas ${dadosOrientacaoDiscente.totalOrientacaoFinalizadaDoutorado}`);
|
||||||
|
}
|
||||||
|
if (dadosOrientacaoDiscente.totalOrientacaoAndamentoDoutorado) {
|
||||||
|
doutoradoParts.push(`Andamento ${dadosOrientacaoDiscente.totalOrientacaoAndamentoDoutorado}`);
|
||||||
|
}
|
||||||
|
const primary = joinParts([
|
||||||
|
mestradoParts.length ? `Mestrado ${mestradoParts.join(' / ')}` : null,
|
||||||
|
doutoradoParts.length ? `Doutorado ${doutoradoParts.join(' / ')}` : null,
|
||||||
|
]);
|
||||||
|
const secondary = dadosOrientacaoDiscente.totalAcompanhamentoPosDoutorado
|
||||||
|
? `Pós-doc ${dadosOrientacaoDiscente.totalAcompanhamentoPosDoutorado}`
|
||||||
|
: null;
|
||||||
|
return { primary, secondary };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tipoLower.includes('processo')) {
|
||||||
|
const iesLabel = dadosProcesso.ies?.sigla || dadosProcesso.ies?.nome;
|
||||||
|
const primary = joinParts([dadosProcesso.nrProcesso || atuacao.descricao, iesLabel]);
|
||||||
|
const secondary = dadosProcesso.ies?.statusJuridico
|
||||||
|
? `IES ${dadosProcesso.ies.statusJuridico.trim()}`
|
||||||
|
: null;
|
||||||
|
return { primary, secondary };
|
||||||
|
}
|
||||||
|
|
||||||
|
const fallbackPrimary = joinParts([
|
||||||
|
atuacao.descricao,
|
||||||
|
getNestedValue(atuacao, 'procedencia.origem'),
|
||||||
|
]);
|
||||||
|
return { primary: fallbackPrimary, secondary: null };
|
||||||
|
};
|
||||||
|
|
||||||
const getAtuacaoColor = (tipo) => {
|
const getAtuacaoColor = (tipo) => {
|
||||||
if (tipo.includes('Coordenação')) return 'atuacao-coordenacao';
|
if (tipo.includes('Coordenação')) return 'atuacao-coordenacao';
|
||||||
if (tipo.includes('Consultor')) return 'atuacao-consultoria';
|
if (tipo.includes('Consultor')) return 'atuacao-consultoria';
|
||||||
@@ -177,8 +325,17 @@ const AtuacaoCard = ({ atuacao, index }) => {
|
|||||||
'dadosParticipacaoInscricaoPremio',
|
'dadosParticipacaoInscricaoPremio',
|
||||||
'dadosBolsistaCNPq',
|
'dadosBolsistaCNPq',
|
||||||
'dadosOrientacao',
|
'dadosOrientacao',
|
||||||
|
'dadosOrientacaoDiscente',
|
||||||
'dadosParticipacao',
|
'dadosParticipacao',
|
||||||
|
'dadosParticipacaoEvento',
|
||||||
'dadosGestaoPrograma',
|
'dadosGestaoPrograma',
|
||||||
|
'dadosDocencia',
|
||||||
|
'dadosEmprego',
|
||||||
|
'dadosEvento',
|
||||||
|
'dadosProjeto',
|
||||||
|
'dadosProcesso',
|
||||||
|
'dadosAnaliseProcesso',
|
||||||
|
'dadosPapelPessoa',
|
||||||
];
|
];
|
||||||
|
|
||||||
const dateKeys = ['inicio', 'fim', 'inicioVinculacao', 'fimVinculacao', 'inicioSituacao', 'inativacaoSituacao'];
|
const dateKeys = ['inicio', 'fim', 'inicioVinculacao', 'fimVinculacao', 'inicioSituacao', 'inativacaoSituacao'];
|
||||||
@@ -196,6 +353,13 @@ const AtuacaoCard = ({ atuacao, index }) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const baseKeys = ['descricao', 'quantidade', 'id', 'procedencia'];
|
||||||
|
baseKeys.forEach((key) => {
|
||||||
|
if (atuacao[key] !== null && atuacao[key] !== undefined && allData[key] === undefined) {
|
||||||
|
allData[key] = atuacao[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (Object.keys(allData).length === 0) {
|
if (Object.keys(allData).length === 0) {
|
||||||
if (atuacao.inicio) allData.inicio = atuacao.inicio;
|
if (atuacao.inicio) allData.inicio = atuacao.inicio;
|
||||||
if (atuacao.fim) allData.fim = atuacao.fim;
|
if (atuacao.fim) allData.fim = atuacao.fim;
|
||||||
@@ -207,17 +371,24 @@ const AtuacaoCard = ({ atuacao, index }) => {
|
|||||||
|
|
||||||
const dados = getAllDados();
|
const dados = getAllDados();
|
||||||
const hasData = Object.keys(dados).length > 0;
|
const hasData = Object.keys(dados).length > 0;
|
||||||
|
const summary = buildSummary();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`atuacao-card ${getAtuacaoColor(tipo)}`}>
|
<div className={`atuacao-card ${getAtuacaoColor(tipo)}`}>
|
||||||
<div className="atuacao-header" onClick={() => setExpanded(!expanded)}>
|
<div className="atuacao-header" onClick={() => setExpanded(!expanded)}>
|
||||||
<span className="atuacao-index">#{index + 1}</span>
|
<span className="atuacao-index">#{index + 1}</span>
|
||||||
|
<div className="atuacao-main">
|
||||||
<span className="atuacao-tipo">{tipo}</span>
|
<span className="atuacao-tipo">{tipo}</span>
|
||||||
|
{summary.primary && <span className="atuacao-summary">{summary.primary}</span>}
|
||||||
|
</div>
|
||||||
|
<div className="atuacao-meta">
|
||||||
<div className="atuacao-periodo">
|
<div className="atuacao-periodo">
|
||||||
{atuacao.inicio && <span>{formatDate(atuacao.inicio)}</span>}
|
{atuacao.inicio && <span>{formatDate(atuacao.inicio)}</span>}
|
||||||
{atuacao.inicio && atuacao.fim && <span> - </span>}
|
{atuacao.inicio && atuacao.fim && <span> - </span>}
|
||||||
{atuacao.fim ? <span>{formatDate(atuacao.fim)}</span> : atuacao.inicio && <span className="ativo">Atual</span>}
|
{atuacao.fim ? <span>{formatDate(atuacao.fim)}</span> : atuacao.inicio && <span className="ativo">Atual</span>}
|
||||||
</div>
|
</div>
|
||||||
|
{summary.secondary && <div className="atuacao-meta-line">{summary.secondary}</div>}
|
||||||
|
</div>
|
||||||
<span className="atuacao-toggle">{expanded ? '−' : '+'}</span>
|
<span className="atuacao-toggle">{expanded ? '−' : '+'}</span>
|
||||||
</div>
|
</div>
|
||||||
{expanded && (
|
{expanded && (
|
||||||
|
|||||||
Reference in New Issue
Block a user