TT#124272 AutoAttendant - As PBX-Attendant (Pilot, Seat, Group), I can change my AutoAttendant configuration

Change-Id: If6238f053f44e4b880dfbbe03d8b44e5e65ce8d9
mr10.0
CORP\hzigha 4 years ago committed by hzigha
parent a282cd29ae
commit 17f2345b30

@ -195,10 +195,23 @@ export default {
]
},
{
to: '/user/pbx-settings',
icon: 'settings',
label: this.$t('PBX Settings'),
visible: this.isPbxEnabled && this.hasSubscriberProfileAttribute(PROFILE_ATTRIBUTE_MAP.pbxSettings)
visible: this.isPbxEnabled && this.hasSubscriberProfileAttribute(PROFILE_ATTRIBUTE_MAP.pbxSettings),
children: [
{
to: '/user/pbx-settings/general',
icon: 'settings',
label: this.$t('General'),
visible: true
},
{
to: '/user/pbx-settings/auto-attendant',
icon: 'dialpad',
label: this.$t('Auto-attendant'),
visible: true
}
]
},
{
to: '/user/registered-devices',

@ -0,0 +1,162 @@
<template>
<csc-list-item
ref="listItem"
icon="dialpad"
:expanded="expanded"
@toggle="toggle"
>
<template
slot="title"
>
<csc-list-item-title>
{{ $t('Slot') }}: {{ personalSlot.slot }}
</csc-list-item-title>
<q-slide-transition>
<csc-list-item-subtitle
v-if="!expanded"
>
{{ $t('Destination') }}: {{ personalSlot.destination }}
</csc-list-item-subtitle>
</q-slide-transition>
</template>
<template slot="menu">
<csc-list-menu-item
icon="delete"
icon-color="negative"
@click="confirmRowDeletion"
>
{{ $t('Remove') }}
</csc-list-menu-item>
</template>
<template
slot="body"
>
<q-input
v-model="newDestination"
:label="$t('Destination')"
:error="$v.newDestination.$error"
:error-message="errorMessage"
@keyup.enter="save"
@input="valueChanged"
>
<template
v-if="hasDestinationChanged"
v-slot:append
>
<csc-input-button-save
v-if="newDestination !== '' && newDestination !== null"
@click.stop="save"
/>
<csc-input-button-reset
v-if="!addNewSlot"
@click.stop="resetSlotDestination"
/>
</template>
</q-input>
</template>
</csc-list-item>
</template>
<script>
import CscListItem from '../../CscListItem'
import CscListItemTitle from '../../CscListItemTitle'
import CscListItemSubtitle from '../../CscListItemSubtitle'
import CscListMenuItem from '../../CscListMenuItem'
import CscInputButtonSave from 'components/form/CscInputButtonSave'
import CscInputButtonReset from 'components/form/CscInputButtonReset'
import CscRemoveDialog from 'components/CscRemoveDialog'
import {
required
} from 'vuelidate/lib/validators'
export default {
name: 'CscPbxSettingsAutoAttendant',
components: {
CscInputButtonSave,
CscInputButtonReset,
CscListItem,
CscListItemTitle,
CscListItemSubtitle,
CscListMenuItem
},
props: {
personalSlot: {
type: Object,
default: null
},
addNewSlot: {
type: Boolean,
default: false
}
},
data () {
return {
expanded: this.addNewSlot,
hasDestinationChanged: false,
newDestination: this.personalSlot.destination,
currentDestination: this.personalSlot.destination
}
},
validations: {
newDestination: {
required
}
},
computed: {
errorMessage () {
if (!this.$v.newDestination.required) {
return this.$t('Destination must not be empty')
} else {
return ''
}
}
},
mounted () {
this.$root.$on('all-slots-saved', () => {
if (this.expanded) {
this.toggle()
}
this.newDestination = this.personalSlot.destination
this.currentDestination = this.personalSlot.destination
this.hasDestinationChanged = this.newDestination !== this.currentDestination
})
},
methods: {
confirmRowDeletion () {
if (!this.addNewSlot) {
this.$q.dialog({
component: CscRemoveDialog,
parent: this,
title: this.$t('Delete slot?'),
message: this.$t('You are about to delete slot {slot}', { slot: this.personalSlot.slot })
}).onOk(() => {
this.remove()
})
} else {
this.remove()
}
},
remove () {
this.$emit('remove', this.personalSlot.slot)
},
save () {
if (this.personalSlot.destination !== '') {
this.$emit('save')
}
},
toggle () {
this.expanded = !this.expanded
this.newDestination = this.personalSlot.destination
},
valueChanged () {
this.$v.newDestination.$touch()
this.hasDestinationChanged = this.newDestination !== this.currentDestination
this.$emit('edit', this.newDestination, this.personalSlot.slot)
},
resetSlotDestination () {
this.$emit('reset', this.personalSlot.slot)
this.newDestination = this.personalSlot.destination
this.hasDestinationChanged = false
}
}
}
</script>

@ -0,0 +1,215 @@
<template>
<csc-page-sticky
id="csc-page-call-forwarding"
class="q-pa-lg"
>
<template
v-slot:header
>
<q-btn-dropdown
size="md"
color="primary"
:label="$t('Add slot')"
:disabled="getAvailableSlots().length === 0"
icon="add"
dropdown-icon=" "
flat
>
<q-list
v-for="availableSlot in getAvailableSlots()"
:key="availableSlot"
>
<csc-popup-menu-item
:label="availableSlot"
@click="addSlot(availableSlot)"
/>
</q-list>
</q-btn-dropdown>
</template>
<div
class="text-center"
>
<csc-spinner
v-if="$wait.is('csc-pbx-auto-attendant') || $wait.is('csc-pbx-autoattendant-slots-table')"
/>
</div>
<csc-list
v-if="newPersonalSlots && newPersonalSlots.length > 0 && !$wait.is('csc-pbx-auto-attendant')
&& !$wait.is('csc-pbx-autoattendant-slots-table')"
>
<csc-fade
v-for="newSlot in newPersonalSlots"
:key="'csc-pbx-settings-fade-'+ newSlot.slot "
>
<csc-pbx-settings-auto-attendant
:add-new-slot="true"
:personal-slot="newSlot"
@save="saveSlot"
@remove="removeSlot"
@edit="editNewSlotDestination"
/>
</csc-fade>
</csc-list>
<csc-list
v-if="personalSlots.length > 0 && !$wait.is('csc-pbx-auto-attendant') && !$wait.is('csc-pbx-autoattendant-slots-table')"
>
<csc-fade
v-for="(personalSlot, index) in personalSlots"
:key="'csc-pbx-settings-fade-'+ personalSlot.slot "
>
<csc-pbx-settings-auto-attendant
v-model="personalSlots[index].destination"
:personal-slot="personalSlot"
@save="saveSlot"
@remove="removeSlot"
@edit="editNewSlotDestination"
@reset="resetPersonalSlot"
/>
</csc-fade>
</csc-list>
</csc-page-sticky>
</template>
<script>
import _ from 'lodash'
import CscPopupMenuItem from 'components/CscPopupMenuItem'
import CscPageSticky from 'components/CscPageSticky'
import CscPbxSettingsAutoAttendant from 'components/pages/PbxSettings/CscPbxSettingsAutoAttendant'
import CscList from 'components/CscList'
import CscFade from 'components/transitions/CscFade'
import CscSpinner from 'components/CscSpinner'
import { mapGetters } from 'vuex'
import { mapWaitingActions } from 'vue-wait'
import { getSubscriberId } from 'src/auth'
import { showGlobalError, showToast } from 'src/helpers/ui'
export default {
name: 'CscPagePbxSettingsAutoAttendant',
components: {
CscPageSticky,
CscPopupMenuItem,
CscPbxSettingsAutoAttendant,
CscList,
CscFade,
CscSpinner
},
data () {
return {
data: [],
subscriberId: parseInt(getSubscriberId()),
personalSlots: [],
newPersonalSlots: []
}
},
computed: {
...mapGetters('pbxAutoAttendants', [
'slots',
'slotsNumbers',
'newSlots'
])
},
async mounted () {
await this.fetchAutoAttendants()
this.personalSlots = _.cloneDeep(this.slots.filter(slot => slot.subscriber_id === this.subscriberId)[0]?.slots)
this.newPersonalSlots = _.cloneDeep(this.newSlots.filter(slot => slot.subscriber_id === this.subscriberId)[0].slots)
this.sortArrays()
},
methods: {
...mapWaitingActions('pbxAutoAttendants', {
updateSubscriberSlots: 'csc-pbx-autoattendant-slots-table',
resetAllNewSlots: 'csc-pbx-autoattendant-slots-table',
fetchAutoAttendants: 'csc-pbx-auto-attendant',
createNewSlot: 'csc-pbx-auto-attendant',
deleteNewSlot: 'csc-pbx-autoattendant-slots-table'
}),
getAvailableSlots () {
let subscriberSlots = this.slots.filter(slot => slot.subscriber_id === this.subscriberId)[0]?.slots
const subscriberSavedSlots = subscriberSlots?.map(item => item.slot)
const subscriberNewSlots = this.newSlots.filter(item => item.subscriber_id === this.subscriberId)
subscriberSlots = subscriberNewSlots.length > 0
? [...subscriberSavedSlots, ...subscriberNewSlots[0].slots.map(item => item.slot)]
: subscriberSavedSlots
const availableSlots = this.slotsNumbers.filter(slot => !subscriberSlots?.includes(slot))
return availableSlots
},
async saveSlot (isARemoval = false) {
for (const newSlot of this.newPersonalSlots) {
if (!newSlot.destination && !isARemoval) {
showGlobalError(this.$t('Please fill or remove the empty slots'))
return
}
}
if (!isARemoval) {
for (const newSlot of this.newPersonalSlots) {
this.updateLocalDestination(newSlot.slot, newSlot.destination)
}
}
await this.updateSubscriberSlots({
subscriberId: this.subscriberId,
slots: [...this.newPersonalSlots, ...this.personalSlots]
})
this.resetAllNewSlots(this.subscriberId)
this.personalSlots = _.cloneDeep(this.slots.filter(slot => slot.subscriber_id === this.subscriberId)[0]?.slots)
this.newPersonalSlots = _.cloneDeep(this.newSlots.filter(slot => slot.subscriber_id === this.subscriberId)[0].slots)
this.sortArrays()
showToast(this.$t('Slots saved successfully'))
this.$root.$emit('all-slots-saved')
},
removeSlot (slotToRemove) {
const foundIndex = this.newPersonalSlots.findIndex(item => item.slot === slotToRemove)
if (foundIndex === -1) {
this.personalSlots = this.personalSlots.filter((item) => item.slot !== slotToRemove)
this.saveSlot(true)
} else {
this.deleteNewSlot({
subscriberId: this.subscriberId,
index: foundIndex
})
this.newPersonalSlots.splice(foundIndex, 1)
}
},
addSlot (availableSlot) {
this.createNewSlot({
subscriberId: this.subscriberId,
slot: availableSlot
})
this.newPersonalSlots = _.cloneDeep(this.newSlots.filter(slot => slot.subscriber_id === this.subscriberId)[0].slots)
this.sortArrays()
},
updateLocalDestination (newPersonalSlot, newDestination) {
this.personalSlots.forEach((item) => {
if (item.slot === newPersonalSlot) {
item.destination = newDestination
}
})
if (this.newPersonalSlots) {
this.newPersonalSlots.forEach((item) => {
if (item.slot === newPersonalSlot) {
item.destination = newDestination
}
})
}
},
editNewSlotDestination (newDestination, newPersonalSlot) {
const foundIndexNewSlots = this.newPersonalSlots.findIndex(item => item.slot === newPersonalSlot)
if (foundIndexNewSlots !== -1) {
this.newPersonalSlots[foundIndexNewSlots].destination = newDestination
} else {
const foundIndexExistingSlots = this.personalSlots.findIndex(item => item.slot === newPersonalSlot)
this.personalSlots[foundIndexExistingSlots].destination = newDestination
if (foundIndexNewSlots !== -1) {
this.personalSlots[foundIndexExistingSlots].destination = newDestination
}
}
},
resetPersonalSlot (personalSlot) {
const slotsFiltered = this.slots.filter(slot => slot.subscriber_id === this.subscriberId)[0]?.slots
const foundIndex = slotsFiltered.findIndex(item => item.slot === personalSlot)
this.personalSlots[foundIndex].destination = slotsFiltered[foundIndex].destination
},
sortArrays () {
this.personalSlots.sort((a, b) => (a.slot > b.slot) ? 1 : ((b.slot > a.slot) ? -1 : 0))
this.newPersonalSlots.sort((a, b) => (a.slot > b.slot) ? 1 : ((b.slot > a.slot) ? -1 : 0))
}
}
}
</script>

@ -29,6 +29,7 @@ import CscRecoverPassword from 'src/pages/CscRecoverPassword'
import CscPageCf from 'pages/CscPageCf'
import CscPageCallSettings from 'pages/CscPageCallSettings'
import CscPageRegisteredDevices from 'pages/CscPageRegisteredDevices'
import CscPagePbxSettingsAutoAttendant from 'pages/CscPagePbxSettingsAutoAttendant'
const getToken = (route) => {
return {
@ -293,7 +294,7 @@ export default function routes (app) {
}
},
{
path: 'pbx-settings',
path: 'pbx-settings/general',
component: CscPagePbxSettings,
meta: {
get title () {
@ -305,6 +306,18 @@ export default function routes (app) {
profileAttribute: PROFILE_ATTRIBUTE_MAP.pbxSettings
}
},
{
path: 'pbx-settings/auto-attendant',
component: CscPagePbxSettingsAutoAttendant,
meta: {
get title () {
return i18n.t('PBX Settings')
},
get subtitle () {
return i18n.t('Auto-attendant')
}
}
},
{
path: 'registered-devices',
component: CscPageRegisteredDevices,

Loading…
Cancel
Save