TT#124272 AutoAttendant - As PBX-Attendant (Pilot, Seat, Group), I can change my AutoAttendant configuration
Change-Id: If6238f053f44e4b880dfbbe03d8b44e5e65ce8d9mr10.0
parent
a282cd29ae
commit
17f2345b30
@ -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>
|
Loading…
Reference in new issue