From edebbee9e7e9efbb33bf709b637c103be40d15a8 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Thu, 9 May 2024 19:00:55 +0100 Subject: [PATCH] feat: Display upload errors in UIWindowProgress dialog The object returned from UIWindowProgress() now has a `show_error()` method, taking a title and message. Calling it will replace the content of the window with those messages. I've made use of this for file uploads. The only other place we currently have errors we could show is for zipping and downloading files, but we do not always have a progress dialog in that case, so I'll leave that for now. I think ideally, we would always create a progress dialog, and it would then support being invisible initially, but appearing after a delay. Then we'd always have an object to call `show_error()` on, and it could then immediately show the dialog. But I'll get to that another day. :^) --- src/UI/UIWindowProgress.js | 68 ++++++++++++++++++++++++++----------- src/helpers.js | 4 +-- src/i18n/translations/en.js | 1 + 3 files changed, 51 insertions(+), 22 deletions(-) diff --git a/src/UI/UIWindowProgress.js b/src/UI/UIWindowProgress.js index 85dc5da9..3f111858 100644 --- a/src/UI/UIWindowProgress.js +++ b/src/UI/UIWindowProgress.js @@ -26,9 +26,8 @@ import Button from './Components/Button.js'; * @param operation_id If provided, is saved in the data-operation-id attribute, for later lookup. * @param show_progress Enable a progress bar, and display `(foo%)` after the status message * @param on_cancel A callback run when the Cancel button is clicked. Without it, no Cancel button will appear. - * @returns {Promise<{set_progress: *, set_status: *, close: *, element: Element}>} Object for managing the progress dialog + * @returns {Promise<{set_progress: *, set_status: *, close: *, show_error: *, element: Element}>} Object for managing the progress dialog * @constructor - * TODO: Error display * TODO: Debouncing logic (show only after a delay, then hide only after a delay) */ async function UIWindowProgress({ @@ -37,30 +36,47 @@ async function UIWindowProgress({ on_cancel = null, } = {}){ const placeholder_cancel_btn = Placeholder(); + const placeholder_ok_btn = Placeholder(); let h = ''; h += `
`; - h += `
`; - // spinner - h += `circle anim`; - // Progress report - h += `
- ${i18n('preparing')}`; + h += `
`; + h += `
`; + // spinner + h += `circle anim`; + // Progress report + h += `
+ ${i18n('preparing')}`; + if (show_progress) { + h += ` (0%)`; + } + h += `
`; + h +=`
`; if (show_progress) { - h += ` (0%)`; + h += `
`; + h += `
`; + h += `
`; } + if (on_cancel) { + h += `
`; + h += placeholder_cancel_btn.html; + h += `
`; + } + h += `
`; + h += ``; - if (show_progress) { - h += `
`; - h += `
`; - h += `
`; - } - if (on_cancel) { + h += `

`; h += `
`; - h += placeholder_cancel_btn.html; + h += placeholder_ok_btn.html; h += `
`; - } + h += `
`; h += `
`; const el_window = await UIWindow({ @@ -106,6 +122,15 @@ async function UIWindowProgress({ cancel_btn.attach(placeholder_cancel_btn); } + const ok_btn = new Button({ + label: i18n('ok'), + style: 'small', + on_click: () => { + $(el_window).close(); + }, + }); + ok_btn.attach(placeholder_ok_btn); + return { element: el_window, set_status: (text) => { @@ -118,7 +143,12 @@ async function UIWindowProgress({ close: () => { $(el_window).close(); }, - // TODO: show_error(), which replaces the window content with a title, error message, and OK button + show_error: (title, message) => { + el_window.querySelector('.progress-running').style.display = 'none'; + el_window.querySelector('.progress-error').style.display = 'block'; + el_window.querySelector('.progress-error-title').innerText = title; + el_window.querySelector('.progress-error-message').innerText = message; + }, }; } diff --git a/src/helpers.js b/src/helpers.js index 77c8abe3..f4e3d134 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -2771,9 +2771,7 @@ window.upload_items = async function(items, dest_path){ }, // error error: async function(err){ - // TODO: Display error in progress dialog - upload_progress_window.close(); - // UIAlert(err?.message ?? 'An error occurred while uploading.'); + upload_progress_window.show_error(i18n('error_uploading_files'), err.message); // remove from active_uploads delete window.active_uploads[opid]; }, diff --git a/src/i18n/translations/en.js b/src/i18n/translations/en.js index 14ca930f..ad2abc47 100644 --- a/src/i18n/translations/en.js +++ b/src/i18n/translations/en.js @@ -114,6 +114,7 @@ const en = { enlarged_qr_code: "Enlarged QR Code", enter_password_to_confirm_delete_user: "Enter your password to confirm account deletion", error_unknown_cause: "An unknown error occurred.", + error_uploading_files: "Failed to upload files", feedback: "Feedback", feedback_c2a: "Please use the form below to send us your feedback, comments, and bug reports.", feedback_sent_confirmation: "Thank you for contacting us. If you have an email associated with your account, you will hear back from us as soon as possible.",