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.",