diff --git a/src/api/common.js b/src/api/common.js index 4d5ce94d..72f577c8 100644 --- a/src/api/common.js +++ b/src/api/common.js @@ -6,7 +6,7 @@ import { getJsonBody } from 'src/api/utils' import { getJwt, hasJwt } from 'src/auth' import { PATH_CHANGE_PASSWORD } from 'src/router/routes' export const LIST_DEFAULT_PAGE = 1 -export const LIST_DEFAULT_ROWS = 24 +export const LIST_DEFAULT_ROWS = 20 export const LIST_ALL_ROWS = 1000 export const API_REQUEST_DEFAULT_TIMEOUT = 30000 @@ -135,7 +135,12 @@ export async function getList (options) { if (lastPage === 0) { lastPage = null } - let items = _.get(body, requestConfig.root, []) + + let items = requestConfig.root + // This gets the results for the API V1 which has the list in the root of the response, and if not found it tries to get it from the API V2 response format + ? _.get(body, requestConfig.root, []) + // This gets the results for the API V2 which has the list in the data field, and if not found it tries to get it from the root of the response (for backward compatibility with API V1) + : _.get(body, 'data', []) if (!Array.isArray(items)) { items = [items] } @@ -149,12 +154,33 @@ export async function getList (options) { } } +function extractMessages (messageArray) { + const messages = [] + if (Array.isArray(messageArray)) { + messageArray.forEach((item) => { + Object.keys(item).forEach((fieldName) => { + const fieldErrors = item[fieldName] + if (Array.isArray(fieldErrors)) { + fieldErrors.forEach((errorObject) => { + Object.values(errorObject).forEach((errorMsg) => { + messages.push(errorMsg) + }) + }) + } + }) + }) + } + return messages.join(', ') +} + function handleResponseError (err) { - const code = _.get(err, 'response.data.code', null) + let code = _.get(err, 'response.data.code', null) let message = _.get(err, 'response.data.message', null) + if (code === 403 && message === 'Invalid license') { message = i18n.global.t('Contact your administrator to activate this functionality') } + if (code === 403 && message === 'Password expired') { message = i18n.global.t('Password Expired') if (routerInstance) { @@ -163,6 +189,13 @@ function handleResponseError (err) { return } + // API V2 returns an array of messages rather than a string + // and the code is available in the response status + if (Array.isArray(message)) { + message = extractMessages(message) + code = _.get(err, 'response.status', null) + } + if (code !== null && message !== null) { throw new ApiResponseError(code, message) } @@ -299,7 +332,8 @@ export async function put (options) { path = `api/${requestConfig.resource}/${requestConfig.resourceId}` } try { - const res = await httpApi.put(path, requestConfig.body, { + const payload = requestConfig.body || requestConfig.data + const res = await httpApi.put(path, payload, { headers: requestConfig.headers }) if (requestConfig.headers.Prefer === Prefer.representation) { diff --git a/src/api/subscriber-phonebook.js b/src/api/subscriber-phonebook.js new file mode 100644 index 00000000..f7c83982 --- /dev/null +++ b/src/api/subscriber-phonebook.js @@ -0,0 +1,60 @@ +import { + del, + get, + getList, + patchReplace, + post, + putMinimal +} from 'src/api/common' + +export async function createPhonebook (data) { + const payload = { + name: data.name, + number: data.number, + shared: data.shared, + subscriber_id: Number(data.subscriber_id) + } + return post({ + path: `api/v2/subscribers/${data.subscriber_id}/phonebook`, + body: payload + }) +} + +export async function deleteEntry (subscriberId, entryId) { + return del({ + path: `api/v2/subscribers/${subscriberId}/phonebook/${entryId}` + }) +} + +export async function getEntryById (subscriberId, id) { + return get({ + path: `api/v2/subscribers/${subscriberId}/phonebook/${id}` + }) +} + +export async function getPhonebook (options) { + return getList({ + path: `api/v2/subscribers/${options.subscriber_id}/phonebook`, + params: options + }) +} + +export function setSharedValue (subscriberId, phonebookId, value) { + return patchReplace({ + path: `api/v2/subscribers/${subscriberId}/phonebook/${phonebookId}`, + fieldPath: 'shared', + value + }) +} + +export async function updateEntry (data) { + return putMinimal({ + path: `api/v2/subscribers/${data.subscriberId}/phonebook/${data.id}`, + body: { + number: data.number, + shared: data.shared, + name: data.name, + subscriber_id: Number(data.subscriberId) + } + }) +} diff --git a/src/api/subscriber.js b/src/api/subscriber.js index a3cface4..3cee60fd 100644 --- a/src/api/subscriber.js +++ b/src/api/subscriber.js @@ -66,19 +66,6 @@ export async function setPreferenceCallBlocking (id, field, value) { await addPreference(id, field, value) } -export async function setPreferencePhonebook (subscriberId, phonebookId, field, value) { - if (value === undefined || value === null || value === '' || (Array.isArray(value) && !value.length)) { - await removePreferencePhonebook(subscriberId, phonebookId, field) - } else { - try { - await replacePreferencePhonebook(subscriberId, phonebookId, field, value) - } catch (err) { - if (err) { - throw err - } - } - } -} export async function setPreferencePhonebookCustomer (customerId, phonebookId, field, value) { if (value === undefined || value === null || value === '' || (Array.isArray(value) && !value.length)) { await removePreferencePhonebookCustomer(customerId, phonebookId, field) @@ -92,6 +79,7 @@ export async function setPreferencePhonebookCustomer (customerId, phonebookId, f } } } + export function getNcosLevels (options) { return new Promise((resolve, reject) => { const mergedOptions = _.merge(options || {}, { @@ -124,12 +112,7 @@ export async function removePreference (id, field) { fieldPath: field }) } -export async function removePreferencePhonebook (subscriberId, phonebookId, field) { - return await patchRemove({ - path: `api/v2/subscribers/${subscriberId}/phonebook/${phonebookId}`, - fieldPath: field - }) -} + export async function removePreferencePhonebookCustomer (customerId, phonebookId, field) { return await patchRemove({ path: `api/v2/customers/${customerId}/phonebook/${phonebookId}`, @@ -176,19 +159,7 @@ export function replacePreference (id, field, value) { }) }) } -export function replacePreferencePhonebook (subscriberId, phonebookId, field, value) { - return new Promise((resolve, reject) => { - patchReplace({ - path: `api/v2/subscribers/${subscriberId}/phonebook/${phonebookId}`, - fieldPath: field, - value - }).then(() => { - resolve() - }).catch((err) => { - reject(err) - }) - }) -} + export function replacePreferencePhonebookCustomer (customerId, phonebookId, field, value) { return new Promise((resolve, reject) => { patchReplace({ @@ -772,13 +743,7 @@ export async function getSubscriberRegistrations (options) { }) return list } -export async function getSubscriberPhonebook (options) { - const list = await get({ - path: `api/v2/subscribers/${options.subscriber_id}/phonebook`, - params: options - }) - return list -} + export async function getCustomerPhonebook (options) { const list = await get({ path: `api/v2/customers/${options.customer_id}/phonebook`, @@ -786,15 +751,7 @@ export async function getCustomerPhonebook (options) { }) return list } -export async function createPhonebook (data) { - const payLoad = { - name: data.name, - number: data.number, - shared: data.shared, - subscriber_id: Number(data.subscriber_id) - } - return await httpApi.post(`api/v2/subscribers/${data.subscriber_id}/phonebook`, payLoad) -} + export async function createCustomerPhonebook (data) { const payLoad = { name: data.name, @@ -822,18 +779,10 @@ export async function uploadCsv (context, formData) { config }) } -export function setValueShared (subscriberId, phonebookId, value) { - return setPreferencePhonebook(subscriberId, phonebookId, 'shared', value) -} -export function setValueName (subscriberId, phonebookId, value) { - return setPreferencePhonebook(subscriberId, phonebookId, 'name', value) -} export function setValueNameCustomer (customerId, phonebookId, value) { return setPreferencePhonebookCustomer(customerId, phonebookId, 'name', value) } -export function setValueNumber (subscriberId, phonebookId, value) { - return setPreferencePhonebook(subscriberId, phonebookId, 'number', value) -} + export function setValueNumberCustomer (customerId, phonebookId, value) { return setPreferencePhonebookCustomer(customerId, phonebookId, 'number', value) } diff --git a/src/i18n/de.json b/src/i18n/de.json index a2ee9747..8c67de48 100644 --- a/src/i18n/de.json +++ b/src/i18n/de.json @@ -159,7 +159,7 @@ "Delete recording": "Aufnahme löschen", "Delete registered device": "Registriertes Gerät löschen", "Delete slot?": "Eintrag löschen?", - "Delete subscriber phonebook": "Telefonbuch des Teilnehmers löschen", + "Delete subscriber phonebook entry": "Telefonbucheintrag des Teilnehmers löschen", "Delete voicemail after email notification is delivered": "Voicemail nach dem Senden der E-Mail-Benachrichtigung löschen", "Deliver Incoming Faxes": "Eingehende Faxe zustellen", "Deliver Outgoing Faxes": "Ausgehende Faxe zustellen", @@ -623,7 +623,7 @@ "You are about to delete slot {slot}": "Sie sind dabei, den Eintrag {slot} zu löschen.", "You are about to delete this destination": "Sie sind dabei, dieses Ziel zu löschen.", "You are about to delete this forwarding": "Sie sind dabei, diese Weiterleitung zu löschen.", - "You are about to delete this phonebook": "Sie sind dabei, dieses Telefonbuch zu löschen.", + "You are about to delete this phonebook entry": "Sie sind dabei, diesen Telefonbucheintrag zu löschen.", "You are about to delete this registered device": "Sie sind dabei, dieses registrierte Gerät zu löschen.", "You are about to delete time range \"{from} - {to}\"": "Sie sind dabei, den Zeitraum „{from} - {to}“ zu entfernen.", "You are about to remove ACL: From email <{from_email}>": "Sie sind dabei, die ACL-Regel für die E-Mail-Adresse <{from_email}> zu entfernen.", diff --git a/src/i18n/en.json b/src/i18n/en.json index 29ab9593..337f9a3a 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -156,7 +156,7 @@ "Delete recording": "Delete recording", "Delete registered device": "Delete registered device", "Delete slot?": "Delete slot?", - "Delete subscriber phonebook": "Delete subscriber phonebook", + "Delete subscriber phonebook entry": "Delete subscriber phonebook entry", "Delete voicemail after email notification is delivered": "Delete voicemail after email notification is delivered", "Deliver Incoming Faxes": "Deliver Incoming Faxes", "Deliver Outgoing Faxes": "Deliver Outgoing Faxes", @@ -605,7 +605,7 @@ "You are about to delete slot {slot}": "You are about to delete slot {slot}", "You are about to delete this destination": "You are about to delete this destination", "You are about to delete this forwarding": "You are about to delete this forwarding", - "You are about to delete this phonebook": "You are about to delete this phonebook", + "You are about to delete this phonebook entry": "You are about to delete this phonebook entry", "You are about to delete this registered device": "You are about to delete this registered device", "You are about to delete time range \"{from} - {to}\"": "You are about to delete time range \"{from} - {to}\"", "You are about to remove ACL: From email <{from_email}>": "You are about to remove ACL: From email <{from_email}>", diff --git a/src/i18n/es.json b/src/i18n/es.json index 520aea32..e59f02ef 100644 --- a/src/i18n/es.json +++ b/src/i18n/es.json @@ -159,7 +159,7 @@ "Delete recording": "Eliminar grabación", "Delete registered device": "Eliminar dispositivo registrado", "Delete slot?": "¿Eliminar ranura?", - "Delete subscriber phonebook": "Eliminar agenda del suscriptor", + "Delete subscriber phonebook entry": "Eliminar la entrada de la agenda del abonado", "Delete voicemail after email notification is delivered": "Eliminar el correo de voz después de enviar la notificación por correo electrónico", "Deliver Incoming Faxes": "Entregar faxes entrantes", "Deliver Outgoing Faxes": "Entregar faxes salientes", @@ -627,7 +627,7 @@ "You are about to delete slot {slot}": "Está a punto de eliminar la ranura {slot}", "You are about to delete this destination": "Está a punto de eliminar este destino", "You are about to delete this forwarding": "Está a punto de eliminar este reenvío", - "You are about to delete this phonebook": "Está a punto de eliminar esta agenda", + "You are about to delete this phonebook entry": "Está a punto de eliminar esta entrada de la agenda", "You are about to delete this registered device": "Está a punto de eliminar este dispositivo registrado", "You are about to delete time range \"{from} - {to}\"": "Está a punto de borrar el rango de tiempo \"{from} - {to}\"", "You are about to remove ACL: From email <{from_email}>": "Está a punto de eliminar la ACL: Del correo electrónico <{from_email}>", diff --git a/src/i18n/fr.json b/src/i18n/fr.json index 73dae020..37608411 100644 --- a/src/i18n/fr.json +++ b/src/i18n/fr.json @@ -159,7 +159,7 @@ "Delete recording": "Supprimer l'enregistrement", "Delete registered device": "Supprimer l'appareil enregistré", "Delete slot?": "Supprimer emplacement ?", - "Delete subscriber phonebook": "Supprimer le répertoire de l'abonné", + "Delete subscriber phonebook entry": "Supprimer l’entrée du répertoire de l’abonné", "Delete voicemail after email notification is delivered": "Supprimer le message vocal une fois la notification e-mail délivrée", "Deliver Incoming Faxes": "Transmission des fax entrants", "Deliver Outgoing Faxes": "Livrer des fax sortants", @@ -623,7 +623,7 @@ "You are about to delete slot {slot}": "Vous êtes sur le point de supprimer l'emplacement {slot}", "You are about to delete this destination": "Vous êtes sur le point de supprimer cette destination", "You are about to delete this forwarding": "Vous êtes sur le point de supprimer cette redirection", - "You are about to delete this phonebook": "Vous êtes sur le point de supprimer ce répertoire téléphonique", + "You are about to delete this phonebook entry": "Vous êtes sur le point de supprimer cette entrée du répertoire", "You are about to delete this registered device": "Vous êtes sur le point de supprimer cet appareil enregistré", "You are about to delete time range \"{from} - {to}\"": "Vous êtes sur le point de supprimer la plage horaire \"{from} - {to}\"", "You are about to remove ACL: From email <{from_email}>": "Vous êtes sur le point de supprimer l'ACL : De l'e-mail <{from_email}>", diff --git a/src/i18n/it.json b/src/i18n/it.json index ce63c2ca..06be7338 100644 --- a/src/i18n/it.json +++ b/src/i18n/it.json @@ -157,7 +157,7 @@ "Delete recording": "Elimina registrazione", "Delete registered device": "Elimina dispositivo registrato", "Delete slot?": "Eliminare slot?", - "Delete subscriber phonebook": "Elimina rubrica abbonato", + "Delete subscriber phonebook entry": "Eliminare la voce della rubrica dell’abbonato", "Delete voicemail after email notification is delivered": "Cancella il messaggio vocale dopo l'invio della notifica email", "Deliver Incoming Faxes": "Consegna fax in arrivo", "Deliver Outgoing Faxes": "Consegna fax in uscita", @@ -613,7 +613,7 @@ "You are about to delete slot {slot}": "Stai per eliminare la postazione {slot}", "You are about to delete this destination": "Stai per eliminare questa destinazione", "You are about to delete this forwarding": "Stai per eliminare questo inoltro", - "You are about to delete this phonebook": "Stai per eliminare questa rubrica", + "You are about to delete this phonebook entry": "Stai per eliminare questa voce della rubrica", "You are about to delete this registered device": "Stai per eliminare questo dispositivo registrato", "You are about to delete time range \"{from} - {to}\"": "Stai per eliminare l'intervallo di tempo \"{from} - {to}\"", "You are about to remove ACL: From email <{from_email}>": "Stai per rimuovere ACL: Dall'email <{from_email}>", diff --git a/src/pages/CscPageConversations.vue b/src/pages/CscPageConversations.vue index a55ced20..b20de4cb 100644 --- a/src/pages/CscPageConversations.vue +++ b/src/pages/CscPageConversations.vue @@ -439,7 +439,7 @@ export default { await this.getVoicemailTranscript(voicemailId) }, addToPhonebookAction (number) { - this.$store.commit('user/setPhonebookNumber', number) + this.$store.commit('subscriber-phonebook/setNumber', number) this.$router.push('subscriber-phonebook/create') } } diff --git a/src/pages/CscPageSubscriberPhonebook.vue b/src/pages/CscPageSubscriberPhonebook.vue index 0b934b43..294eeda6 100644 --- a/src/pages/CscPageSubscriberPhonebook.vue +++ b/src/pages/CscPageSubscriberPhonebook.vue @@ -64,8 +64,8 @@ v-model:pagination="pagination" class="no-shadow" :columns="columns" - :rows="subscriberPhonebook" - :loading="$wait.is('loadSubscriberPhonebook')" + :rows="phonebookRows" + :loading="$wait.is('loadPhonebook')" row-key="id" @request="fetchPaginatedRegistrations" > @@ -144,7 +144,6 @@ import CscPageSticky from 'components/CscPageSticky' import CscPopupMenuItem from 'components/CscPopupMenuItem' import CscSpinner from 'components/CscSpinner' import CscSubscriberFilters from 'components/pages/SubscriberPhonebook/CscSubscriberFilters' -import { LIST_DEFAULT_ROWS } from 'src/api/common' import { mapWaitingActions } from 'vue-wait-vue3' import { mapGetters, mapState } from 'vuex' export default { @@ -161,22 +160,15 @@ export default { }, data () { return { - data: [], - pagination: { - sortBy: 'id', - descending: false, - page: 1, - rowsPerPage: LIST_DEFAULT_ROWS, - rowsNumber: 0 - }, filters: {}, showFilters: false } }, computed: { - ...mapState('user', [ - 'subscriberPhonebook' - ]), + ...mapState('subscriber-phonebook', { + phonebookRows: 'phonebookRows', + pagination: 'pagination' + }), ...mapGetters('user', [ 'isPbxEnabled', 'getSubscriberId' @@ -224,10 +216,10 @@ export default { await this.refresh() }, methods: { - ...mapWaitingActions('user', { - loadSubscriberPhonebook: 'loadSubscriberPhonebook', - removeSubscriberPhonebook: 'removeSubscriberPhonebook', - updateValueShared: 'updateValueShared' + ...mapWaitingActions('subscriber-phonebook', { + loadPhonebook: 'loadPhonebook', + removeEntry: 'removeEntry', + updateSharedValue: 'updateSharedValue' }), async refresh () { await this.fetchPaginatedRegistrations({ @@ -236,16 +228,14 @@ export default { }, async fetchPaginatedRegistrations (props) { const { page, rowsPerPage, sortBy, descending } = props.pagination - const count = await this.loadSubscriberPhonebook({ + await this.loadPhonebook({ + include: 'customer', + subscriber_id: this.getSubscriberId, page, rows: rowsPerPage, order_by: sortBy, - order_by_direction: descending ? 'desc' : 'asc', - include: 'customer', - subscriber_id: this.getSubscriberId + order_by_direction: descending ? 'desc' : 'asc' }) - this.pagination = { ...props.pagination } - this.pagination.rowsNumber = count }, async showPhonebookDetails (row) { this.$router.push(`/user/subscriber-phonebook/${row.id}`) @@ -267,13 +257,13 @@ export default { }, async deleteRow (row) { this.$q.dialog({ - title: this.$t('Delete subscriber phonebook'), - message: this.$t('You are about to delete this phonebook'), + title: this.$t('Delete subscriber phonebook entry'), + message: this.$t('You are about to delete this phonebook entry'), color: 'negative', cancel: true, persistent: true }).onOk(async (data) => { - await this.removeSubscriberPhonebook({ + await this.removeEntry({ row, subscriberId: this.getSubscriberId }) @@ -281,7 +271,7 @@ export default { }) }, async toggleShared (row) { - await this.updateValueShared(row) + await this.updateSharedValue(row) }, isLevelEntry (id) { // Entries with composite Ids are considered "level entries", must not be modified (no edit or delete allowed) @@ -290,7 +280,7 @@ export default { openSeatTable () { this.$router.push('/user/seats') }, - applyFilter (filters) { + async applyFilter (filters) { this.filters = filters // Add wildcards to make search more extensive if (filters?.name) { @@ -300,14 +290,13 @@ export default { this.filters.number = `*${filters.number}*` } - this.pagination.page = 1 // Reset to first page on filter change - this.$scrollTo(this.$parent.$el) - const payload = this.filters - payload.page = 1 - payload.subscriber_id = this.getSubscriberId - - this.loadSubscriberPhonebook(payload) + await this.loadPhonebook({ + ...this.filters, + page: 1, + rows: this.pagination.rowsPerPage, + subscriber_id: this.getSubscriberId + }) }, closeFilters () { this.showFilters = false @@ -316,10 +305,10 @@ export default { openSearchFilters () { this.showFilters = true }, - resetFilters () { + async resetFilters () { if (this.hasFilters) { this.filters = {} - this.loadSubscriberPhonebook({ + await this.loadPhonebook({ page: this.pagination.page, rows: this.pagination.rowsPerPage, order_by: this.pagination.sortBy, diff --git a/src/pages/CscPageSubscriberPhonebookAdd.vue b/src/pages/CscPageSubscriberPhonebookAdd.vue index 443d5ccf..4eb7cf89 100644 --- a/src/pages/CscPageSubscriberPhonebookAdd.vue +++ b/src/pages/CscPageSubscriberPhonebookAdd.vue @@ -107,9 +107,11 @@ export default { }, computed: { ...mapGetters('user', [ - 'prefilledNumber', 'getSubscriberId' ]), + ...mapGetters('subscriber-phonebook', [ + 'getPrefilledNumber' + ]), nameErrorMessage () { const errorsTab = this.v$.formData.name.$errors if (errorsTab && errorsTab.length > 0 && errorsTab[0].$validator === 'required') { @@ -121,14 +123,14 @@ export default { } }, mounted () { - if (this.prefilledNumber) { - this.formData.number = this.prefilledNumber - this.$store.commit('user/setPhonebookNumber', '') + if (this.getPrefilledNumber) { + this.formData.number = this.getPrefilledNumber + this.$store.commit('subscriber-phonebook/setNumber', '') } }, methods: { - ...mapWaitingActions('user', { - createPhonebookSubscriber: 'createPhonebookSubscriber' + ...mapWaitingActions('subscriber-phonebook', { + createPhonebook: 'createPhonebook' }), getDefaultFormData () { return { @@ -160,7 +162,7 @@ export default { async confirm () { try { this.formData.subscriber_id = this.getSubscriberId - await this.createPhonebookSubscriber(this.formData) + await this.createPhonebook(this.formData) await this.$router.push('/user/subscriber-phonebook/') } catch (error) { if (error.response && error.response.data.message === "Duplicate entry 'subscriber_id-number") { diff --git a/src/pages/CscPageSubscriberPhonebookDetails.vue b/src/pages/CscPageSubscriberPhonebookDetails.vue index c629f97e..4656bee0 100644 --- a/src/pages/CscPageSubscriberPhonebookDetails.vue +++ b/src/pages/CscPageSubscriberPhonebookDetails.vue @@ -91,7 +91,13 @@ export default { } }, async mounted () { - await this.getPhonebook(this.id) + const response = await this.getEntry({ + id: this.id, + subscriberId: this.getSubscriberId + }) + this.name = response.name + this.number = response.number + this.shared = response.shared }, computed: { ...mapGetters('user', [ @@ -99,48 +105,23 @@ export default { ]) }, methods: { - ...mapWaitingActions('user', { - getPhonebookDetails: 'getPhonebookDetails', - getValueShared: 'getValueShared', - getValueName: 'getValueName', - getValueNumber: 'getValueNumber' + ...mapWaitingActions('subscriber-phonebook', { + getEntry: 'getEntry', + updateEntry: 'updateEntry' }), - async getPhonebook (id) { - const response = await this.getPhonebookDetails({ phonebookId: id, subscriberId: this.getSubscriberId }) - this.name = response.data.name - this.number = response.data.number - this.shared = response.data.shared - }, cancel () { this.$router.push('/user/subscriber-phonebook/') this.$emit('cancel') }, - async changeValueName () { - await this.getValueName({ + async confirm () { + await this.updateEntry({ subscriberId: this.getSubscriberId, - phonebookId: this.id, + id: this.id, + number: this.number, + shared: this.shared, name: this.name }) - }, - changeValueShared () { - this.getValueShared({ - subscriberId: this.getSubscriberId, - phonebookId: this.id, - shared: this.shared - }) - }, - changeValueNumber () { - this.getValueNumber({ - subscriberId: this.getSubscriberId, - phonebookId: this.id, - number: this.number - }) - }, - async confirm () { - await this.changeValueName() - await this.changeValueShared() - await this.changeValueNumber() - await this.$router.push('/user/subscriber-phonebook/') + this.$router.push('/user/subscriber-phonebook/') } } } diff --git a/src/store/index.js b/src/store/index.js index e054b75c..d48d1f38 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -20,6 +20,7 @@ import PbxSeatsModule from 'src/store/pbx-seats' import PbxSoundSetsModule from 'src/store/pbx-soundsets' import ReminderModule from 'src/store/reminder' import SpeedDialModule from 'src/store/speed-dial' +import SubscriberPhonebookModule from 'src/store/subscriber-phonebook' import TranscriptionsModule from 'src/store/transcriptions' import UserModule from 'src/store/user' import VoiceboxModule from 'src/store/voicebox' @@ -59,7 +60,8 @@ export default function (/* { ssrContext } */) { pbxAutoAttendants: PbxAutoAttendants, dashboard: DashboardModule, customer: Customer, - transcriptions: TranscriptionsModule + transcriptions: TranscriptionsModule, + 'subscriber-phonebook': SubscriberPhonebookModule }, state: { route: null diff --git a/src/store/subscriber-phonebook.js b/src/store/subscriber-phonebook.js new file mode 100644 index 00000000..e4a4c98c --- /dev/null +++ b/src/store/subscriber-phonebook.js @@ -0,0 +1,92 @@ +import { LIST_DEFAULT_ROWS } from 'src/api/common' +import { + createPhonebook, + deleteEntry, + getEntryById, + getPhonebook, + setSharedValue, + updateEntry +} from 'src/api/subscriber-phonebook' + +export default { + namespaced: true, + state: { + phonebookRows: [], + pagination: { + sortBy: 'id', + descending: false, + page: 1, + rowsPerPage: LIST_DEFAULT_ROWS, + rowsNumber: 0 + }, + numberInput: null + }, + getters: { + getEntryById: (state) => (id) => { + return state.phonebookRows.find((entry) => entry.id === id) + }, + getPrefilledNumber: (state) => state.numberInput, + phonebookRows: (state) => state.phonebookRows, + pagination: (state) => state.pagination + }, + mutations: { + setPhonebookRows (state, rows) { + state.phonebookRows = rows + }, + setPagination (state, pagination) { + state.pagination = { ...state.pagination, ...pagination } + }, + setSharedValue (state, { id, value }) { + const index = state.phonebookRows.findIndex((row) => { + return row.id === id + }) + if (index > -1) { + state.phonebookRows[index].shared = value + } + }, + setNumber (state, numberInput) { + state.numberInput = numberInput + } + }, + actions: { + async loadPhonebook ({ commit }, options) { + try { + const list = await getPhonebook({ + ...options + }) + commit('setPhonebookRows', list.items || []) + commit('setPagination', { + page: options.page, + rowsPerPage: options.rows, + rowsNumber: list.totalCount + }) + return list + } catch (err) { + commit('setPhonebookRows', []) + throw err + } + }, + async removeEntry (context, { row, subscriberId }) { + await deleteEntry(subscriberId, row.id) + }, + async getEntry (context, { id, subscriberId }) { + const cachedEntry = context.getters.getEntryById(id) + if (cachedEntry) { + return cachedEntry + } + // Fetch from API if not in store + const response = await getEntryById(subscriberId, id) + return response + }, + async createPhonebook (context, data) { + await createPhonebook(data) + }, + async updateEntry (context, data) { + await updateEntry(data) + }, + async updateSharedValue (context, row) { + context.commit('setSharedValue', { id: row.id, value: !row.shared }) + await setSharedValue(row.subscriber_id, row.id, row.shared) + } + } +} diff --git a/src/store/user.js b/src/store/user.js index b851c5f0..1171950d 100644 --- a/src/store/user.js +++ b/src/store/user.js @@ -9,25 +9,20 @@ import { changePassword, changeSIPPassword, createCustomerPhonebook, - createPhonebook, generateGeneralPassword, getBrandingLogo, getCustomerPhonebook, getNcosLevels, getNcosSet, getPreferences, - getSubscriberPhonebook, getSubscriberProfile, getSubscriberRegistrations, getSubscriberSeats, recoverPassword, resetPassword, setPreference, - setValueName, setValueNameCustomer, - setValueNumber, setValueNumberCustomer, - setValueShared, uploadCsv } from 'src/api/subscriber' import { @@ -77,10 +72,8 @@ export default { resellerBranding: null, defaultBranding: {}, subscriberRegistrations: [], - subscriberPhonebook: [], subscriberSeats: [], customerPhonebook: [], - phonebookMap: {}, platformInfo: null, qrCode: null, qrExpiringTime: null, @@ -238,9 +231,6 @@ export default { }, isSpCe (state) { return state?.platformInfo?.type === 'spce' - }, - prefilledNumber (state) { - return state.numberInput } }, mutations: { @@ -335,9 +325,6 @@ export default { setSubscriberRegistrations (state, value) { state.subscriberRegistrations = value }, - setSubscriberPhonebook (state, value) { - state.subscriberPhonebook = value - }, setSubscriberSeats (state, value) { state.subscriberSeats = value }, @@ -353,14 +340,6 @@ export default { setQrExpiringTime (state, qrExpiringTime) { state.qrExpiringTime = qrExpiringTime }, - setPhonebookShared (state, { id, value }) { - const index = state.subscriberPhonebook.findIndex((row) => { - return row.id === id - }) - if (index > -1) { - state.subscriberPhonebook[index].shared = value - } - }, loginWaitingForOTPCode (state) { state.loginWaitingOTPCode = true state.OTPSecret = null @@ -370,9 +349,6 @@ export default { state.loginWaitingOTPCode = true state.OTPSecret = payload state.loginRequesting = false - }, - setPhonebookNumber (state, numberInput) { - state.numberInput = numberInput } }, actions: { @@ -566,18 +542,6 @@ export default { throw err } }, - async loadSubscriberPhonebook ({ commit, dispatch, state, rootGetters }, options) { - try { - const list = await getSubscriberPhonebook({ - ...options - }) - commit('setSubscriberPhonebook', list.data) - return list.totalCount - } catch (err) { - commit('setSubscriberPhonebook', []) - throw err - } - }, async loadCustomerPhonebook ({ commit, dispatch, state, rootGetters }, options) { try { const list = await getCustomerPhonebook({ @@ -608,9 +572,6 @@ export default { async removeSubscriberRegistration (context, row) { await httpApi.delete(`api/subscriberregistrations/${row.id}`) }, - async removeSubscriberPhonebook (context, { row, subscriberId }) { - await httpApi.delete(`api/v2/subscribers/${subscriberId}/phonebook/${row.id}`) - }, async removeCustomerPhonebook (context, { row, customerId }) { await httpApi.delete(`api/v2/customers/${customerId}/phonebook/${row.id}`) }, @@ -649,36 +610,16 @@ export default { async setNcosLevelsSubscriber (value) { await setPreference(getSubscriberId(), 'ncos', value) }, - async getPhonebookDetails (context, { phonebookId, subscriberId }) { - const list = await httpApi.get(`api/v2/subscribers/${subscriberId}/phonebook/${phonebookId}`) - return list - }, async getPhonebookCustomerDetails (context, { phonebookId, customerId }) { const list = await httpApi.get(`api/v2/customers/${customerId}/phonebook/${phonebookId}`) return list }, - async getValueShared (context, options) { - await setValueShared(options.subscriberId, options.phonebookId, options.shared) - }, - async updateValueShared (context, row) { - context.commit('setPhonebookShared', { id: row.id, value: !row.shared }) - await setValueShared(row.subscriber_id, row.id, row.shared) - }, - async getValueName (context, options) { - await setValueName(options.subscriberId, options.phonebookId, options.name) - }, async getValueNameCustomer (context, options) { await setValueNameCustomer(options.customerId, options.phonebookId, options.name) }, - async getValueNumber (context, options) { - await setValueNumber(options.subscriberId, options.phonebookId, options.number) - }, async getValueNumberCustomer (context, options) { await setValueNumberCustomer(options.customerId, options.phonebookId, options.number) }, - async createPhonebookSubscriber (context, data) { - await createPhonebook(data) - }, async createPhonebookCustomer (context, data) { await createCustomerPhonebook(data) },