diff --git a/doc/remove-dialog.md b/doc/remove-dialog.md
new file mode 100644
index 00000000..65be8339
--- /dev/null
+++ b/doc/remove-dialog.md
@@ -0,0 +1,59 @@
+# Remove Dialog Usage
+
+`CscRemoveDialog` is currently used in two different ways in the codebase. Both work and can render the same UI, but are used in different contexts.
+
+- If there is any type of interaction with the state, use the ref-based pattern.
+- If the delete button can build the dialog message and action immediately without changes in the state, use the Quasar plugin pattern.
+
+## Ref-based mounted dialog
+
+Example: `src/pages/CscPagePbxDevices.vue`
+
+Reference:
+
+- `src/pages/CscPagePbxDevices.vue`
+
+In this pattern, the dialog is mounted in the page template and the page keeps a ref to it.
+
+```vue
+
+```
+
+```js
+openDeviceRemovalDialog (deviceId) {
+ if (this.$refs.removeDialog) {
+ this.deviceRemovalRequesting(deviceId)
+ this.$refs.removeDialog.show()
+ }
+}
+```
+
+## Quasar plugin dialog
+
+Example: `src/pages/CscPageCallRecording.vue`
+
+Reference:
+
+- `src/pages/CscPageCallRecording.vue`
+
+In this pattern, the dialog is created on demand through Quasar's dialog plugin.
+
+```js
+confirmRowDeletion (rowId) {
+ this.$q.dialog({
+ component: CscRemoveDialog,
+ componentProps: {
+ title: this.$t('Delete recording'),
+ message: this.$t('You are about to delete recording #{id}', { id: rowId })
+ }
+ }).onOk(() => {
+ this.deleteRecord(rowId)
+ })
+}
+```
diff --git a/src/components/CscDialog.vue b/src/components/CscDialog.vue
index 92bfdfd3..308b9b5a 100644
--- a/src/components/CscDialog.vue
+++ b/src/components/CscDialog.vue
@@ -1,6 +1,6 @@
-
diff --git a/src/components/CscRemoveDialog.vue b/src/components/CscRemoveDialog.vue
index ffbb8e69..dea844d6 100644
--- a/src/components/CscRemoveDialog.vue
+++ b/src/components/CscRemoveDialog.vue
@@ -27,50 +27,46 @@
-
-
+const remove = () => {
+ emit('remove')
+ emit('ok')
+}
+
+defineExpose({
+ show,
+ hide
+})
+
diff --git a/src/components/CscRetrievePasswordDialog.vue b/src/components/CscRetrievePasswordDialog.vue
index 3434ca1d..805c9106 100644
--- a/src/components/CscRetrievePasswordDialog.vue
+++ b/src/components/CscRetrievePasswordDialog.vue
@@ -1,10 +1,10 @@
-
diff --git a/src/store/user.js b/src/store/user.js
index 1171950d..8632eab3 100644
--- a/src/store/user.js
+++ b/src/store/user.js
@@ -43,6 +43,7 @@ import { LICENSES, PROFILE_ATTRIBUTE_MAP } from 'src/constants'
import { getSipInstanceId } from 'src/helpers/call-utils'
import { parseBlobToObject } from 'src/helpers/parse-blob-to-object'
import { qrPayload } from 'src/helpers/qr'
+import { showGlobalError, showToast } from 'src/helpers/ui'
import { PATH_CHANGE_PASSWORD } from 'src/router/routes'
import { setLocal } from 'src/storage'
import { RequestState } from 'src/store/common'
@@ -499,10 +500,15 @@ export default {
context.commit('subscriberUpdateSucceeded', subscriberData)
},
async resetPassword ({ commit }, data) {
- commit('newPasswordRequesting', true)
- const response = await resetPassword(data)
- commit('newPasswordRequesting', false)
- return response
+ try {
+ commit('newPasswordRequesting', true)
+ const res = await resetPassword(data)
+ showToast(res.data.message)
+ } catch (err) {
+ showGlobalError(i18n.global.t('There was an error, please retry later'))
+ } finally {
+ commit('newPasswordRequesting', false)
+ }
},
async recoverPassword ({ commit, dispatch, state, rootGetters }, data) {
commit('userPasswordRequesting')