From eb8bbd53395375037cce39f2393a744e387ab14f Mon Sep 17 00:00:00 2001 From: Marius Vollmer Date: Wed, 23 Oct 2024 11:04:20 +0300 Subject: [PATCH] storage: Scroll dialog fields into view as needed When fields fail validation, the first of them is scrolled into view at the top of the dialog. Additionally, when the encryption fields of the Format dialog are revealed, they are scrolled into view. https://bugzilla.redhat.com/show_bug.cgi?id=2264540 --- pkg/storaged/block/format-dialog.jsx | 3 +++ pkg/storaged/dialog.jsx | 25 ++++++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/pkg/storaged/block/format-dialog.jsx b/pkg/storaged/block/format-dialog.jsx index feaad1845cad..867f8719ee99 100644 --- a/pkg/storaged/block/format-dialog.jsx +++ b/pkg/storaged/block/format-dialog.jsx @@ -392,6 +392,9 @@ function format_dialog_internal(client, path, start, size, enable_dos_extended, } if (vals.type == "efi" && !vals.mount_point) dlg.set_values({ mount_point: "/boot/efi" }); + } else if (trigger == "crypto") { + if (vals.crypto != "none" && vals.crypto != " keep") + dlg.show_field("crypto_options"); } }, Action: { diff --git a/pkg/storaged/dialog.jsx b/pkg/storaged/dialog.jsx index 08bfcaf5f19f..84f4012c8ff6 100644 --- a/pkg/storaged/dialog.jsx +++ b/pkg/storaged/dialog.jsx @@ -513,7 +513,16 @@ export const dialog_open = (def) => { return null; })).then(results => { const errors = { }; - fields.forEach((f, i) => { if (results[i]) errors[f.tag] = results[i]; }); + let scrolled = false; + fields.forEach((f, i) => { + if (results[i]) { + if (!scrolled) { + show_field(f.tag); + scrolled = true; + } + errors[f.tag] = results[i]; + } + }); if (Object.keys(errors).length > 0) return Promise.reject(errors); }); @@ -521,6 +530,18 @@ export const dialog_open = (def) => { const dlg = show_modal_dialog(props(), footer_props(null, null)); + function show_field(tag) { + function scroll() { + const field_element = document.querySelector('#dialog [data-field="' + tag + '"]'); + if (field_element) + field_element.scrollIntoView({ behavior: "smooth", block: "nearest" }); + } + // By the time show_field is called from the "update" + // callback, newly visible fields don't exist yet in the + // DOM, so delay the scrolling a bit. + window.setTimeout(scroll, 10); + } + const self = { run: (title, promise) => { update_footer(title, promise); @@ -593,6 +614,8 @@ export const dialog_open = (def) => { update_footer(); }, + show_field: show_field, + close: () => { dlg.footerProps.dialog_done(); }