feat: adiciona modal para salvar layout com campo de texto e botão na tela de configuração de colunas

This commit is contained in:
FelipeCN
2026-03-03 09:19:23 -03:00
parent b2b91cda55
commit 0f728b9684
2 changed files with 73 additions and 1 deletions
+69 -1
View File
@@ -50,6 +50,8 @@ pub struct Modal {
pub tipo: TipoModal,
/// Para modal de confirmação, a ação ao confirmar.
pub acao_confirmacao: Option<AcaoModal>,
/// Para modal com campo de texto (InputTexto).
pub input_texto: String,
}
#[derive(Default, Clone, PartialEq)]
@@ -59,6 +61,8 @@ pub enum TipoModal {
Aviso,
Erro,
Confirmacao,
/// Modal com campo de texto para entrada do usuário.
InputTexto,
}
#[derive(Clone)]
@@ -67,6 +71,8 @@ pub enum AcaoModal {
ConfirmarExclusaoLayout(i64),
SobrescreverLayout,
ConfirmarNovaAnalise,
/// Salvar a configuração atual como novo layout, usando modal.input_texto como nome.
SalvarLayoutConfig,
}
/// Struct principal da aplicação egui.
@@ -176,6 +182,7 @@ impl App {
mensagem: msg.into(),
tipo: TipoModal::Erro,
acao_confirmacao: None,
input_texto: String::new(),
};
}
@@ -186,6 +193,7 @@ impl App {
mensagem: msg.into(),
tipo: TipoModal::Aviso,
acao_confirmacao: None,
input_texto: String::new(),
};
}
@@ -201,10 +209,23 @@ impl App {
mensagem: msg.into(),
tipo: TipoModal::Confirmacao,
acao_confirmacao: Some(acao),
input_texto: String::new(),
};
}
/// Recarrega a lista de layouts do banco.
/// Exibe modal com campo de texto para salvar o layout atual como novo preset.
pub fn exibir_modal_salvar_layout(&mut self) {
self.modal = Modal {
visivel: true,
titulo: "Salvar como layout...".to_string(),
mensagem: "Nome do layout:".to_string(),
tipo: TipoModal::InputTexto,
acao_confirmacao: Some(AcaoModal::SalvarLayoutConfig),
input_texto: self.nome_layout_atual.clone(),
};
}
pub fn recarregar_layouts(&mut self) {
if let Some(conn) = &self.conn {
match listar_layouts(conn) {
@@ -228,14 +249,26 @@ impl App {
egui::Window::new(&titulo)
.collapsible(false)
.resizable(false)
.min_width(320.0)
.anchor(egui::Align2::CENTER_CENTER, [0.0, 0.0])
.show(ctx, |ui| {
ui.add_space(8.0);
ui.label(&mensagem);
if tipo == TipoModal::InputTexto {
ui.add_space(4.0);
let resp = ui.add(
egui::TextEdit::singleline(&mut self.modal.input_texto)
.desired_width(280.0)
.hint_text("Nome do layout"),
);
resp.request_focus();
}
ui.add_space(12.0);
ui.horizontal(|ui| {
if tipo == TipoModal::Confirmacao {
if tipo == TipoModal::Confirmacao || tipo == TipoModal::InputTexto {
if ui.button("✔ Confirmar").clicked() {
self.modal.visivel = false;
if let Some(acao) = acao.clone() {
@@ -244,6 +277,7 @@ impl App {
}
if ui.button("✖ Cancelar").clicked() {
self.modal.visivel = false;
self.modal.input_texto.clear();
}
} else {
if ui.button("OK").clicked() {
@@ -279,6 +313,40 @@ impl App {
self.notas_importadas.clear();
self.estado = EstadoApp::Importando;
}
AcaoModal::SalvarLayoutConfig => {
let nome = self.modal.input_texto.trim().to_string();
self.modal.input_texto.clear();
if nome.is_empty() {
self.exibir_erro("O nome do layout não pode ser vazio.");
return;
}
let layout = match &self.tipo_arquivo_atual {
TipoArquivo::Csv => Layout::Csv {
id: None,
nome: nome.clone(),
config: self.layout_csv_atual.clone(),
},
TipoArquivo::Xlsx => Layout::Xlsx {
id: None,
nome: nome.clone(),
config: self.layout_xlsx_atual.clone(),
},
};
let resultado = if let Some(conn) = &self.conn {
Some(salvar_layout(conn, &layout))
} else {
None
};
match resultado {
Some(Ok(_)) => {
self.nome_layout_atual = nome;
self.recarregar_layouts();
self.exibir_aviso("Layout salvo", "Layout salvo com sucesso.");
}
Some(Err(e)) => self.exibir_erro(e),
None => {}
}
}
}
}
+4
View File
@@ -88,6 +88,10 @@ pub fn renderizar(ui: &mut Ui, ctx: &Context, app: &mut App) {
executar_importacao(app);
}
});
if ui.button("💾 Salvar como layout...").clicked() {
app.exibir_modal_salvar_layout();
}
});
}