You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ngcp-csc-ui/src/pages/CscPagePbxGroupDetails.vue

591 lines
20 KiB

<template>
<csc-page-sticky-tabs
id="csc-page-pbx-groups-details"
ref="pageSticky"
:value="selectedTab"
>
<template
#tabs
>
<q-breadcrumbs
class="q-item absolute absolute-left text-weight-light"
active-color="primary"
separator-color="primary"
>
<q-breadcrumbs-el
key="groups"
class="cursor-pointer"
to="/user/pbx-configuration/groups"
:label="$t('Groups')"
icon="group"
/>
<q-breadcrumbs-el
v-if="groupSelected"
key="group"
:label="groupSelected.display_name"
/>
</q-breadcrumbs>
<q-tab
v-for="tab in tabs"
:key="tab.value"
class="d-flex justify-content-center"
:name="tab.value"
:icon="tab.icon"
:label="tab.label"
:default="tab.value === selectedTab"
@click="selectTab(tab.value)"
/>
</template>
<q-item
v-if="selectedTab === 'preferences'"
class="col col-xs-12 col-md-6"
>
<q-list
v-if="changes"
class="col col-xs-12 col-md-6"
side
top
no-wrap
>
<q-input
v-model="changes.name"
:label="$t('Name')"
:disable="isLoading"
@keyup.enter="save"
>
<template
v-if="hasNameChanged"
#append
>
<csc-input-button-save
@click.stop="save"
/>
<csc-input-button-reset
@click.stop="resetName"
/>
</template>
</q-input>
<q-input
readonly
disable
:model-value="changes.sipUsername"
:label="$t('SIP Username')"
/>
<q-input
v-model="changes.extension"
hide-hint
:error="v$.changes.extension.$errors.length > 0"
:error-message="extensionErrorMessage"
:label="$t('Extension')"
:hint="getExtensionHint"
:disable="isLoading"
@keyup.enter="save"
@update:model-value="v$.changes.extension.$touch()"
>
<template
v-if="hasExtensionChanged"
#append
>
<csc-input-button-save
@click.stop="save"
/>
<csc-input-button-reset
@click.stop="resetExtension"
/>
</template>
</q-input>
<q-input
readonly
disable
:model-value="getPrimaryNumber"
:label="$t('Primary Number')"
/>
<q-select
v-model="changes.huntPolicy"
emit-value
map-options
radio
:label="$t('Hunt Policy')"
:disable="isLoading"
:options="getHuntPolicyOptions"
>
<template
v-if="hasHuntPolicyChanged"
#append
>
<csc-input-button-save
@click.stop="save"
/>
<csc-input-button-reset
@click.stop="resetHuntPolicy"
/>
</template>
</q-select>
<q-input
v-model="changes.huntTimeout"
:label="$t('Hunt Timeout')"
:disable="isLoading"
@keyup.enter="save"
>
<template
v-if="hasHuntTimeoutChanged"
#append
>
<csc-input-button-save
@click.stop="save"
/>
<csc-input-button-reset
@click.stop="resetHuntTimeout"
/>
</template>
</q-input>
<q-select
v-model="changes.huntCancelMode"
emit-value
map-options
radio
:label="$t('Cancel Mode')"
:disable="isLoading"
:options="getHuntCancelModeOptions"
>
<template
v-if="hasHuntCancelModeChanged"
#append
>
<csc-input-button-save
@click.stop="save"
/>
<csc-input-button-reset
@click.stop="resetHuntCancelMode"
/>
</template>
</q-select>
<q-select
v-model="changes.aliasNumbers"
emit-value
map-options
use-chips
multiple
:disable="isLoading"
:label="$t('Alias Numbers')"
:options="getNumberOptions"
>
<template
v-if="hasAliasNumbersChanged"
#append
>
<csc-input-button-save
@click.stop="save"
/>
<csc-input-button-reset
@click.stop="resetAliasNumbers"
/>
</template>
</q-select>
<q-select
v-model="changes.seats"
emit-value
map-options
use-chips
multiple
:disable="isLoading"
:label="$t('Seats')"
:options="getSeatOptions"
>
<template
v-if="hasSeatsChanged"
#append
>
<csc-input-button-save
@click.stop="save"
/>
<csc-input-button-reset
@click.stop="resetSeats"
/>
</template>
</q-select>
<q-select
v-model="changes.soundSet"
emit-value
map-options
radio
:disable="isLoading"
:label="$t('Sound Set')"
:options="getSoundSetOptions"
>
<template
v-if="hasSoundSetChanged"
#append
>
<csc-input-button-save
@click.stop="save"
/>
<csc-input-button-reset
@click.stop="resetSoundSet"
/>
</template>
</q-select>
<q-btn
v-if="hasCallQueue(id)"
icon="filter_none"
flat
color="primary"
:label="$t('Call Queue')"
:disable="isLoading"
@click="jumpToCallQueueInternal"
/>
</q-list>
</q-item>
<csc-call-forward-details
v-if="selectedTab === 'callForwards'"
:id="id"
:key="id"
/>
<csc-page-voicebox
v-if="selectedTab === 'voicebox'"
:id="id"
:key="id"
/>
<csc-fax-to-mail-settings
v-if="selectedTab === 'fax2mail'"
:id="id"
:key="id"
/>
<csc-mail-to-fax-settings
v-if="selectedTab === 'mail2fax'"
:id="id"
:key="id"
/>
</csc-page-sticky-tabs>
</template>
<script>
import _ from 'lodash'
import { inRange } from 'src/helpers/validation'
import {
mapState,
mapMutations,
mapGetters,
mapActions
} from 'vuex'
import {
RequestState
} from 'src/store/common'
import {
showGlobalError,
showToast
} from 'src/helpers/ui'
import numberFilter from 'src/filters/number'
import CscPageStickyTabs from 'components/CscPageStickyTabs'
import CscInputButtonSave from 'components/form/CscInputButtonSave'
import CscInputButtonReset from 'components/form/CscInputButtonReset'
import CscCallForwardDetails from 'components/pages/CallForward/CscCallForwardDetails.vue'
import CscFaxToMailSettings from 'components/pages/FaxSettings/CscFaxToMailSettings'
import CscPageVoicebox from 'src/pages/CscPageVoicebox.vue'
import CscMailToFaxSettings from 'components/pages/FaxSettings/CscMailToFaxSettings'
import useValidate from '@vuelidate/core'
export default {
name: 'CscPagePbxGroupDetails',
components: {
CscInputButtonReset,
CscInputButtonSave,
CscPageStickyTabs,
CscCallForwardDetails,
CscPageVoicebox,
CscFaxToMailSettings,
CscMailToFaxSettings
},
props: {
initialTab: {
type: String,
default: 'preferences'
}
},
data () {
return {
changes: null,
id: this.$route.params.id,
soundSet: null,
selectedTab: this.initialTab,
v$: useValidate()
}
},
computed: {
tabs () {
return [
{
label: this.$t('Preferences'),
value: 'preferences',
icon: 'perm_phone_msg'
},
{
label: this.$t('Call Forwards'),
value: 'callForwards',
icon: 'forward_to_inbox'
},
{
label: this.$t('Voicebox'),
value: 'voicebox',
icon: 'voicemail'
},
{
label: this.$t('Fax to mail and sendfax'),
value: 'fax2mail',
icon: 'perm_phone_msg'
},
{
label: this.$t('Mail to Fax'),
value: 'mail2fax',
icon: 'forward_to_inbox'
}
]
},
...mapState('pbxGroups', [
'groupSelected',
'groupUpdateState',
'groupUpdateError'
]),
...mapGetters('pbx', [
'getSeatOptions',
'getExtensionHint',
'getMinAllowedExtension',
'getMaxAllowedExtension',
'getNumberOptions',
'getSoundSetOptions'
]),
...mapGetters('pbxGroups', [
'getHuntPolicyOptions',
'hasCallQueue',
'getGroupUpdateToastMessage',
'getSoundSetByGroupId',
'isGroupLoading',
'getHuntCancelModeOptions'
]),
...mapGetters('callForwarding', [
'groups'
]),
hasNameChanged () {
return this.changes.name !== this.groupSelected.display_name
},
hasExtensionChanged () {
return this.changes.extension !== this.groupSelected.pbx_extension
},
hasHuntPolicyChanged () {
return this.changes.huntPolicy !== this.groupSelected.pbx_hunt_policy
},
hasHuntTimeoutChanged () {
return this.changes.huntTimeout !== this.groupSelected.pbx_hunt_timeout
},
hasHuntCancelModeChanged () {
return this.changes.huntCancelMode !== this.groupSelected.pbx_hunt_cancel_mode
},
hasAliasNumbersChanged () {
const aliasNumbers = _.clone(this.changes.aliasNumbers)
return !_.isEqual(aliasNumbers.sort(), this.getAliasNumberIds().sort())
},
hasSeatsChanged () {
const seatIds1 = _.clone(this.changes.seats)
const seatIds2 = _.clone(this.groupSelected.pbx_groupmember_ids)
return !_.isEqual(seatIds1.sort(), seatIds2.sort())
},
hasSoundSetChanged () {
return this.changes.soundSet !== this.getSoundSetId()
},
getPrimaryNumber () {
return numberFilter(this.groupSelected.primary_number)
},
extensionErrorMessage () {
const errorsTab = this.v$.changes.extension.$errors
if (errorsTab && errorsTab.length > 0 && errorsTab[0].$validator === 'isInRange') {
return this.getExtensionHint
} else {
return ''
}
},
isLoading () {
return this.isGroupLoading(this.groupSelected.id)
}
},
watch: {
async $route (to) {
if (this.id !== to.params.id) {
this.id = to.params.id
this.selectGroup(this.id)
await this.loadMappingsFull(this.id)
}
},
groupSelected () {
this.changes = this.getGroupData()
this.soundSet = this.getSoundSetByGroupId(this.groupSelected.id)
},
groupUpdateState (state) {
if (state === RequestState.succeeded) {
showToast(this.getGroupUpdateToastMessage)
} else if (state === RequestState.failed) {
showGlobalError(this.groupUpdateError)
}
}
},
async mounted () {
this.selectGroup(this.id)
await this.loadMappingsFull(this.id)
},
beforeUnmount () {
this.resetSelectedGroup()
},
validations: {
changes: {
extension: {
isInRange: function (value) {
return inRange(value, this.getMinAllowedExtension, this.getMaxAllowedExtension)
}
}
}
},
methods: {
...mapActions('pbxGroups', [
'setGroupName',
'setGroupExtension',
'setGroupHuntPolicy',
'setGroupHuntTimeout',
'setGroupHuntCancelMode',
'setGroupSeats',
'setGroupNumbers',
'setGroupSoundSet'
]),
...mapActions('pbxCallQueues', [
'jumpToCallQueue'
]),
...mapActions('callForwarding', [
'loadMappingsFull',
'createMapping'
]),
...mapMutations('pbxGroups', [
'selectGroup',
'resetSelectedGroup'
]),
getGroupData () {
return (this.groupSelected)
? {
name: this.groupSelected.display_name,
sipUsername: this.groupSelected.username,
extension: this.groupSelected.pbx_extension,
huntPolicy: this.groupSelected.pbx_hunt_policy,
huntTimeout: this.groupSelected.pbx_hunt_timeout,
huntCancelMode: this.groupSelected.pbx_hunt_cancel_mode,
aliasNumbers: this.getAliasNumberIds(),
seats: this.getSeatIds(),
soundSet: this.getSoundSetId()
}
: null
},
getAliasNumberIds () {
const numberIds = []
this.groupSelected.alias_numbers.forEach((number) => {
numberIds.push(number.number_id)
})
return numberIds
},
getSeatIds () {
return _.clone(this.groupSelected.pbx_groupmember_ids)
},
getSoundSetId () {
const soundSet = this.getSoundSetByGroupId(this.groupSelected.id)
if (soundSet !== null) {
return soundSet.id
}
return null
},
resetName () {
this.changes.name = this.groupSelected.display_name
},
resetExtension () {
this.changes.extension = this.groupSelected.pbx_extension
},
resetHuntPolicy () {
this.changes.huntPolicy = this.groupSelected.pbx_hunt_policy
},
resetHuntTimeout () {
this.changes.huntTimeout = this.groupSelected.pbx_hunt_timeout
},
resetHuntCancelMode () {
this.changes.huntCancelMode = this.groupSelected.pbx_hunt_cancel_mode
},
resetAliasNumbers () {
this.changes.aliasNumbers = this.getAliasNumberIds()
},
resetSeats () {
this.changes.seats = this.getSeatIds()
},
resetSoundSet () {
this.changes.soundSet = this.getSoundSetId()
},
jumpToCallQueueInternal () {
this.jumpToCallQueue(this.groupSelected)
},
save () {
if (this.hasNameChanged) {
this.setGroupName({
groupId: this.groupSelected.id,
groupName: this.changes.name
})
}
if (this.hasExtensionChanged) {
this.setGroupExtension({
groupId: this.groupSelected.id,
groupExtension: this.changes.extension
})
}
if (this.hasHuntPolicyChanged) {
this.setGroupHuntPolicy({
groupId: this.groupSelected.id,
groupHuntPolicy: this.changes.huntPolicy
})
}
if (this.hasHuntTimeoutChanged) {
this.setGroupHuntTimeout({
groupId: this.groupSelected.id,
groupHuntTimeout: this.changes.huntTimeout
})
}
if (this.hasHuntCancelModeChanged) {
this.setGroupHuntCancelMode({
groupId: this.groupSelected.id,
groupHuntCancelMode: this.changes.huntCancelMode
})
}
if (this.hasAliasNumbersChanged) {
this.setGroupNumbers({
groupId: this.groupSelected.id,
assignedNumbers: _.difference(this.changes.aliasNumbers, this.getAliasNumberIds()),
unassignedNumbers: _.difference(this.getAliasNumberIds(), this.changes.aliasNumbers)
})
}
if (this.hasSeatsChanged) {
this.setGroupSeats({
groupId: this.groupSelected.id,
seatIds: this.changes.seats
})
}
if (this.hasSoundSetChanged) {
this.setGroupSoundSet({
groupId: this.groupSelected.id,
soundSetId: this.changes.soundSet
})
}
},
selectTab (tabName) {
if (this.selectedTab !== tabName) {
this.forceTabReload(tabName)
}
},
forceTabReload (tabName) {
this.selectedTab = tabName
}
}
}
</script>