feat: adiciona nova ação de confirmação para iniciar nova análise e implementa breadcrumb na interface
This commit is contained in:
@@ -66,6 +66,7 @@ pub enum AcaoModal {
|
|||||||
ConfirmarExpansaoFaltantes,
|
ConfirmarExpansaoFaltantes,
|
||||||
ConfirmarExclusaoLayout(i64),
|
ConfirmarExclusaoLayout(i64),
|
||||||
SobrescreverLayout,
|
SobrescreverLayout,
|
||||||
|
ConfirmarNovaAnalise,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Struct principal da aplicação egui.
|
/// Struct principal da aplicação egui.
|
||||||
@@ -274,6 +275,10 @@ impl App {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
AcaoModal::SobrescreverLayout => {} // Handled inline in layouts screen
|
AcaoModal::SobrescreverLayout => {} // Handled inline in layouts screen
|
||||||
|
AcaoModal::ConfirmarNovaAnalise => {
|
||||||
|
self.notas_importadas.clear();
|
||||||
|
self.estado = EstadoApp::Importando;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,11 +321,47 @@ impl App {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl App {
|
||||||
|
/// Renderiza o breadcrumb de etapas no topo (exceto na tela de layouts).
|
||||||
|
pub fn renderizar_breadcrumb(&self, ctx: &Context) {
|
||||||
|
let passo_ativo: usize = match self.tela_atual() {
|
||||||
|
0 | 1 => 1,
|
||||||
|
2 | 4 => 2,
|
||||||
|
3 => 3,
|
||||||
|
_ => return, // GerenciandoLayouts: sem breadcrumb
|
||||||
|
};
|
||||||
|
|
||||||
|
egui::TopBottomPanel::top("breadcrumb").show(ctx, |ui| {
|
||||||
|
ui.add_space(4.0);
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
for (i, label) in ["① Arquivo", "② Colunas", "③ Resultado"].iter().enumerate() {
|
||||||
|
let n = i + 1;
|
||||||
|
let texto = egui::RichText::new(*label);
|
||||||
|
if n == passo_ativo {
|
||||||
|
ui.label(texto.strong());
|
||||||
|
} else if n < passo_ativo {
|
||||||
|
ui.label(texto);
|
||||||
|
} else {
|
||||||
|
ui.label(texto.weak());
|
||||||
|
}
|
||||||
|
if n < 3 {
|
||||||
|
ui.label(egui::RichText::new(" ›").weak());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ui.add_space(4.0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl eframe::App for App {
|
impl eframe::App for App {
|
||||||
fn update(&mut self, ctx: &Context, _frame: &mut eframe::Frame) {
|
fn update(&mut self, ctx: &Context, _frame: &mut eframe::Frame) {
|
||||||
// Sempre renderizar modal por cima de tudo
|
// Sempre renderizar modal por cima de tudo
|
||||||
self.renderizar_modal(ctx);
|
self.renderizar_modal(ctx);
|
||||||
|
|
||||||
|
// Breadcrumb de etapas no topo
|
||||||
|
self.renderizar_breadcrumb(ctx);
|
||||||
|
|
||||||
// Determinar qual tela exibir sem borrar self.estado
|
// Determinar qual tela exibir sem borrar self.estado
|
||||||
let tela_id = self.tela_atual();
|
let tela_id = self.tela_atual();
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::application::usecases::importar_arquivo::{importar_csv, importar_xlsx};
|
use crate::application::usecases::importar_arquivo::{importar_csv, importar_xlsx};
|
||||||
use crate::domain::entities::layout::TipoArquivo;
|
use crate::domain::entities::layout::{Layout, TipoArquivo};
|
||||||
use crate::ui::app::{App, EstadoApp};
|
use crate::ui::app::{App, EstadoApp};
|
||||||
use egui::{Context, Ui};
|
use egui::{Context, Ui};
|
||||||
|
|
||||||
@@ -12,6 +12,51 @@ pub fn renderizar(ui: &mut Ui, ctx: &Context, app: &mut App) {
|
|||||||
ui.label(format!("Arquivo: {}", caminho.display()));
|
ui.label(format!("Arquivo: {}", caminho.display()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ui.add_space(8.0);
|
||||||
|
|
||||||
|
// Seletor de layout
|
||||||
|
let tipo_atual = app.tipo_arquivo_atual.clone();
|
||||||
|
let opcoes_layout: Vec<(i64, String)> = app
|
||||||
|
.layouts_salvos
|
||||||
|
.iter()
|
||||||
|
.filter(|l| l.tipo() == tipo_atual)
|
||||||
|
.filter_map(|l| l.id().map(|id| (id, l.nome().to_string())))
|
||||||
|
.collect();
|
||||||
|
let nome_layout_atual = app.nome_layout_atual.clone();
|
||||||
|
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.label("Layout:");
|
||||||
|
egui::ComboBox::from_id_salt("combo_layouts_config")
|
||||||
|
.selected_text(if nome_layout_atual.is_empty() {
|
||||||
|
"— Selecionar layout —"
|
||||||
|
} else {
|
||||||
|
&nome_layout_atual
|
||||||
|
})
|
||||||
|
.show_ui(ui, |ui| {
|
||||||
|
for (id, nome) in &opcoes_layout {
|
||||||
|
if ui
|
||||||
|
.selectable_label(nome_layout_atual == *nome, nome.as_str())
|
||||||
|
.clicked()
|
||||||
|
{
|
||||||
|
app.nome_layout_atual = nome.clone();
|
||||||
|
if let Some(layout) =
|
||||||
|
app.layouts_salvos.iter().find(|l| l.id() == Some(*id))
|
||||||
|
{
|
||||||
|
let layout = layout.clone();
|
||||||
|
match &layout {
|
||||||
|
Layout::Csv { config, .. } => {
|
||||||
|
app.layout_csv_atual = config.clone();
|
||||||
|
}
|
||||||
|
Layout::Xlsx { config, .. } => {
|
||||||
|
app.layout_xlsx_atual = config.clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
ui.add_space(12.0);
|
ui.add_space(12.0);
|
||||||
|
|
||||||
match app.tipo_arquivo_atual.clone() {
|
match app.tipo_arquivo_atual.clone() {
|
||||||
|
|||||||
+12
-10
@@ -4,7 +4,7 @@ use crate::domain::{
|
|||||||
services::parser_monetario::formatar_valor_br,
|
services::parser_monetario::formatar_valor_br,
|
||||||
};
|
};
|
||||||
use crate::infrastructure::pdf_generator::GenpdfGenerator;
|
use crate::infrastructure::pdf_generator::GenpdfGenerator;
|
||||||
use crate::ui::app::{App, EstadoApp};
|
use crate::ui::app::{AcaoModal, App, EstadoApp};
|
||||||
use egui::{Context, Ui};
|
use egui::{Context, Ui};
|
||||||
|
|
||||||
const OPCOES_PAGINA: &[usize] = &[50, 100, 200, 1000];
|
const OPCOES_PAGINA: &[usize] = &[50, 100, 200, 1000];
|
||||||
@@ -22,9 +22,11 @@ pub fn renderizar(ui: &mut Ui, ctx: &Context, app: &mut App) {
|
|||||||
|
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
if ui.button("< Nova Análise").clicked() {
|
if ui.button("< Nova Análise").clicked() {
|
||||||
app.estado = EstadoApp::Importando;
|
app.exibir_confirmacao(
|
||||||
app.notas_importadas.clear();
|
"Nova Análise",
|
||||||
return;
|
"Deseja iniciar uma nova análise? O resultado atual será descartado.",
|
||||||
|
AcaoModal::ConfirmarNovaAnalise,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ui.button("⚙ Reconfigurar Colunas").clicked() {
|
if ui.button("⚙ Reconfigurar Colunas").clicked() {
|
||||||
@@ -58,12 +60,6 @@ pub fn renderizar(ui: &mut Ui, ctx: &Context, app: &mut App) {
|
|||||||
ui.separator();
|
ui.separator();
|
||||||
|
|
||||||
egui::ScrollArea::vertical().show(ui, |ui| {
|
egui::ScrollArea::vertical().show(ui, |ui| {
|
||||||
// Totais
|
|
||||||
renderizar_totais(ui, &resultado);
|
|
||||||
|
|
||||||
ui.add_space(12.0);
|
|
||||||
ui.separator();
|
|
||||||
|
|
||||||
// Faltantes
|
// Faltantes
|
||||||
renderizar_faltantes(ui, app, &resultado);
|
renderizar_faltantes(ui, app, &resultado);
|
||||||
|
|
||||||
@@ -72,6 +68,12 @@ pub fn renderizar(ui: &mut Ui, ctx: &Context, app: &mut App) {
|
|||||||
|
|
||||||
// Duplicatas
|
// Duplicatas
|
||||||
renderizar_duplicatas(ui, app, &resultado);
|
renderizar_duplicatas(ui, app, &resultado);
|
||||||
|
|
||||||
|
ui.add_space(12.0);
|
||||||
|
ui.separator();
|
||||||
|
|
||||||
|
// Totais
|
||||||
|
renderizar_totais(ui, &resultado);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user