F-03 está 40% implementado. O preview raw existe e funciona bem. O que
seria novo é sobrepor ao preview existente uma segunda linha de "interpretação" — indicando qual coluna mapeada seria o número, qual seria a série, e se o valor parsearia com sucesso.
This commit is contained in:
@@ -8,7 +8,8 @@
|
||||
"Bash(cargo metadata --no-deps --format-version 1)",
|
||||
"Bash(python3 -c \"import json,sys; d=json.load\\(sys.stdin\\); [print\\(p[''name''], p[''version'']\\) for p in d[''packages'']]\")",
|
||||
"WebFetch(domain:github.com)",
|
||||
"WebFetch(domain:api.github.com)"
|
||||
"WebFetch(domain:api.github.com)",
|
||||
"Bash(ls D:/PROJECTS/comparador-notas/*.md)"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
# F-03 — Preview Interpretado de Colunas
|
||||
|
||||
> Análise feita em 03/03/2026. O preview bruto já existe; este documento descreve apenas o que falta.
|
||||
|
||||
## O que já existe
|
||||
|
||||
A tela de configuração de colunas (`src/ui/screens/configuracao_colunas.rs`) exibe as primeiras 5 linhas do arquivo como uma tabela de dados brutos, com cabeçalhos A(0), B(1), C(2)... O preview é atualizado quando o delimitador muda (CSV).
|
||||
|
||||
- `app.preview_arquivo: Option<Vec<Vec<String>>>` — `src/ui/app.rs:131`
|
||||
- `renderizar_tabela_preview()` — `src/ui/screens/mod.rs:22`
|
||||
- Recálculo ao mudar delimitador — `src/ui/screens/configuracao_colunas.rs:165`
|
||||
|
||||
## O que falta implementar
|
||||
|
||||
### 1. Struct `LinhaPreview`
|
||||
|
||||
Resultado do parse tentativo de cada linha usando o layout atual.
|
||||
|
||||
```rust
|
||||
// src/application/usecases/pre_visualizar.rs (arquivo novo)
|
||||
pub struct LinhaPreview {
|
||||
pub numero: Result<u64, String>,
|
||||
pub serie: Result<String, String>,
|
||||
pub valor: Option<Result<rust_decimal::Decimal, String>>,
|
||||
pub data: Option<Result<String, String>>,
|
||||
pub documento_tipo: Option<Result<String, String>>,
|
||||
}
|
||||
|
||||
pub fn pre_visualizar_csv(
|
||||
caminho: &Path,
|
||||
layout: &LayoutCsv,
|
||||
n_linhas: usize,
|
||||
) -> Vec<LinhaPreview>
|
||||
|
||||
pub fn pre_visualizar_xlsx(
|
||||
caminho: &Path,
|
||||
layout: &LayoutXlsx,
|
||||
n_linhas: usize,
|
||||
) -> Vec<LinhaPreview>
|
||||
```
|
||||
|
||||
Internamente, reutiliza a lógica de parse já existente em `importar_csv` / `importar_xlsx`, mas sem abortar na primeira falha — retorna `Err(mensagem)` por campo.
|
||||
|
||||
---
|
||||
|
||||
### 2. Estado no `App`
|
||||
|
||||
```rust
|
||||
// src/ui/app.rs
|
||||
pub preview_interpretado: Option<Vec<LinhaPreview>>,
|
||||
```
|
||||
|
||||
Recalculado sempre que qualquer campo de configuração muda (não só o delimitador). Gatilhos em `configuracao_colunas.rs`:
|
||||
|
||||
- Mudança de delimitador (já atualiza preview bruto; adicionar aqui)
|
||||
- Mudança de encoding
|
||||
- Mudança de qualquer `DragValue` de índice (via `.changed()`)
|
||||
- Mudança de qualquer `text_edit` de posição XLSX (via `.changed()`)
|
||||
|
||||
---
|
||||
|
||||
### 3. Widget `renderizar_tabela_preview_interpretado`
|
||||
|
||||
Substitui ou complementa `renderizar_tabela_preview` na tela de configuração. Exibe uma tabela com colunas fixas pelos campos mapeados (Número, Série, Valor, Data, Tipo), não pelas colunas do arquivo.
|
||||
|
||||
Comportamento por célula:
|
||||
- `Ok(v)` → texto verde ou neutro com o valor parseado
|
||||
- `Err(msg)` → fundo vermelho claro, texto com o erro curto (ex: `"não é número"`)
|
||||
- Campo opcional não mapeado → célula vazia/cinza
|
||||
|
||||
```
|
||||
| Número | Série | Valor | Data | Tipo |
|
||||
|--------|-------|----------|------------|------|
|
||||
| 1001 | 001 | 1.250,00 | 2024-01-05 | |
|
||||
| ✗ "abc"| 001 | 980,50 | 2024-01-06 | |
|
||||
| 1003 | 001 | ✗ "" | 2024-01-07 | |
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Atualização reativa nos campos de índice
|
||||
|
||||
Atualmente, mudar um `DragValue` de índice não recalcula o preview. É necessário capturar `.changed()` em cada campo e disparar o recálculo.
|
||||
|
||||
Exemplo para CSV em `configuracao_colunas.rs`:
|
||||
|
||||
```rust
|
||||
let changed = campo_indice_rastreado(ui, "Número:", &mut app.layout_csv_atual.indice_numero);
|
||||
if changed {
|
||||
recalcular_preview_interpretado(app);
|
||||
}
|
||||
```
|
||||
|
||||
Alternativa mais simples: comparar o layout no início e no fim do frame e recalcular se diferente (evita modificar cada campo individualmente).
|
||||
|
||||
---
|
||||
|
||||
## Escopo de arquivos afetados
|
||||
|
||||
| Arquivo | Mudança |
|
||||
|---|---|
|
||||
| `src/application/usecases/pre_visualizar.rs` | Criar — lógica de parse tentativo |
|
||||
| `src/ui/app.rs` | Adicionar campo `preview_interpretado` |
|
||||
| `src/ui/screens/configuracao_colunas.rs` | Adicionar gatilhos de recálculo e chamar novo widget |
|
||||
| `src/ui/screens/mod.rs` | Adicionar `renderizar_tabela_preview_interpretado()` |
|
||||
|
||||
Não são necessárias novas dependências. O parse tentativo reutiliza funções já existentes nos readers.
|
||||
|
||||
---
|
||||
|
||||
## O que NÃO precisa mudar
|
||||
|
||||
- O preview bruto (`renderizar_tabela_preview`) pode ser mantido ou removido — a tabela interpretada é mais informativa.
|
||||
- Nenhuma mudança em domínio, banco ou PDF.
|
||||
- O fluxo de importação real não é alterado.
|
||||
|
||||
---
|
||||
|
||||
## Esforço reavaliado
|
||||
|
||||
O backlog estimava 4–6h. Com o preview bruto já existindo e a lógica de parse já implementada nos readers, o esforço real é de **2–3h**:
|
||||
|
||||
- 45min — `pre_visualizar.rs` (reutiliza lógica dos readers)
|
||||
- 30min — estado no `App` + gatilhos de recálculo
|
||||
- 1h — widget `renderizar_tabela_preview_interpretado`
|
||||
- 30min — testes e ajustes visuais
|
||||
Reference in New Issue
Block a user