MT#65122 Refactor PBX call queue ownership flow

* Split call queue resource identity from subscriber ownership
  * Use callQueue.id for row state, updates, and removal
  * Use subscriber_id, with id fallback, for owner display lookup
  * Send complete form payload with subscriberId and queue values
  * Use setPreference when creating queue preferences
  * Remove lodash usage from newly changed store/API lines
  * Fix call queue removal loading state check
  * Resolve dead call queue link in seat's pbx configuration menu
  * Improve remove call queue flow

Change-Id: Iabf7382799866534de12eea6bc3db8ed13cfcb52
(cherry picked from commit d5e1f72d6e)
(cherry picked from commit 0223a37550)
mr12.5.1
Giancarlo Errigo Mattos 3 weeks ago committed by Giancarlo Mattos
parent d5f646391f
commit 05948f7f08

@ -1,9 +1,10 @@
import _ from 'lodash'
import {
addPreference,
addPreferenceFull,
getAllPreferences,
getSubscriber
getSubscriber,
removeCallQueueConfig,
setPreference
} from 'src/api/subscriber'
export function getCallQueues () {
@ -24,63 +25,29 @@ export function getCallQueues () {
})
}
export function getCallQueueList () {
return new Promise((resolve, reject) => {
let callQueues = []
Promise.resolve().then(() => {
return getCallQueues()
}).then(($callQueues) => {
callQueues = $callQueues
const subscriberPromises = []
callQueues.items.forEach((callQueue) => {
subscriberPromises.push(getSubscriber(callQueue.id))
})
return Promise.all(subscriberPromises)
}).then((subscribers) => {
resolve({
export async function getCallQueueList () {
const callQueues = await getCallQueues()
const subscribers = await Promise.all(
callQueues.items.map((callQueue) => getSubscriber(callQueue.subscriber_id))
)
return {
subscribers: {
items: subscribers
},
callQueues
})
}).catch((err) => {
reject(err)
})
})
}
}
/**
* @param options.subscriber_id
* @param options.max_queue_length
* @param options.queue_wrap_up_time
* @return {Promise}
*/
export function createCallQueue (options) {
return new Promise((resolve, reject) => {
Promise.resolve().then(() => {
return Promise.all([
addPreference(options.subscriber_id, 'cloud_pbx_callqueue', true),
addPreference(options.subscriber_id, 'max_queue_length', options.max_queue_length),
addPreference(options.subscriber_id, 'queue_wrap_up_time', options.queue_wrap_up_time)
export async function createCallQueue ({ subscriberId, maxQueueLength, queueWrapUpTime }) {
await Promise.all([
setPreference(subscriberId, 'cloud_pbx_callqueue', true),
setPreference(subscriberId, 'max_queue_length', maxQueueLength),
setPreference(subscriberId, 'queue_wrap_up_time', queueWrapUpTime)
])
}).then(() => {
resolve()
}).catch((err) => {
reject(err)
})
})
}
export function removeCallQueue (subscriberId) {
return new Promise((resolve, reject) => {
Promise.resolve().then(() => {
return addPreference(subscriberId, 'cloud_pbx_callqueue', false)
}).then(() => {
resolve()
}).catch((err) => {
reject(err)
})
})
export async function removeCallQueue (callQueueId) {
await removeCallQueueConfig(callQueueId)
}
export function setCallQueueMaxLength (options) {

@ -21,6 +21,11 @@ const generateNumbers = '0123456789'
const generateLowercase = 'abcdefghijklmnopqrstuvwxyz'
const generateUppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
const generateLength = 12
export const CALL_QUEUE_PREFERENCE_FIELDS = [
'cloud_pbx_callqueue',
'max_queue_length',
'queue_wrap_up_time'
]
export function getPreferences (id) {
return new Promise((resolve, reject) => {
@ -569,9 +574,10 @@ export function setWrapUpTime (id, wrapUpTime) {
return editCallQueuePreference(id, { queue_wrap_up_time: wrapUpTime })
}
export function removeCallQueueConfig (subscriberId) {
const param = { cloud_pbx_callqueue: false }
return httpApi.put(`api/subscriberpreferences/${subscriberId}`, param)
export async function removeCallQueueConfig (subscriberId) {
const preferences = await getPreferences(subscriberId)
const fields = CALL_QUEUE_PREFERENCE_FIELDS.filter((field) => Object.hasOwn(preferences, field))
await Promise.all(fields.map((field) => removePreference(subscriberId, field)))
}
export function getAllPreferences (options) {

@ -266,6 +266,7 @@ export default {
if (this.hasMaxQueueLengthChanged && this.v$.changes.max_queue_length.$errors.length <= 0) {
this.$emit('save-max-queue-length', {
callQueueId: this.callQueue.id,
subscriberId: this.callQueue.subscriber_id,
maxQueueLength: this.changes.max_queue_length
})
}
@ -274,6 +275,7 @@ export default {
if (this.hasQueueWrapUpTimeChanged && this.v$.changes.queue_wrap_up_time.$errors.length <= 0) {
this.$emit('save-queue-wrap-up-time', {
callQueueId: this.callQueue.id,
subscriberId: this.callQueue.subscriber_id,
queueWrapUpTime: this.changes.queue_wrap_up_time
})
}

@ -186,7 +186,11 @@ export default {
this.$emit('cancel')
},
save () {
this.$emit('submit', this.data)
this.$emit('submit', {
subscriberId: this.data.subscriber_id,
maxQueueLength: this.data.max_queue_length,
queueWrapUpTime: this.data.queue_wrap_up_time
})
},
reset () {
this.data = this.getDefaults()

@ -52,7 +52,7 @@
:loading="isCallQueueLoading(callQueue.id)"
:expanded="isCallQueueExpanded(callQueue.id)"
:call-queue="callQueue"
:subscriber="subscriberMap[callQueue.id]"
:subscriber="subscriberMap[callQueue.subscriber_id]"
:default-max-queue-length="defaultMaxQueueLength"
:default-queue-wrap-up-time="defaultQueueWrapUpTime"
@remove="openCallQueueRemovalDialog"
@ -89,7 +89,6 @@ import CscRemoveDialog from 'components/CscRemoveDialog'
import CscPbxCallQueue from 'components/pages/PbxConfiguration/CscPbxCallQueue'
import CscPbxCallQueueAddForm from 'components/pages/PbxConfiguration/CscPbxCallQueueAddForm'
import CscFade from 'components/transitions/CscFade'
import { getSubscriberId } from 'src/auth'
import {
showGlobalError,
showToast
@ -193,7 +192,7 @@ export default {
}
},
mounted () {
this.loadCallQueueList({ subscriberId: getSubscriberId() })
this.loadCallQueueList()
},
methods: {
...mapActions('pbx', [

@ -180,7 +180,8 @@ export default {
methods: {
...mapWaitingActions('callSettings', {
loadSubscriberPreferencesAction: 'csc-pbx-call-settings-load-preferences',
fieldUpdateAction: 'csc-pbx-call-settings-update-preferences'
fieldUpdateAction: 'csc-pbx-call-settings-update-preferences',
removeCallQueueAction: 'csc-pbx-call-settings-update-preferences'
}),
resetMaxQueueLength () {
this.changes.max_queue_length = this.getDefaultData().max_queue_length
@ -219,10 +220,16 @@ export default {
queue_wrap_up_time: this.subscriberPreferences.queue_wrap_up_time || this.defaultQueueWrapUpTime.toString(),
subscriber_id: getSubscriberId()
}
this.cloud_pbx_callqueue = this.subscriberPreferences.cloud_pbx_callqueue ? this.subscriberPreferences.cloud_pbx_callqueue : this.cloud_pbx_callqueue
this.cloud_pbx_callqueue = this.subscriberPreferences.cloud_pbx_callqueue === true
},
addOrRemoveCallQueue () {
this.fieldUpdateAction({ field: 'cloud_pbx_callqueue', value: this.cloud_pbx_callqueue })
async addOrRemoveCallQueue () {
if (this.cloud_pbx_callqueue) {
await this.fieldUpdateAction({ field: 'cloud_pbx_callqueue', value: true })
} else {
await this.removeCallQueueAction()
this.getCallQueue()
this.changes = this.getDefaultData()
}
}
}
}

@ -1,6 +1,8 @@
import {
CALL_QUEUE_PREFERENCE_FIELDS,
getPreferences,
getPreferencesDefs,
removeCallQueueConfig,
removePreference,
setPreference
} from 'src/api/subscriber'
@ -42,6 +44,9 @@ export default {
subscriberPreferencesUpdate (state, { field, value }) {
state.subscriberPreferences[field] = value
},
subscriberPreferencesRemove (state, field) {
delete state.subscriberPreferences[field]
},
preferencesDefsSucceeded (state, res) {
state.preferencesDefs = res
}
@ -59,6 +64,12 @@ export default {
value: options.value
})
},
async removeCallQueueAction (context) {
await removeCallQueueConfig(context.getters.subscriberId)
CALL_QUEUE_PREFERENCE_FIELDS.forEach((field) => {
context.commit('subscriberPreferencesRemove', field)
})
},
async loadPreferencesDefsAction (context) {
const preferencesDefs = await getPreferencesDefs()
context.commit('preferencesDefsSucceeded', preferencesDefs)

@ -1,5 +1,4 @@
import { i18n } from 'boot/i18n'
import _ from 'lodash'
import {
createCallQueue,
getCallQueueList,
@ -7,7 +6,6 @@ import {
setCallQueueMaxLength,
setCallQueueWrapUpTime
} from 'src/api/pbx-callqueues'
import { getPreferences } from 'src/api/subscriber'
import { CreationState, RequestState } from 'src/store/common'
export default {
@ -50,40 +48,40 @@ export default {
return state.callQueueUpdateState === RequestState.requesting
},
isCallQueueRemoving (state) {
return state.callQueueRemoving === RequestState.requesting
return state.callQueueRemovalState === RequestState.requesting
},
isCallQueueLoading (state) {
return (id) => {
return (callQueueId) => {
return (state.callQueueRemovalState === RequestState.requesting &&
state.callQueueRemoving !== null && state.callQueueRemoving.id === id) ||
state.callQueueRemoving !== null && state.callQueueRemoving.id === callQueueId) ||
(state.callQueueUpdateState === RequestState.requesting &&
state.callQueueUpdating !== null && state.callQueueUpdating.id === id)
state.callQueueUpdating !== null && state.callQueueUpdating.id === callQueueId)
}
},
isCallQueueExpanded (state) {
return (id) => {
return state.callQueueSelected !== null && state.callQueueSelected.id === id
return (callQueueId) => {
return state.callQueueSelected !== null && state.callQueueSelected.id === callQueueId
}
},
getCallQueueRemoveDialogMessage (state) {
if (state.callQueueRemoving !== null) {
return i18n.global.t('You are about to remove call queue for {subscriber}', {
subscriber: state.subscriberMap[state.callQueueRemoving.id].display_name
subscriber: state.subscriberMap[state.callQueueRemoving.subscriber_id]?.display_name ?? ''
})
}
return ''
},
getCallQueueRemovingName (state) {
const subscriber = _.get(state.subscriberMap, _.get(state.callQueueRemoving, 'id', null), null)
return _.get(subscriber, 'display_name', '')
const subscriber = state.subscriberMap[state.callQueueRemoving?.subscriber_id]
return subscriber?.display_name ?? ''
},
getCallQueueCreatingName (state) {
const subscriber = _.get(state.subscriberMap, _.get(state.callQueueCreationData, 'subscriber_id', null), null)
return _.get(subscriber, 'display_name', '')
const subscriber = state.subscriberMap[state.callQueueCreationData?.subscriberId]
return subscriber?.display_name ?? ''
},
getCallQueueUpdatingName (state) {
const subscriber = _.get(state.subscriberMap, _.get(state.callQueueUpdating, 'id', null), null)
return _.get(subscriber, 'display_name', '')
const subscriber = state.subscriberMap[state.callQueueUpdating?.subscriber_id]
return subscriber?.display_name ?? ''
},
getCallQueueUpdatingField (state) {
return state.callQueueUpdatingField
@ -118,11 +116,14 @@ export default {
},
callQueueListSucceeded (state, callQueueList) {
state.callQueueListState = RequestState.succeeded
state.callQueueList = _.get(callQueueList, 'callQueues.items', [])
state.callQueueList = callQueueList?.callQueues?.items ?? []
state.callQueueMap = {}
state.callQueueList.forEach((callQueue) => {
state.callQueueMap[callQueue.id] = callQueue
})
_.get(callQueueList, 'subscribers.items', []).forEach((subscriber) => {
state.subscriberMap = {}
const subscribers = callQueueList?.subscribers?.items ?? []
subscribers.forEach((subscriber) => {
state.subscriberMap[subscriber.id] = subscriber
})
state.callQueueListVisible = true
@ -162,15 +163,15 @@ export default {
},
callQueueUpdateSucceeded (state, preferences) {
state.callQueueUpdateState = RequestState.succeeded
if (preferences) {
for (let i = 0; i < state.callQueueList.length; i++) {
if (state.callQueueList[i].id === preferences.id) {
state.callQueueList[i] = preferences
}
if (!preferences) {
return
}
delete state.callQueueMap[preferences.id]
state.callQueueMap[preferences.id] = preferences
const callQueueId = preferences.id
const index = state.callQueueList.findIndex((callQueue) => callQueue.id === callQueueId)
if (index !== -1) {
state.callQueueList[index] = preferences
}
state.callQueueMap[callQueueId] = preferences
},
callQueueUpdateFailed (state, err) {
state.callQueueUpdateState = RequestState.failed
@ -185,30 +186,29 @@ export default {
expandCallQueue (state, callQueueId) {
state.callQueueSelected = state.callQueueMap[callQueueId]
},
expandCallQueueBySubscriberId (state, subscriberId) {
state.callQueueSelected = state.callQueueList.find((callQueue) => {
return callQueue.subscriber_id === subscriberId
}) || null
},
collapseCallQueue (state) {
state.callQueueSelected = null
},
setDefaultQueueWrapUpTime (state, value) {
state.defaultQueueWrapUpTime = value
}
},
actions: {
async loadCallQueueList (context, options) {
const subscriberId = _.get(options, 'subscriberId', null)
const listVisible = _.get(options, 'listVisible', false)
const selectedId = _.get(options, 'selectedId', null)
const listVisible = options?.listVisible ?? false
const selectedId = options?.selectedId ?? null
const selectedSubscriberId = options?.selectedSubscriberId ?? null
context.commit('callQueueListRequesting', { listVisible })
try {
const callQueueList = await getCallQueueList()
context.commit('callQueueListSucceeded', callQueueList)
const subscriberPreferences = await getPreferences(subscriberId)
const wrapUpTime = _.get(subscriberPreferences, 'queue_wrap_up_time', 10)
context.commit('setDefaultQueueWrapUpTime', wrapUpTime)
if (selectedId !== null) {
context.commit('expandCallQueue', callQueueList)
context.commit('highlightCallQueue', callQueueList)
context.commit('expandCallQueue', selectedId)
} else if (selectedSubscriberId !== null) {
context.commit('expandCallQueueBySubscriberId', selectedSubscriberId)
}
} catch (err) {
context.commit('callQueueListFailed', err.message)
@ -218,7 +218,8 @@ export default {
context.commit('callQueueCreationRequesting', callQueueData)
createCallQueue(callQueueData).then(() => {
return context.dispatch('loadCallQueueList', {
listVisible: true
listVisible: true,
selectedSubscriberId: callQueueData.subscriberId
})
}).then(() => {
context.commit('callQueueCreationSucceeded')
@ -269,8 +270,8 @@ export default {
})
},
jumpToCallQueue (context, subscriber) {
this.$router.push({ path: '/user/pbx-configuration/call-queues' })
context.commit('expandCallQueue', subscriber.id)
this.$router?.push({ path: '/user/pbx-configuration/call-queues' })
context.commit('expandCallQueueBySubscriberId', subscriber.id)
}
}
}

Loading…
Cancel
Save