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:
@@ -15,6 +15,7 @@ class PDFService:
|
||||
)
|
||||
self.env.filters['format_date'] = self._format_date
|
||||
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")
|
||||
|
||||
def _format_date(self, date_str: str) -> str:
|
||||
@@ -46,6 +47,68 @@ class PDFService:
|
||||
except (ValueError, AttributeError, IndexError):
|
||||
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:
|
||||
if is_dataclass(consultor) and not isinstance(consultor, type):
|
||||
return asdict(consultor)
|
||||
|
||||
@@ -195,7 +195,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for e in emails %}
|
||||
{% for e in emails|sort_by_date('ultimaAlteracao') %}
|
||||
<tr>
|
||||
<td>{{ e.email }}</td>
|
||||
<td>{{ e.tipo or '-' }}</td>
|
||||
@@ -275,7 +275,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for i in identificadores %}
|
||||
{% for i in identificadores|sort_by_date('fimValidade', 'inicioValidade') %}
|
||||
<tr>
|
||||
<td>{{ i.tipo 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>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% for d in documentos %}
|
||||
{% for d in documentos|sort_by_date('fimValidade', 'inicioValidade') %}
|
||||
<tr>
|
||||
<td>{{ d.tipo or '-' }}</td>
|
||||
<td>{{ d.descricao or '-' }}</td>
|
||||
@@ -322,7 +322,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for t in titulacoes %}
|
||||
{% for t in titulacoes|sort_by_date('fim', 'inicio') %}
|
||||
<tr>
|
||||
<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>
|
||||
@@ -370,7 +370,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for b in bolsas %}
|
||||
{% for b in bolsas|sort_by_date('fim', 'inicio') %}
|
||||
<tr>
|
||||
<td>{{ b.programa or b.tipo or '-' }}</td>
|
||||
<td>{{ b.ies.nome if b.ies else '-' }}</td>
|
||||
@@ -475,7 +475,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for v in consultor.consultoria.vinculos %}
|
||||
{% for v in consultor.consultoria.vinculos|sort_by_date('periodo.fim', 'periodo.inicio') %}
|
||||
<tr>
|
||||
<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>
|
||||
@@ -549,7 +549,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for coord in consultor.coordenacoes_capes %}
|
||||
{% for coord in consultor.coordenacoes_capes|sort_by_date('periodo.fim', 'periodo.inicio') %}
|
||||
<tr>
|
||||
<td>{{ coord.codigo }}</td>
|
||||
<td>{{ coord.area_avaliacao or '-' }}</td>
|
||||
@@ -630,7 +630,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for v in consultor.consultoria.vinculos %}
|
||||
{% for v in consultor.consultoria.vinculos|sort_by_date('periodo.fim', 'periodo.inicio') %}
|
||||
<tr>
|
||||
<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>
|
||||
@@ -689,7 +689,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for a in consultor.avaliacoes_comissao %}
|
||||
{% for a in consultor.avaliacoes_comissao|sort_by_date('ano') %}
|
||||
<tr>
|
||||
<td>{{ a.codigo }}</td>
|
||||
<td>{{ a.tipo }}</td>
|
||||
@@ -715,7 +715,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for p in consultor.premiacoes %}
|
||||
{% for p in consultor.premiacoes|sort_by_date('ano') %}
|
||||
<tr>
|
||||
<td>{{ p.codigo }}</td>
|
||||
<td>{{ p.tipo }}</td>
|
||||
@@ -741,7 +741,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for i in consultor.inscricoes %}
|
||||
{% for i in consultor.inscricoes|sort_by_date('ano') %}
|
||||
<tr>
|
||||
<td>{{ i.codigo }}</td>
|
||||
<td>{{ i.tipo }}</td>
|
||||
@@ -768,7 +768,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for o in consultor.orientacoes %}
|
||||
{% for o in consultor.orientacoes|sort_by_date('ano') %}
|
||||
<tr>
|
||||
<td>{{ o.codigo }}</td>
|
||||
<td>{{ o.tipo }}</td>
|
||||
@@ -794,7 +794,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for b in consultor.membros_banca %}
|
||||
{% for b in consultor.membros_banca|sort_by_date('ano') %}
|
||||
<tr>
|
||||
<td>{{ b.codigo }}</td>
|
||||
<td>{{ b.tipo }}</td>
|
||||
@@ -818,7 +818,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for p in consultor.participacoes %}
|
||||
{% for p in consultor.participacoes|sort_by_date('ano') %}
|
||||
<tr>
|
||||
<td>{{ p.codigo }}</td>
|
||||
<td>{{ p.tipo }}</td>
|
||||
@@ -873,7 +873,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for a in atuacoes_raw %}
|
||||
{% for a in atuacoes_raw|sort_by_date('fim', 'inicio') %}
|
||||
<tr>
|
||||
<td>{{ a.tipo or '-' }}</td>
|
||||
<td>{{ a.descricao or a.nome or '-' }}</td>
|
||||
|
||||
Reference in New Issue
Block a user