From 43610de5713851406e0a1ff461e068521e27d94c Mon Sep 17 00:00:00 2001 From: Bastian Allgeier Date: Thu, 5 Dec 2024 10:12:54 +0100 Subject: [PATCH 1/7] Fix the footer attribute if the cancel button prop is not a boolean --- panel/src/components/Dialogs/Dialog.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panel/src/components/Dialogs/Dialog.vue b/panel/src/components/Dialogs/Dialog.vue index 4eb339646f..88966fd328 100644 --- a/panel/src/components/Dialogs/Dialog.vue +++ b/panel/src/components/Dialogs/Dialog.vue @@ -7,7 +7,7 @@ $vnode.data.staticClass, $attrs.class ]" - :data-has-footer="cancelButton || submitButton" + :data-has-footer="Boolean(cancelButton || submitButton)" :data-size="size" method="dialog" @click.stop From 19aadb61b5650e8c626e86e7ad625a54a0cc382c Mon Sep 17 00:00:00 2001 From: Bastian Allgeier Date: Thu, 5 Dec 2024 10:13:11 +0100 Subject: [PATCH 2/7] New content.retry and content.closeRetryDialog methods --- panel/src/panel/content.js | 59 +++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/panel/src/panel/content.js b/panel/src/panel/content.js index e3b4ddaf15..eb4226efc4 100644 --- a/panel/src/panel/content.js +++ b/panel/src/panel/content.js @@ -34,6 +34,18 @@ export default (panel) => { return changes; }, + /** + * Closes the retry dialog if it is still open + */ + closeRetryDialog() { + if ( + panel.dialog.isOpen && + panel.dialog.props.id === "content-retry-dialog" + ) { + panel.dialog.close(); + } + }, + /** * Removes all unpublished changes */ @@ -145,17 +157,59 @@ export default (panel) => { try { await panel.api.post(api + "/changes/publish", values); + // close the retry dialog if it is still open + this.closeRetryDialog(); + // update the props for the current view if (this.isCurrent(api)) { panel.view.props.originals = panel.view.props.content; } panel.events.emit("content.publish", { values, api }); + } catch (error) { + this.retry("publish", error, panel.view.props.content, api); } finally { this.isProcessing = false; } }, + /** + * Opens a dialog with the error message + * to retry the given method. + */ + retry(method, error, values, api) { + // log the error to the console to make it + // easier to debug the issue + console.error(error); + + // show a dialog to the user to try again + panel.dialog.open({ + component: "k-text-dialog", + props: { + id: "content-retry-dialog", + text: panel.t(`form.${method}.error`), + cancelButton: panel.t("close"), + submitButton: { + icon: "refresh", + text: panel.t("retry") + } + }, + on: { + submit: async () => { + panel.dialog.isLoading = true; + + // try again with the latest state in the props + await this.save(panel.view.props.content, api); + + panel.dialog.isLoading = true; + + // give a more reassuring longer success notification + panel.notification.success(panel.t(`form.${method}.success`)); + } + } + }); + }, + /** * Saves any changes */ @@ -181,6 +235,9 @@ export default (panel) => { this.isProcessing = false; + // close the retry dialog if it is still open + this.closeRetryDialog(); + // update the lock timestamp if (this.isCurrent(api) === true) { panel.view.props.lock.modified = new Date(); @@ -191,7 +248,7 @@ export default (panel) => { // silent aborted requests, but throw all other errors if (error.name !== "AbortError") { this.isProcessing = false; - throw error; + this.retry("save", error, panel.view.props.content, api); } } }, From 803d000cebe66cd0d2003addfbfaa93c4efdc6cb Mon Sep 17 00:00:00 2001 From: Bastian Allgeier Date: Thu, 5 Dec 2024 10:13:45 +0100 Subject: [PATCH 3/7] New translation strings for the retry dialog --- i18n/translations/en.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/i18n/translations/en.json b/i18n/translations/en.json index 71c9747425..dfd99d62e6 100644 --- a/i18n/translations/en.json +++ b/i18n/translations/en.json @@ -383,8 +383,12 @@ "form.discard.confirm": "Do you really want to discard all your changes?", "form.locked": "This content is disabled for you as it is currently edited by another user", "form.unsaved": "The current changes have not yet been saved", + "form.save.error": "Your changes could not be saved.", + "form.save.success": "Your changes have been saved", "form.preview": "Preview changes", "form.preview.draft": "Preview draft", + "form.publish.error": "Your changes could not be published.", + "form.publish.success": "Your changes have been published", "hide": "Hide", "hour": "Hour", From 4e16f4962ef7747bbca151cbc6febf6a9688b0b1 Mon Sep 17 00:00:00 2001 From: Bastian Allgeier Date: Thu, 5 Dec 2024 14:45:58 +0100 Subject: [PATCH 4/7] Disable isLoading state after request --- panel/src/panel/content.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panel/src/panel/content.js b/panel/src/panel/content.js index eb4226efc4..8557becc06 100644 --- a/panel/src/panel/content.js +++ b/panel/src/panel/content.js @@ -201,7 +201,7 @@ export default (panel) => { // try again with the latest state in the props await this.save(panel.view.props.content, api); - panel.dialog.isLoading = true; + panel.dialog.isLoading = false; // give a more reassuring longer success notification panel.notification.success(panel.t(`form.${method}.success`)); From 3c84509f369a9135a0284574d1d60613e0b3325c Mon Sep 17 00:00:00 2001 From: Bastian Allgeier Date: Thu, 5 Dec 2024 14:58:43 +0100 Subject: [PATCH 5/7] Simplify dialog setup --- panel/src/panel/content.js | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/panel/src/panel/content.js b/panel/src/panel/content.js index 8557becc06..6e6b7ef324 100644 --- a/panel/src/panel/content.js +++ b/panel/src/panel/content.js @@ -34,17 +34,7 @@ export default (panel) => { return changes; }, - /** - * Closes the retry dialog if it is still open - */ - closeRetryDialog() { - if ( - panel.dialog.isOpen && - panel.dialog.props.id === "content-retry-dialog" - ) { - panel.dialog.close(); - } - }, + dialog: null, /** * Removes all unpublished changes @@ -158,7 +148,7 @@ export default (panel) => { await panel.api.post(api + "/changes/publish", values); // close the retry dialog if it is still open - this.closeRetryDialog(); + this.dialog?.close(); // update the props for the current view if (this.isCurrent(api)) { @@ -182,8 +172,11 @@ export default (panel) => { // easier to debug the issue console.error(error); + // set the dialog instance + this.dialog = panel.dialog; + // show a dialog to the user to try again - panel.dialog.open({ + this.dialog.open({ component: "k-text-dialog", props: { id: "content-retry-dialog", @@ -195,13 +188,17 @@ export default (panel) => { } }, on: { + close: () => { + this.dialog = null; + }, submit: async () => { - panel.dialog.isLoading = true; + this.dialog.isLoading = true; // try again with the latest state in the props await this.save(panel.view.props.content, api); - panel.dialog.isLoading = false; + // make sure the dialog is closed if the request was successful + this.dialog?.close(); // give a more reassuring longer success notification panel.notification.success(panel.t(`form.${method}.success`)); @@ -236,7 +233,7 @@ export default (panel) => { this.isProcessing = false; // close the retry dialog if it is still open - this.closeRetryDialog(); + this.dialog?.close(); // update the lock timestamp if (this.isCurrent(api) === true) { From e15c4abe596c3895702dd1eae81e3aec2394465d Mon Sep 17 00:00:00 2001 From: Bastian Allgeier Date: Thu, 5 Dec 2024 14:59:43 +0100 Subject: [PATCH 6/7] Remove unnecessary id --- panel/src/panel/content.js | 1 - 1 file changed, 1 deletion(-) diff --git a/panel/src/panel/content.js b/panel/src/panel/content.js index 6e6b7ef324..0a4b357d7f 100644 --- a/panel/src/panel/content.js +++ b/panel/src/panel/content.js @@ -179,7 +179,6 @@ export default (panel) => { this.dialog.open({ component: "k-text-dialog", props: { - id: "content-retry-dialog", text: panel.t(`form.${method}.error`), cancelButton: panel.t("close"), submitButton: { From 4e99614b5201b1b5c4c23d1c8c5011bc63479315 Mon Sep 17 00:00:00 2001 From: Bastian Allgeier Date: Thu, 5 Dec 2024 16:19:59 +0100 Subject: [PATCH 7/7] Use the right method --- panel/src/panel/content.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panel/src/panel/content.js b/panel/src/panel/content.js index 0a4b357d7f..a01261cc44 100644 --- a/panel/src/panel/content.js +++ b/panel/src/panel/content.js @@ -194,7 +194,7 @@ export default (panel) => { this.dialog.isLoading = true; // try again with the latest state in the props - await this.save(panel.view.props.content, api); + await this[method](panel.view.props.content, api); // make sure the dialog is closed if the request was successful this.dialog?.close();