MT#32999 Customer admin must be able to configure seat's call forward

With this improvement the customer administrator can configure
the call forwards of subscribers that belong to it.
The setting can be done in the CSC Seat page inside the
PBX Configurations.

Change-Id: I3dd4c7ba7e34725705da69bdf28fae93a379aee0
pull/27/merge
CORP\franci11 3 years ago committed by Marco Capetta
parent 64e8ff3d14
commit 58361b087e

@ -19,36 +19,30 @@ export async function cfLoadDestinationSets (subscriberId) {
return getList({
resource: 'cfdestinationsets',
all: true,
params: {
subscriber_id: subscriberId
}
params: (subscriberId) ? { subscriber_id: subscriberId } : {}
})
}
export async function cfLoadSourceSets (subscriberId) {
return getList({
resource: 'cfsourcesets',
params: {
subscriber_id: subscriberId
}
params: (subscriberId) ? { subscriber_id: subscriberId } : {}
})
}
export async function cfLoadTimeSets (subscriberId) {
return getList({
resource: 'cftimesets',
params: {
subscriber_id: subscriberId
}
params: (subscriberId) ? { subscriber_id: subscriberId } : {}
})
}
export async function cfLoadMappingsFull (subscriberId) {
return await Promise.all([
cfLoadMappings(subscriberId),
cfLoadDestinationSets(subscriberId),
cfLoadSourceSets(subscriberId),
cfLoadTimeSets(subscriberId)
cfLoadDestinationSets(),
cfLoadSourceSets(),
cfLoadTimeSets()
])
}

@ -1,33 +1,46 @@
<template>
<csc-page-sticky
<csc-page-sticky-tabs
id="csc-page-pbx-seats-details"
class="row q-pa-lg"
ref="pageSticky"
:value="selectedTab"
>
<template
v-slot:header-align-left
v-slot:tabs
>
<q-breadcrumbs
v-if="seatSelected"
class="text-weight-light q-mr-md"
active-color="primary"
separator-color="primary"
class="q-item absolute absolute-left text-weight-light"
active-color="primary"
separator-color="primary"
>
<q-breadcrumbs-el
key="seats"
class="cursor-pointer"
to="/user/pbx-configuration/seats"
:label="$t('Seats')"
icon="person"
/>
<q-breadcrumbs-el
key="seat"
:label="seatSelected.display_name"
/>
</q-breadcrumbs>
<q-breadcrumbs-el
key="seats"
class="cursor-pointer"
to="/user/pbx-configuration/seats"
:label="$t('Seats')"
icon="person"
/>
<q-breadcrumbs-el
key="seat"
:label="seatSelected.display_name"
/>
</q-breadcrumbs>
<q-tab
v-for="tab in tabs"
class="d-flex justify-content-center"
:key="tab.value"
:name="tab.value"
:icon="tab.icon"
:label="tab.label"
:default="tab.value === selectedTab"
@click="selectTab(tab.value)"
/>
</template>
<q-item
class="col col-xs-12 col-md-6"
v-if="selectedTab === 'preferences'"
>
<q-list
@ -236,7 +249,93 @@
</q-list>
</q-item>
</csc-page-sticky>
<q-list
class="col col-xs-12 col-md-6"
v-else
>
<!-- v-else-if="selectedTab === 'callForwards'" -->
<!-- v-if="hasSubscriberProfileAttributes(['cfu', 'cfna', 'cfb'])" -->
<q-item
class="row justify-center q-pt-lg"
>
<q-btn
flat
icon="add"
color="primary"
:label="$t('Add forwarding')"
:disable="$wait.is('csc-cf-mappings-full')"
:loading="$wait.is('csc-cf-mappings-full')"
>
<csc-popup-menu>
<csc-popup-menu-item
v-if="hasSubscriberProfileAttribute('cfu')"
color="primary"
:label="$t('If available')"
@click="createMapping({ type: 'cfu', subscriberId: id})"
/>
<csc-popup-menu-item
v-if="hasSubscriberProfileAttribute('cfna')"
color="primary"
:label="$t('If not available')"
@click="createMapping({ type: 'cfna', subscriberId: id})"
/>
<csc-popup-menu-item
v-if="hasSubscriberProfileAttribute('cfb')"
color="primary"
:label="$t('If busy')"
@click="createMapping({ type: 'cfb', subscriberId: id})"
/>
</csc-popup-menu>
<template
v-slot:loading
>
<csc-spinner />
</template>
</q-btn>
</q-item>
<q-item
class="row justify-center q-pt-lg"
>
<div
id="csc-wrapper-call-forwarding"
class="col-xs-12 col-lg-8"
>
<q-list
v-if="groups.length === 0 && !$wait.is('csc-cf-mappings-full')"
dense
separator
>
<q-item
:disable="$wait.is('csc-cf-mappings-full')"
>
<q-item-section>
<q-item-label
class="text-weight-bold"
>
{{ $t('Always') }}
</q-item-label>
</q-item-section>
</q-item>
<csc-cf-group-item-primary-number />
</q-list>
<template
v-for="group in groups"
>
<csc-cf-group
:key="group.cfm_id"
class="q-mb-lg"
:loading="$wait.is('csc-cf-mappings-full')"
:mapping="group"
:destination-set="destinationSetMap[group.destinationset_id]"
:source-set="sourceSetMap[group.sourceset_id]"
:time-set="timeSetMap[group.timeset_id]"
/>
</template>
</div>
</q-item>
</q-list>
</csc-page-sticky-tabs>
</template>
<script>
@ -254,10 +353,16 @@ import {
mapGetters,
mapActions
} from 'vuex'
import CscCfGroup from 'components/call-forwarding/CscCfGroup'
import CscCfGroupItemPrimaryNumber from 'components/call-forwarding/CscCfGroupItemPrimaryNumber'
import CscPopupMenu from 'components/CscPopupMenu'
import CscPopupMenuItem from 'components/CscPopupMenuItem'
import CscPageStickyTabs from 'components/CscPageStickyTabs'
import CscInputButtonSave from 'components/form/CscInputButtonSave'
import CscInputButtonReset from 'components/form/CscInputButtonReset'
import CscChangePasswordDialog from 'src/components/CscChangePasswordDialog'
import CscPageSticky from 'src/components/CscPageSticky'
import CscSpinner from 'components/CscSpinner'
import { inRange } from 'src/helpers/validation'
import numberFilter from '../filters/number'
import {
@ -271,16 +376,27 @@ export default {
CscInputButtonReset,
CscInputButtonSave,
CscChangePasswordDialog,
CscPageSticky
CscPageSticky,
CscPageStickyTabs,
CscPopupMenu,
CscPopupMenuItem,
CscCfGroupItemPrimaryNumber,
CscCfGroup,
CscSpinner
},
props: {
initialTab: {
type: String,
default: 'preferences'
}
},
data () {
return {
changes: null,
id: this.$route.params.id,
soundSet: null,
currentCli: ""
currentCli: "",
selectedTab: this.initialTab
}
},
validations: {
@ -301,11 +417,38 @@ export default {
}
},
computed: {
tabs () {
return [
{
label: this.$t('Preferences'),
value: 'preferences',
icon: 'perm_phone_msg'
},
{
label: this.$t('Call Forwards'),
value: 'callForwards',
icon: 'forward_to_inbox'
}
]
},
...mapState('pbxSeats', [
'seatSelected',
'seatUpdateState',
'seatUpdateError'
]),
...mapState('callForwarding', [
'mappings',
'destinationSetMap',
'sourceSetMap',
'timeSetMap'
]),
...mapGetters('callForwarding', [
'groups'
]),
...mapGetters('user', [
'hasSubscriberProfileAttribute',
'hasSubscriberProfileAttributes'
]),
...mapGetters('pbxSeats', [
'getSoundSetBySeatId',
'hasCallQueue',
@ -443,6 +586,8 @@ export default {
},
async mounted () {
this.selectSeat(this.id)
await this.loadAnnouncements()
this.loadMappingsFull(this.id)
},
beforeDestroy () {
this.resetSelectedSeat()
@ -460,6 +605,11 @@ export default {
'loadPreferences',
'setCli'
]),
...mapActions('callForwarding', [
'loadMappingsFull',
'createMapping',
'loadAnnouncements'
]),
...mapActions('pbxCallQueues', [
'jumpToCallQueue'
]),
@ -471,6 +621,14 @@ export default {
'getPrimaryNumberOptions',
'numbers'
]),
selectTab (tabName) {
if (this.selectedTab !== tabName) {
this.forceTabReload(tabName)
}
},
forceTabReload (tabName) {
this.selectedTab = tabName
},
getAliasNumberIds () {
const numberIds = []
this.seatSelected.alias_numbers.forEach((number) => {

@ -42,9 +42,14 @@ function createDefaultDestination (destination, defaultAnnouncementId) {
return payload
}
export async function loadMappingsFull ({ dispatch, commit, rootGetters }) {
export async function loadMappingsFull ({ dispatch, commit, rootGetters }, payload) {
dispatch('wait/start', WAIT_IDENTIFIER, { root: true })
const res = await cfLoadMappingsFull(rootGetters['user/getSubscriberId'])
let res = null
if (payload) {
res = await cfLoadMappingsFull(payload)
} else {
res = await cfLoadMappingsFull(rootGetters['user/getSubscriberId'])
}
commit('dataSucceeded', {
mappings: res[0],
destinationSets: res[1].items,
@ -60,12 +65,13 @@ export async function createMapping ({ dispatch, commit, state, rootGetters }, p
if (payload.type === 'cfu' && state.mappings.cft && state.mappings.cft.length > 0) {
type = 'cft'
}
const subscriberId = (payload.subscriberId) ? (payload.subscriberId) : rootGetters['user/getSubscriberId']
const mappings = _.cloneDeep(state.mappings[type])
const destinationSetId = await post({
resource: 'cfdestinationsets',
body: {
name: 'csc-' + v4(),
subscriber_id: rootGetters['user/getSubscriberId'],
subscriber_id: subscriberId,
destinations: [createDefaultDestination()]
}
})
@ -75,7 +81,7 @@ export async function createMapping ({ dispatch, commit, state, rootGetters }, p
const res = await Promise.all([
patchReplaceFull({
resource: 'cfmappings',
resourceId: rootGetters['user/getSubscriberId'],
resourceId: subscriberId,
fieldPath: type,
value: mappings
}),
@ -104,7 +110,7 @@ export async function deleteMapping ({ dispatch, commit, state, rootGetters }, p
value: updatedMappings
})
await cfDeleteDestinationSet(payload.destinationset_id)
const destinationSets = await cfLoadDestinationSets(rootGetters['user/getSubscriberId'])
const destinationSets = await cfLoadDestinationSets()
commit('dataSucceeded', {
mappings: patchRes,
destinationSets: destinationSets.items
@ -138,7 +144,7 @@ export async function updateDestination ({ dispatch, commit, state, rootGetters
fieldPath: 'destinations',
value: destinations
})
const destinationSets = await cfLoadDestinationSets(rootGetters['user/getSubscriberId'])
const destinationSets = await cfLoadDestinationSets()
commit('dataSucceeded', {
destinationSets: destinationSets.items
})
@ -155,7 +161,7 @@ export async function addDestination ({ dispatch, commit, state, rootGetters },
fieldPath: 'destinations',
value: destinations
})
const destinationSets = await cfLoadDestinationSets(rootGetters['user/getSubscriberId'])
const destinationSets = await cfLoadDestinationSets()
commit('dataSucceeded', {
destinationSets: destinationSets.items
})
@ -193,7 +199,7 @@ export async function removeDestination ({ dispatch, commit, state, rootGetters
fieldPath: 'destinations',
value: updatedDestinations
})
const destinationSets = await cfLoadDestinationSets(rootGetters['user/getSubscriberId'])
const destinationSets = await cfLoadDestinationSets()
commit('dataSucceeded', {
destinationSets: destinationSets.items
})
@ -210,7 +216,7 @@ export async function updateDestinationTimeout ({ dispatch, commit, state, rootG
fieldPath: 'destinations',
value: destinations
})
const destinationSets = await cfLoadDestinationSets(rootGetters['user/getSubscriberId'])
const destinationSets = await cfLoadDestinationSets()
commit('dataSucceeded', {
destinationSets: destinationSets.items
})
@ -219,7 +225,7 @@ export async function updateDestinationTimeout ({ dispatch, commit, state, rootG
export async function loadSourceSets ({ dispatch, commit, rootGetters }) {
dispatch('wait/start', 'csc-cf-sourcesets', { root: true })
const sourceSets = await cfLoadSourceSets(rootGetters['user/getSubscriberId'])
const sourceSets = await cfLoadSourceSets()
commit('dataSucceeded', {
sourceSets: sourceSets.items
})
@ -238,7 +244,7 @@ export async function createSourceSet ({ dispatch, commit, rootGetters, state },
fieldPath: payload.mapping.type,
value: updatedMapping
})
const sourceSets = await cfLoadSourceSets(rootGetters['user/getSubscriberId'])
const sourceSets = await cfLoadSourceSets()
commit('dataSucceeded', {
mappings: updatedMappings,
sourceSets: sourceSets.items
@ -252,7 +258,7 @@ export async function updateSourceSet ({ dispatch, commit, rootGetters, state },
try {
dispatch('wait/start', 'csc-cf-source-set-create', { root: true })
await cfUpdateSourceSet(rootGetters['user/getSubscriberId'], payload)
const sourceSets = await cfLoadSourceSets(rootGetters['user/getSubscriberId'])
const sourceSets = await cfLoadSourceSets()
commit('dataSucceeded', {
sourceSets: sourceSets.items
})
@ -274,7 +280,7 @@ export async function deleteSourceSet ({ dispatch, commit, rootGetters, state },
value: updatedMapping
})
await cfDeleteSourceSet(payload.id)
const sourceSets = await cfLoadSourceSets(rootGetters['user/getSubscriberId'])
const sourceSets = await cfLoadSourceSets()
commit('dataSucceeded', {
mappings: updatedMappings,
sourceSets: sourceSets.items
@ -334,7 +340,7 @@ export async function createTimeSetDate ({ dispatch, commit, rootGetters, state
fieldPath: payload.mapping.type,
value: updatedMapping
})
const timeSets = await cfLoadTimeSets(rootGetters['user/getSubscriberId'])
const timeSets = await cfLoadTimeSets()
commit('dataSucceeded', {
mappings: updatedMappings,
timeSets: timeSets.items
@ -345,7 +351,7 @@ export async function createTimeSetDate ({ dispatch, commit, rootGetters, state
export async function updateTimeSetDate ({ dispatch, commit, rootGetters, state }, payload) {
dispatch('wait/start', 'csc-cf-time-set-create', { root: true })
await cfUpdateTimeSetDate(payload.id, payload.date)
const timeSets = await cfLoadTimeSets(rootGetters['user/getSubscriberId'])
const timeSets = await cfLoadTimeSets()
commit('dataSucceeded', {
timeSets: timeSets.items
})
@ -364,7 +370,7 @@ export async function deleteTimeSet ({ dispatch, commit, rootGetters, state }, p
value: updatedMapping
})
await cfDeleteTimeSet(payload.id)
const timeSets = await cfLoadTimeSets(rootGetters['user/getSubscriberId'])
const timeSets = await cfLoadTimeSets()
commit('dataSucceeded', {
mappings: updatedMappings,
timeSets: timeSets.items
@ -425,7 +431,7 @@ export async function createTimeSetDateRange ({ dispatch, commit, rootGetters, s
fieldPath: payload.mapping.type,
value: updatedMapping
})
const timeSets = await cfLoadTimeSets(rootGetters['user/getSubscriberId'])
const timeSets = await cfLoadTimeSets()
commit('dataSucceeded', {
mappings: updatedMappings,
timeSets: timeSets.items
@ -436,7 +442,7 @@ export async function createTimeSetDateRange ({ dispatch, commit, rootGetters, s
export async function updateTimeSetDateRange ({ dispatch, commit, rootGetters, state }, payload) {
dispatch('wait/start', 'csc-cf-time-set-create', { root: true })
await cfUpdateTimeSetDateRange(payload.id, payload.date)
const timeSets = await cfLoadTimeSets(rootGetters['user/getSubscriberId'])
const timeSets = await cfLoadTimeSets()
commit('dataSucceeded', {
timeSets: timeSets.items
})
@ -454,7 +460,7 @@ export async function createTimeSetWeekdays ({ dispatch, commit, rootGetters, st
fieldPath: payload.mapping.type,
value: updatedMapping
})
const timeSets = await cfLoadTimeSets(rootGetters['user/getSubscriberId'])
const timeSets = await cfLoadTimeSets()
commit('dataSucceeded', {
mappings: updatedMappings,
timeSets: timeSets.items
@ -465,7 +471,7 @@ export async function createTimeSetWeekdays ({ dispatch, commit, rootGetters, st
export async function updateTimeSetWeekdays ({ dispatch, commit, rootGetters, state }, payload) {
dispatch('wait/start', 'csc-cf-time-set-create', { root: true })
await cfUpdateTimeSetWeekdays(payload.id, payload.weekdays)
const timeSets = await cfLoadTimeSets(rootGetters['user/getSubscriberId'])
const timeSets = await cfLoadTimeSets()
commit('dataSucceeded', {
timeSets: timeSets.items
})
@ -486,7 +492,7 @@ export async function createOfficeHours ({ dispatch, commit, rootGetters, state
if (payload.id) {
await cfDeleteTimeSet(payload.id)
}
const timeSets = await cfLoadTimeSets(rootGetters['user/getSubscriberId'])
const timeSets = await cfLoadTimeSets()
commit('dataSucceeded', {
mappings: updatedMappings,
timeSets: timeSets.items
@ -497,7 +503,7 @@ export async function createOfficeHours ({ dispatch, commit, rootGetters, state
export async function updateOfficeHours ({ dispatch, commit, rootGetters, state }, payload) {
dispatch('wait/start', 'csc-cf-time-set-create', { root: true })
await cfUpdateOfficeHours(payload.id, payload.times)
const timeSets = await cfLoadTimeSets(rootGetters['user/getSubscriberId'])
const timeSets = await cfLoadTimeSets()
commit('dataSucceeded', {
timeSets: timeSets.items
})
@ -539,7 +545,7 @@ export async function updateAnnouncement ({ dispatch, commit, rootGetters, state
fieldPath: 'destinations',
value: destinations
})
const destinationSets = await cfLoadDestinationSets(rootGetters['user/getSubscriberId'])
const destinationSets = await cfLoadDestinationSets()
commit('dataSucceeded', {
destinationSets: destinationSets.items
})

Loading…
Cancel
Save