From 8dfcc4f5e8e6cb04dbc3bb8d3561f43b99224d3a Mon Sep 17 00:00:00 2001 From: Akinator31 Date: Tue, 2 Dec 2025 14:43:47 +0100 Subject: [PATCH] refactor(panel): make the 'save configuration' button float --- .../src/components/configuration.rs | 116 +++++++++++++++--- rustmail_panel/src/i18n/en/en.json | 3 + rustmail_panel/src/i18n/fr/fr.json | 3 + 3 files changed, 102 insertions(+), 20 deletions(-) diff --git a/rustmail_panel/src/components/configuration.rs b/rustmail_panel/src/components/configuration.rs index d3e2e2dc..12232e11 100644 --- a/rustmail_panel/src/components/configuration.rs +++ b/rustmail_panel/src/components/configuration.rs @@ -18,7 +18,8 @@ pub fn configuration_page() -> Html { let show_restart_modal = use_state(|| false); let save_message = use_state(|| None::<(bool, String)>); - let expanded_sections = use_state(|| vec![true, false, false, false, false, false, false, false]); + let expanded_sections = + use_state(|| vec![true, false, false, false, false, false, false, false]); let permissions = use_state(|| None::>); { @@ -120,21 +121,35 @@ pub fn configuration_page() -> Html { let show_restart_modal = show_restart_modal.clone(); let save_message = save_message.clone(); let i18n = i18n.clone(); + let config = config.clone(); Callback::from(move |new_config: ConfigResponse| { let show_restart_modal = show_restart_modal.clone(); let save_message = save_message.clone(); let i18n = i18n.clone(); + let config = config.clone(); spawn_local(async move { match Request::put("/api/bot/config").json(&new_config) { Ok(req) => match req.send().await { Ok(resp) => { if resp.ok() { - save_message.set(Some((true, i18n.t("panel.configuration.save_success")))); + save_message + .set(Some((true, i18n.t("panel.configuration.save_success")))); show_restart_modal.set(true); + if let Ok(resp) = Request::get("/api/bot/config").send().await { + if resp.ok() { + if let Ok(config_data) = resp.json::().await + { + config.set(Some(config_data)); + } + } + } } else { - let error_msg = resp.text().await.unwrap_or_else(|_| "Erreur inconnue".to_string()); + let error_msg = resp + .text() + .await + .unwrap_or_else(|_| "Erreur inconnue".to_string()); save_message.set(Some((false, error_msg))); } } @@ -334,8 +349,24 @@ struct ConfigFormProps { fn config_form(props: &ConfigFormProps) -> Html { let (i18n, _set_language) = use_translation(); let config = use_state(|| props.config.clone()); + let is_saving = use_state(|| false); + + let has_changes = *config != props.config; + let original_config = props.config.clone(); + + { + let is_saving = is_saving.clone(); + let config_matches = *config == props.config; + use_effect_with(config_matches, move |matches| { + if *matches { + is_saving.set(false); + } + || () + }); + } html! { + <>
Html { > +
-
- -

- {i18n.t("panel.configuration.save_help")} -

-
- + +
+ +
+ +
+ + } + } else { + html! {} + }} + } } @@ -502,7 +575,10 @@ struct TextInputProps { #[function_component(TextInput)] fn text_input(props: &TextInputProps) -> Html { - let input_type = props.input_type.clone().unwrap_or_else(|| "text".to_string()); + let input_type = props + .input_type + .clone() + .unwrap_or_else(|| "text".to_string()); let placeholder = props.placeholder.clone().unwrap_or_default(); html! { diff --git a/rustmail_panel/src/i18n/en/en.json b/rustmail_panel/src/i18n/en/en.json index 15252c34..a4cc125d 100644 --- a/rustmail_panel/src/i18n/en/en.json +++ b/rustmail_panel/src/i18n/en/en.json @@ -121,6 +121,9 @@ "save": "Save Configuration", "save_help": "A backup will be automatically created before saving", "save_success": "Configuration saved!", + "reset": "Reset", + "unsaved_changes": "Unsaved changes", + "save_button": "Save", "loading": "Loading...", "load_error": "Unable to load configuration", "restart_modal": { diff --git a/rustmail_panel/src/i18n/fr/fr.json b/rustmail_panel/src/i18n/fr/fr.json index 0ed4e677..1d0ff5ae 100644 --- a/rustmail_panel/src/i18n/fr/fr.json +++ b/rustmail_panel/src/i18n/fr/fr.json @@ -121,6 +121,9 @@ "save": "Sauvegarder la Configuration", "save_help": "Un backup sera automatiquement créé avant la sauvegarde", "save_success": "Configuration sauvegardée !", + "reset": "Réinitialiser", + "unsaved_changes": "Modifications non sauvegardées", + "save_button": "Sauvegarder", "loading": "Chargement...", "load_error": "Impossible de charger la configuration", "restart_modal": {