From 1678db78365a8442fa23654315e7f9d79053c240 Mon Sep 17 00:00:00 2001 From: dante di domenico Date: Wed, 19 Mar 2025 16:49:42 +0100 Subject: [PATCH 1/4] feat: centralize api error handling --- .../object-captions/object-captions.vue | 4 ++-- .../components/relation-view/relation-view.vue | 10 +++------- resources/js/app/helpers/view.js | 16 ++++++++++++++++ resources/js/app/pages/admin/appearance.vue | 4 ++-- resources/js/app/pages/modules/view.vue | 15 ++++++++------- 5 files changed, 31 insertions(+), 18 deletions(-) diff --git a/resources/js/app/components/object-captions/object-captions.vue b/resources/js/app/components/object-captions/object-captions.vue index 681bc3c3b..c388d170d 100644 --- a/resources/js/app/components/object-captions/object-captions.vue +++ b/resources/js/app/components/object-captions/object-captions.vue @@ -603,13 +603,13 @@ export default { const response = await fetch(`${BEDITA.base}/api/${this.objectType}/${this.objectId}`, options); const responseJson = await response.json(); if (responseJson.error) { - BEDITA.error(responseJson.error); + this.$helpers.handleApiError(responseJson); } else { const captions = responseJson.data.attributes.captions || []; this.reset(captions); } } catch (error) { - BEDITA.error(error); + this.$helpers.handleApiError(error); } finally { this.loading = false; } diff --git a/resources/js/app/components/relation-view/relation-view.vue b/resources/js/app/components/relation-view/relation-view.vue index 0d9f30055..84cd86c40 100644 --- a/resources/js/app/components/relation-view/relation-view.vue +++ b/resources/js/app/components/relation-view/relation-view.vue @@ -719,7 +719,7 @@ export default { body: JSON.stringify({ data: toRemove }), }); if (response?.error) { - BEDITA.error(response.error?.title || response?.error); + this.$helpers.handleApiError(response); } else { this.removedRelated = []; this.prepareRelationsToRemove(this.removedRelated); @@ -740,7 +740,7 @@ export default { }); const json = await response.json(); if (json?.error) { - BEDITA.error(json.error?.title); + this.$helpers.handleApiError(json); } else { this.addedRelations = []; this.modifiedRelations = []; @@ -749,11 +749,7 @@ export default { } await this.reloadObjects(); } catch (error) { - if (typeof error === 'string') { - BEDITA.error(error); - } else { - BEDITA.error(error?.title); - } + this.$helpers.handleApiError(error); } finally { this.savingRelated = false; } diff --git a/resources/js/app/helpers/view.js b/resources/js/app/helpers/view.js index 5258806e6..b0d08c6a5 100644 --- a/resources/js/app/helpers/view.js +++ b/resources/js/app/helpers/view.js @@ -336,6 +336,22 @@ export default { return d ? new Date(d).toLocaleDateString(locale) + ' ' + new Date(d).toLocaleTimeString(locale) : ''; }, + + handleApiError(response) { + if (typeof response === 'string') { + BEDITA.error(response); + + return; + } + if (response?.error && typeof response.error === 'string') { + BEDITA.error(response.error); + + return; + } + const message = response?.error?.title || 'An error occurred'; + const detail = response?.error?.detail || false; + BEDITA.error(message, document.body, detail); + }, } } }; diff --git a/resources/js/app/pages/admin/appearance.vue b/resources/js/app/pages/admin/appearance.vue index da08b57d3..580ad5453 100644 --- a/resources/js/app/pages/admin/appearance.vue +++ b/resources/js/app/pages/admin/appearance.vue @@ -88,10 +88,10 @@ export default { const response = await fetch(`${BEDITA.base}/admin/appearance/save`, options); const responseJson = await response.json(); if (responseJson.error) { - BEDITA.error(responseJson.error); + this.$helpers.handleApiError(responseJson); } } catch (error) { - BEDITA.error(error); + this.$helpers.handleApiError(error); } finally { this.loading = false; this.loadingKey = ''; diff --git a/resources/js/app/pages/modules/view.vue b/resources/js/app/pages/modules/view.vue index a76daee3b..172d0a8b8 100644 --- a/resources/js/app/pages/modules/view.vue +++ b/resources/js/app/pages/modules/view.vue @@ -105,7 +105,7 @@ export default { } if (json?.error) { await this.showFlashMessages(); - BEDITA.error(json.error); + this.$helpers.handleApiError(json); throw new Error(json.error); } @@ -210,12 +210,13 @@ export default { details = details + '\n' + e.details; } } - const message = t`OOOPS! Something went wrong` + '. ' + this.errors[0].message; - if (this.userRoles.includes('admin')) { - BEDITA.error(message, document.body, details); - } else { - BEDITA.error(message); - } + const title = t`OOOPS! Something went wrong` + '. ' + this.errors[0].message; + this.$helpers.handleApiError({ + error: { + title, + details + } + }); this.errors = []; }, From e1278ca170e58a9476f192a843295c75b1dceede Mon Sep 17 00:00:00 2001 From: dante di domenico Date: Thu, 20 Mar 2025 08:53:42 +0100 Subject: [PATCH 2/4] fix: processErrors --- resources/js/app/pages/modules/view.vue | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/resources/js/app/pages/modules/view.vue b/resources/js/app/pages/modules/view.vue index 172d0a8b8..72dfdb3ef 100644 --- a/resources/js/app/pages/modules/view.vue +++ b/resources/js/app/pages/modules/view.vue @@ -211,12 +211,20 @@ export default { } } const title = t`OOOPS! Something went wrong` + '. ' + this.errors[0].message; - this.$helpers.handleApiError({ + let params = { error: { title, - details } - }); + }; + if (this.userRoles.includes('admin')) { + params = { + error: { + title, + details + } + } + } + this.$helpers.handleApiError(params); this.errors = []; }, From a7c7dd024120159934e90f55e27f50b7881a9bc5 Mon Sep 17 00:00:00 2001 From: dante di domenico Date: Tue, 25 Mar 2025 12:23:53 +0100 Subject: [PATCH 3/4] refactor: js to vue --- .../dialog/{dialog.js => dialog.vue} | 124 +++++++++++++----- 1 file changed, 93 insertions(+), 31 deletions(-) rename resources/js/app/components/dialog/{dialog.js => dialog.vue} (62%) diff --git a/resources/js/app/components/dialog/dialog.js b/resources/js/app/components/dialog/dialog.vue similarity index 62% rename from resources/js/app/components/dialog/dialog.js rename to resources/js/app/components/dialog/dialog.vue index b57e446de..1e5adfc21 100644 --- a/resources/js/app/components/dialog/dialog.js +++ b/resources/js/app/components/dialog/dialog.vue @@ -1,42 +1,94 @@ -import { t } from 'ttag'; -import Vue from 'vue'; - -/** - * Component to display a dialog. - */ -export const Dialog = Vue.extend({ - template: `