AC: Can add forwarding Can alter forwarding Can remove forwarding Can enable forwarding Can disable forwarding Can enable that primary number rings Can disable that primary number rings Can forward to Number Can forward to Voicebox Can forward to Fax2Mail Can forward to ManagerSecretary Can forward to Conference Can create SourceSet Can assign number to SourceSet Can remove number from SourceSet Can change name of the SourceSet Can search for existing SourceSets Can assign an existing SourceSet Can assign TimeSet (Date) Can delete TimeSet (Date) Can assign TimeSet (Date range) Can delete TimeSet (Date range) Can assign TimeSet (Weekdays) Can delete TimeSet (Weekdays) Can assign TimeSet (Office Hours) Can delete TimeSet (Office Hours) Change-Id: If5e5267e229a20947e0278212f59349d9e2eb7bepull/4/head
parent
1c839a7f84
commit
c3a278f992
@ -0,0 +1,323 @@
|
||||
import {
|
||||
del,
|
||||
get,
|
||||
getList, patchReplace, post, putMinimal
|
||||
} from 'src/api/common'
|
||||
import {
|
||||
v4
|
||||
} from 'uuid'
|
||||
|
||||
export async function cfLoadMappings (subscriberId) {
|
||||
return get({
|
||||
resource: 'cfmappings',
|
||||
resourceId: subscriberId
|
||||
})
|
||||
}
|
||||
|
||||
export async function cfLoadDestinationSets (subscriberId) {
|
||||
return getList({
|
||||
resource: 'cfdestinationsets',
|
||||
all: true,
|
||||
params: {
|
||||
subscriber_id: subscriberId
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export async function cfLoadSourceSets (subscriberId) {
|
||||
return getList({
|
||||
resource: 'cfsourcesets',
|
||||
params: {
|
||||
subscriber_id: subscriberId
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export async function cfLoadTimeSets (subscriberId) {
|
||||
return getList({
|
||||
resource: 'cftimesets',
|
||||
params: {
|
||||
subscriber_id: subscriberId
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export async function cfLoadMappingsFull (subscriberId) {
|
||||
return await Promise.all([
|
||||
cfLoadMappings(subscriberId),
|
||||
cfLoadDestinationSets(subscriberId),
|
||||
cfLoadSourceSets(subscriberId),
|
||||
cfLoadTimeSets(subscriberId)
|
||||
])
|
||||
}
|
||||
|
||||
export async function cfCreateDestinationSet (payload) {
|
||||
return post({
|
||||
resource: 'cfdestinationsets',
|
||||
body: payload
|
||||
})
|
||||
}
|
||||
|
||||
export async function cfDeleteDestinationSet (id) {
|
||||
return del({
|
||||
resource: 'cfdestinationsets',
|
||||
resourceId: id
|
||||
})
|
||||
}
|
||||
|
||||
export async function cfCreateSourceSet (id, payload) {
|
||||
const sources = []
|
||||
payload.numbers.forEach((number) => {
|
||||
sources.push({
|
||||
source: number
|
||||
})
|
||||
})
|
||||
return post({
|
||||
resource: 'cfsourcesets',
|
||||
body: {
|
||||
name: payload.name,
|
||||
subscriber_id: id,
|
||||
is_regex: true,
|
||||
sources: sources,
|
||||
mode: payload.mode
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export async function cfUpdateSourceSet (id, payload) {
|
||||
const sources = []
|
||||
payload.numbers.forEach((number) => {
|
||||
sources.push({
|
||||
source: number
|
||||
})
|
||||
})
|
||||
return putMinimal({
|
||||
resource: 'cfsourcesets',
|
||||
resourceId: payload.id,
|
||||
body: {
|
||||
name: payload.name,
|
||||
subscriber_id: id,
|
||||
is_regex: true,
|
||||
sources: sources,
|
||||
mode: payload.mode
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export async function cfDeleteSourceSet (id) {
|
||||
return del({
|
||||
resource: 'cfsourcesets',
|
||||
resourceId: id
|
||||
})
|
||||
}
|
||||
|
||||
export async function cfCreateTimeSetDate (subscriberId, date) {
|
||||
return post({
|
||||
resource: 'cftimesets',
|
||||
body: {
|
||||
subscriber_id: subscriberId,
|
||||
name: 'csc-date-exact-' + v4(),
|
||||
times: [
|
||||
{
|
||||
minute: null,
|
||||
month: date.month,
|
||||
hour: null,
|
||||
mday: date.date,
|
||||
year: date.year,
|
||||
wday: null
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export async function cfUpdateTimeSetDate (timeSetId, date) {
|
||||
return patchReplace({
|
||||
resource: 'cftimesets',
|
||||
resourceId: timeSetId,
|
||||
fieldPath: 'times',
|
||||
value: [
|
||||
{
|
||||
minute: null,
|
||||
month: date.month,
|
||||
hour: null,
|
||||
mday: date.date,
|
||||
year: date.year,
|
||||
wday: null
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
export async function cfDeleteTimeSet (timesetId) {
|
||||
return del({
|
||||
resource: 'cftimesets',
|
||||
resourceId: timesetId
|
||||
})
|
||||
}
|
||||
|
||||
export async function cfCreateTimeSetDateRange (subscriberId, date) {
|
||||
return post({
|
||||
resource: 'cftimesets',
|
||||
body: {
|
||||
subscriber_id: subscriberId,
|
||||
name: 'csc-date-range-' + v4(),
|
||||
times: [
|
||||
{
|
||||
minute: null,
|
||||
month: date.from.month + '-' + date.to.month,
|
||||
hour: null,
|
||||
mday: date.from.date + '-' + date.to.date,
|
||||
year: date.from.year + '-' + date.to.year,
|
||||
wday: null
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export async function cfUpdateTimeSetDateRange (timeSetId, date) {
|
||||
return patchReplace({
|
||||
resource: 'cftimesets',
|
||||
resourceId: timeSetId,
|
||||
fieldPath: 'times',
|
||||
value: [
|
||||
{
|
||||
minute: null,
|
||||
month: date.from.month + '-' + date.to.month,
|
||||
hour: null,
|
||||
mday: date.from.date + '-' + date.to.date,
|
||||
year: date.from.year + '-' + date.to.year,
|
||||
wday: null
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
export async function cfCreateTimeSetWeekdays (subscriberId, weekdays) {
|
||||
const times = []
|
||||
weekdays.forEach((weekday) => {
|
||||
times.push({
|
||||
minute: null,
|
||||
month: null,
|
||||
hour: null,
|
||||
mday: null,
|
||||
year: null,
|
||||
wday: weekday
|
||||
})
|
||||
})
|
||||
return post({
|
||||
resource: 'cftimesets',
|
||||
body: {
|
||||
subscriber_id: subscriberId,
|
||||
name: 'csc-weekdays-' + v4(),
|
||||
times: times
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export async function cfUpdateTimeSetWeekdays (timeSetId, weekdays) {
|
||||
const times = []
|
||||
weekdays.forEach((weekday) => {
|
||||
times.push({
|
||||
minute: null,
|
||||
month: null,
|
||||
hour: null,
|
||||
mday: null,
|
||||
year: null,
|
||||
wday: weekday
|
||||
})
|
||||
})
|
||||
return patchReplace({
|
||||
resource: 'cftimesets',
|
||||
resourceId: timeSetId,
|
||||
fieldPath: 'times',
|
||||
value: times
|
||||
})
|
||||
}
|
||||
|
||||
function cfNormaliseOfficeHours (timesPerWeekday) {
|
||||
const normalisedTimes = []
|
||||
timesPerWeekday.forEach((times, index) => {
|
||||
times.forEach((time) => {
|
||||
if (time.from !== '' && time.to !== '') {
|
||||
const fromParts = time.from.split(':')
|
||||
const toParts = time.to.split(':')
|
||||
if (fromParts[0] !== '__' && fromParts[1] !== '__' && toParts[0] !== '__' && toParts[1] !== '__') {
|
||||
normalisedTimes.push({
|
||||
minute: fromParts[1] + '-' + toParts[1],
|
||||
month: null,
|
||||
hour: fromParts[0] + '-' + toParts[0],
|
||||
mday: null,
|
||||
year: null,
|
||||
wday: (index + 1)
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
return normalisedTimes
|
||||
}
|
||||
|
||||
export async function cfCreateOfficeHours (subscriberId, timesPerWeekday) {
|
||||
return post({
|
||||
resource: 'cftimesets',
|
||||
body: {
|
||||
subscriber_id: subscriberId,
|
||||
name: 'csc-office-hours-' + v4(),
|
||||
times: cfNormaliseOfficeHours(timesPerWeekday)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export async function cfUpdateOfficeHours (timeSetId, timesPerWeekday) {
|
||||
return patchReplace({
|
||||
resource: 'cftimesets',
|
||||
resourceId: timeSetId,
|
||||
fieldPath: 'times',
|
||||
value: cfNormaliseOfficeHours(timesPerWeekday)
|
||||
})
|
||||
}
|
||||
|
||||
function cfNormaliseOfficeHoursSameTimes (times, weekdays) {
|
||||
const normalisedTimes = []
|
||||
weekdays.forEach((weekday) => {
|
||||
times.forEach((time) => {
|
||||
if (time.from !== '' && time.to !== '') {
|
||||
const fromParts = time.from.split(':')
|
||||
const toParts = time.to.split(':')
|
||||
if (fromParts[0] !== '__' && fromParts[1] !== '__' && toParts[0] !== '__' && toParts[1] !== '__') {
|
||||
normalisedTimes.push({
|
||||
minute: fromParts[1] + '-' + toParts[1],
|
||||
month: null,
|
||||
hour: fromParts[0] + '-' + toParts[0],
|
||||
mday: null,
|
||||
year: null,
|
||||
wday: weekday
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
return normalisedTimes
|
||||
}
|
||||
|
||||
export async function cfCreateOfficeHoursSameTimes (subscriberId, times, weekdays) {
|
||||
return post({
|
||||
resource: 'cftimesets',
|
||||
body: {
|
||||
subscriber_id: subscriberId,
|
||||
name: 'csc-office-hours-same-times-' + v4(),
|
||||
times: cfNormaliseOfficeHoursSameTimes(times, weekdays)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export async function cfUpdateOfficeHoursSameTimes (timeSetId, times, weekdays) {
|
||||
return patchReplace({
|
||||
resource: 'cftimesets',
|
||||
resourceId: timeSetId,
|
||||
fieldPath: 'times',
|
||||
value: cfNormaliseOfficeHoursSameTimes(times, weekdays)
|
||||
})
|
||||
}
|
||||
@ -0,0 +1,202 @@
|
||||
<template>
|
||||
<q-popup-proxy
|
||||
ref="popup"
|
||||
persistent
|
||||
anchor="bottom middle"
|
||||
self="top middle"
|
||||
@before-show="beforeShow"
|
||||
>
|
||||
<csc-cf-group-condition-menu
|
||||
v-if="internalStep === 'menu'"
|
||||
:mapping="mapping"
|
||||
:destination-set="destinationSet"
|
||||
:source-set="sourceSet"
|
||||
:time-set="timeSet"
|
||||
@step="internalStep=$event"
|
||||
@close="closePopup"
|
||||
/>
|
||||
<csc-cf-group-condition-source-set-create
|
||||
v-if="internalStep === 'call-from'"
|
||||
mode="whitelist"
|
||||
:title="$t('call from ...')"
|
||||
icon="person_add"
|
||||
:back-button="true"
|
||||
:mapping="mapping"
|
||||
:destination-set="destinationSet"
|
||||
:source-set="sourceSet"
|
||||
:time-set="timeSet"
|
||||
@back="internalStep='menu'"
|
||||
@select="internalStep='call-from-select'"
|
||||
@close="closePopup"
|
||||
/>
|
||||
<csc-cf-group-condition-source-set-select
|
||||
v-if="internalStep === 'call-from-select'"
|
||||
mode="whitelist"
|
||||
:title="$t('call from ...')"
|
||||
icon="person_add"
|
||||
:create-label="$t('Create List')"
|
||||
:back-button="true"
|
||||
:mapping="mapping"
|
||||
:destination-set="destinationSet"
|
||||
:source-set="sourceSet"
|
||||
:time-set="timeSet"
|
||||
@back="internalStep='call-from'"
|
||||
@create="internalStep='call-from'"
|
||||
@close="closePopup"
|
||||
/>
|
||||
<csc-cf-group-condition-source-set-create
|
||||
v-if="internalStep === 'call-not-from'"
|
||||
mode="blacklist"
|
||||
:title="$t('call not from ...')"
|
||||
icon="person_add_disabled"
|
||||
:back-button="true"
|
||||
:mapping="mapping"
|
||||
:destination-set="destinationSet"
|
||||
:source-set="sourceSet"
|
||||
:time-set="timeSet"
|
||||
@back="internalStep='menu'"
|
||||
@select="internalStep='call-not-from-select'"
|
||||
@close="closePopup"
|
||||
/>
|
||||
<csc-cf-group-condition-source-set-select
|
||||
v-if="internalStep === 'call-not-from-select'"
|
||||
mode="blacklist"
|
||||
:title="$t('call not from ...')"
|
||||
icon="person_add_disabled"
|
||||
:create-label="$t('Create List')"
|
||||
:back-button="true"
|
||||
:mapping="mapping"
|
||||
:destination-set="destinationSet"
|
||||
:source-set="sourceSet"
|
||||
:time-set="timeSet"
|
||||
@back="internalStep='call-not-from'"
|
||||
@create="internalStep='call-not-from'"
|
||||
@close="closePopup"
|
||||
/>
|
||||
<csc-cf-group-condition-date
|
||||
v-if="internalStep === 'date-is'"
|
||||
:back-button="true"
|
||||
:mapping="mapping"
|
||||
:destination-set="destinationSet"
|
||||
:source-set="sourceSet"
|
||||
:time-set="timeSet"
|
||||
@back="internalStep='menu'"
|
||||
@close="closePopup"
|
||||
/>
|
||||
<csc-cf-group-condition-date-range
|
||||
v-if="internalStep === 'date-range-is'"
|
||||
:back-button="true"
|
||||
:mapping="mapping"
|
||||
:destination-set="destinationSet"
|
||||
:source-set="sourceSet"
|
||||
:time-set="timeSet"
|
||||
@back="internalStep='menu'"
|
||||
@close="closePopup"
|
||||
/>
|
||||
<csc-cf-group-condition-weekdays
|
||||
v-if="internalStep === 'date-weekdays'"
|
||||
:back-button="true"
|
||||
:mapping="mapping"
|
||||
:destination-set="destinationSet"
|
||||
:source-set="sourceSet"
|
||||
:time-set="timeSet"
|
||||
@back="internalStep='menu'"
|
||||
@close="closePopup"
|
||||
/>
|
||||
<csc-cf-group-condition-office-hours
|
||||
v-if="internalStep.startsWith('office-hours')"
|
||||
:step="internalStep"
|
||||
:back-button="true"
|
||||
:mapping="mapping"
|
||||
:destination-set="destinationSet"
|
||||
:source-set="sourceSet"
|
||||
:time-set="timeSet"
|
||||
@navigate="navigate"
|
||||
@back="internalStep='menu'"
|
||||
@close="closePopup"
|
||||
/>
|
||||
</q-popup-proxy>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CscCfGroupConditionMenu from 'components/call-forwarding/CscCfGroupConditionMenu'
|
||||
import CscCfGroupConditionSourceSetCreate from 'components/call-forwarding/CscCfGroupConditionSourceSetCreate'
|
||||
import CscCfGroupConditionSourceSetSelect from 'components/call-forwarding/CscCfGroupConditionSourceSetSelect'
|
||||
import CscCfGroupConditionDate from 'components/call-forwarding/CscCfGroupConditionDate'
|
||||
import CscCfGroupConditionDateRange from 'components/call-forwarding/CscCfGroupConditionDateRange'
|
||||
import CscCfGroupConditionWeekdays from 'components/call-forwarding/CscCfGroupConditionWeekdays'
|
||||
import CscCfGroupConditionOfficeHours from 'components/call-forwarding/CscCfGroupConditionOfficeHours'
|
||||
export default {
|
||||
name: 'CscCfConditionPopupAll',
|
||||
components: {
|
||||
CscCfGroupConditionOfficeHours,
|
||||
CscCfGroupConditionWeekdays,
|
||||
CscCfGroupConditionDateRange,
|
||||
CscCfGroupConditionDate,
|
||||
CscCfGroupConditionSourceSetSelect,
|
||||
CscCfGroupConditionSourceSetCreate,
|
||||
CscCfGroupConditionMenu
|
||||
},
|
||||
props: {
|
||||
step: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
mapping: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
destinationSet: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
sourceSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
timeSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
closed: false,
|
||||
internalStep: this.step,
|
||||
selectedSourceSet: null
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
internalStep () {
|
||||
if (!this.closed) {
|
||||
this.$refs.popup.hide()
|
||||
this.$nextTick(() => {
|
||||
this.$refs.popup.show()
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
beforeShow () {
|
||||
this.closed = false
|
||||
},
|
||||
closePopup () {
|
||||
this.closed = true
|
||||
this.internalStep = 'menu'
|
||||
this.$refs.popup.hide()
|
||||
},
|
||||
openPopup () {
|
||||
if (!this.closed) {
|
||||
this.$refs.popup.hide()
|
||||
this.$nextTick(() => {
|
||||
this.$refs.popup.show()
|
||||
})
|
||||
}
|
||||
},
|
||||
navigate (step) {
|
||||
this.internalStep = step
|
||||
this.openPopup()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,96 @@
|
||||
<template>
|
||||
<q-popup-proxy
|
||||
ref="popup"
|
||||
persistent
|
||||
anchor="bottom middle"
|
||||
self="top middle"
|
||||
@before-show="beforeShow"
|
||||
>
|
||||
<csc-cf-group-condition-source-set-create
|
||||
v-if="internalStep === 'call-from'"
|
||||
mode="whitelist"
|
||||
:title="$t('call from ...')"
|
||||
icon="person_add"
|
||||
:back-button="false"
|
||||
:delete-button="true"
|
||||
:unassign-button="true"
|
||||
:mapping="mapping"
|
||||
:destination-set="destinationSet"
|
||||
:source-set="sourceSet"
|
||||
:time-set="timeSet"
|
||||
@select="internalStep='call-from-select'"
|
||||
@close="closePopup"
|
||||
/>
|
||||
<csc-cf-group-condition-source-set-select
|
||||
v-if="internalStep === 'call-from-select'"
|
||||
mode="whitelist"
|
||||
:title="$t('call from ...')"
|
||||
icon="person_add"
|
||||
:create-label="$t('Edit List')"
|
||||
:back-button="true"
|
||||
:mapping="mapping"
|
||||
:destination-set="destinationSet"
|
||||
:source-set="sourceSet"
|
||||
:time-set="timeSet"
|
||||
@back="internalStep='call-from'"
|
||||
@create="internalStep='call-from'"
|
||||
@close="closePopup"
|
||||
/>
|
||||
</q-popup-proxy>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CscCfGroupConditionSourceSetCreate from 'components/call-forwarding/CscCfGroupConditionSourceSetCreate'
|
||||
import CscCfGroupConditionSourceSetSelect from 'components/call-forwarding/CscCfGroupConditionSourceSetSelect'
|
||||
export default {
|
||||
name: 'CscCfConditionPopupCallFrom',
|
||||
components: {
|
||||
CscCfGroupConditionSourceSetSelect,
|
||||
CscCfGroupConditionSourceSetCreate
|
||||
},
|
||||
props: {
|
||||
mapping: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
destinationSet: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
sourceSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
timeSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
internalStep: 'call-from',
|
||||
selectedSourceSet: null
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
internalStep () {
|
||||
if (!this.closed) {
|
||||
this.$refs.popup.hide()
|
||||
this.$nextTick(() => {
|
||||
this.$refs.popup.show()
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
beforeShow () {
|
||||
this.closed = false
|
||||
},
|
||||
closePopup () {
|
||||
this.closed = true
|
||||
this.internalStep = 'call-from'
|
||||
this.$refs.popup.hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,96 @@
|
||||
<template>
|
||||
<q-popup-proxy
|
||||
ref="popup"
|
||||
persistent
|
||||
anchor="bottom middle"
|
||||
self="top middle"
|
||||
@before-show="beforeShow"
|
||||
>
|
||||
<csc-cf-group-condition-source-set-create
|
||||
v-if="internalStep === 'call-not-from'"
|
||||
mode="blacklist"
|
||||
:title="$t('call not from ...')"
|
||||
icon="person_add_disabled"
|
||||
:back-button="false"
|
||||
:delete-button="true"
|
||||
:unassign-button="true"
|
||||
:mapping="mapping"
|
||||
:destination-set="destinationSet"
|
||||
:source-set="sourceSet"
|
||||
:time-set="timeSet"
|
||||
@select="internalStep='call-not-from-select'"
|
||||
@close="closePopup"
|
||||
/>
|
||||
<csc-cf-group-condition-source-set-select
|
||||
v-if="internalStep === 'call-not-from-select'"
|
||||
mode="blacklist"
|
||||
:title="$t('call not from ...')"
|
||||
icon="person_add_disabled"
|
||||
:create-label="$t('Edit List')"
|
||||
:back-button="true"
|
||||
:mapping="mapping"
|
||||
:destination-set="destinationSet"
|
||||
:source-set="sourceSet"
|
||||
:time-set="timeSet"
|
||||
@back="internalStep='call-not-from'"
|
||||
@create="internalStep='call-not-from'"
|
||||
@close="closePopup"
|
||||
/>
|
||||
</q-popup-proxy>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CscCfGroupConditionSourceSetCreate from 'components/call-forwarding/CscCfGroupConditionSourceSetCreate'
|
||||
import CscCfGroupConditionSourceSetSelect from 'components/call-forwarding/CscCfGroupConditionSourceSetSelect'
|
||||
export default {
|
||||
name: 'CscCfConditionPopupCallNotFrom',
|
||||
components: {
|
||||
CscCfGroupConditionSourceSetSelect,
|
||||
CscCfGroupConditionSourceSetCreate
|
||||
},
|
||||
props: {
|
||||
mapping: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
destinationSet: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
sourceSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
timeSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
internalStep: 'call-not-from',
|
||||
selectedSourceSet: null
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
internalStep () {
|
||||
if (!this.closed) {
|
||||
this.$refs.popup.hide()
|
||||
this.$nextTick(() => {
|
||||
this.$refs.popup.show()
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
beforeShow () {
|
||||
this.closed = false
|
||||
},
|
||||
closePopup () {
|
||||
this.closed = true
|
||||
this.internalStep = 'call-not-from'
|
||||
this.$refs.popup.hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<q-popup-proxy
|
||||
ref="popup"
|
||||
persistent
|
||||
anchor="bottom middle"
|
||||
self="top middle"
|
||||
@before-show="beforeShow"
|
||||
>
|
||||
<csc-cf-group-condition-date
|
||||
:mapping="mapping"
|
||||
:destination-set="destinationSet"
|
||||
:source-set="sourceSet"
|
||||
:time-set="timeSet"
|
||||
:delete-button="true"
|
||||
@close="closePopup"
|
||||
/>
|
||||
</q-popup-proxy>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CscCfGroupConditionDate from 'components/call-forwarding/CscCfGroupConditionDate'
|
||||
export default {
|
||||
name: 'CscCfConditionPopupDate',
|
||||
components: {
|
||||
CscCfGroupConditionDate
|
||||
},
|
||||
props: {
|
||||
mapping: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
destinationSet: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
sourceSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
timeSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
beforeShow () {
|
||||
this.closed = false
|
||||
},
|
||||
closePopup () {
|
||||
this.closed = true
|
||||
this.$refs.popup.hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<q-popup-proxy
|
||||
ref="popup"
|
||||
persistent
|
||||
anchor="bottom middle"
|
||||
self="top middle"
|
||||
@before-show="beforeShow"
|
||||
>
|
||||
<csc-cf-group-condition-date-range
|
||||
:mapping="mapping"
|
||||
:destination-set="destinationSet"
|
||||
:source-set="sourceSet"
|
||||
:time-set="timeSet"
|
||||
:delete-button="true"
|
||||
@close="closePopup"
|
||||
/>
|
||||
</q-popup-proxy>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CscCfGroupConditionDateRange from 'components/call-forwarding/CscCfGroupConditionDateRange'
|
||||
export default {
|
||||
name: 'CscCfConditionPopupDateRange',
|
||||
components: {
|
||||
CscCfGroupConditionDateRange
|
||||
},
|
||||
props: {
|
||||
mapping: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
destinationSet: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
sourceSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
timeSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
beforeShow () {
|
||||
this.closed = false
|
||||
},
|
||||
closePopup () {
|
||||
this.closed = true
|
||||
this.$refs.popup.hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<q-popup-proxy
|
||||
ref="popup"
|
||||
persistent
|
||||
anchor="bottom middle"
|
||||
self="top middle"
|
||||
@before-show="beforeShow"
|
||||
>
|
||||
<csc-cf-group-condition-office-hours
|
||||
:mapping="mapping"
|
||||
:destination-set="destinationSet"
|
||||
:source-set="sourceSet"
|
||||
:time-set="timeSet"
|
||||
:delete-button="true"
|
||||
@close="closePopup"
|
||||
/>
|
||||
</q-popup-proxy>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CscCfGroupConditionOfficeHours from 'components/call-forwarding/CscCfGroupConditionOfficeHours'
|
||||
export default {
|
||||
name: 'CscCfConditionPopupOfficeHours',
|
||||
components: {
|
||||
CscCfGroupConditionOfficeHours
|
||||
},
|
||||
props: {
|
||||
mapping: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
destinationSet: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
sourceSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
timeSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
beforeShow () {
|
||||
this.closed = false
|
||||
},
|
||||
closePopup () {
|
||||
this.closed = true
|
||||
this.$refs.popup.hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<q-popup-proxy
|
||||
ref="popup"
|
||||
persistent
|
||||
anchor="bottom middle"
|
||||
self="top middle"
|
||||
@before-show="beforeShow"
|
||||
>
|
||||
<csc-cf-group-condition-weekdays
|
||||
:mapping="mapping"
|
||||
:destination-set="destinationSet"
|
||||
:source-set="sourceSet"
|
||||
:time-set="timeSet"
|
||||
:delete-button="true"
|
||||
@close="closePopup"
|
||||
/>
|
||||
</q-popup-proxy>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CscCfGroupConditionWeekdays from 'components/call-forwarding/CscCfGroupConditionWeekdays'
|
||||
export default {
|
||||
name: 'CscCfConditionPopupWeekdays',
|
||||
components: {
|
||||
CscCfGroupConditionWeekdays
|
||||
},
|
||||
props: {
|
||||
mapping: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
destinationSet: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
sourceSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
timeSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
beforeShow () {
|
||||
this.closed = false
|
||||
},
|
||||
closePopup () {
|
||||
this.closed = true
|
||||
this.$refs.popup.hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,91 @@
|
||||
<template>
|
||||
<q-list
|
||||
class="relative-position"
|
||||
dense
|
||||
separator
|
||||
>
|
||||
<csc-cf-group-title
|
||||
ref="cfGroupTitle"
|
||||
:loading="loading"
|
||||
:mapping="mapping"
|
||||
:destination-set="destinationSet"
|
||||
:source-set="sourceSet"
|
||||
:time-set="timeSet"
|
||||
/>
|
||||
<template
|
||||
v-if="destinationSet"
|
||||
>
|
||||
<csc-cf-group-item-primary-number
|
||||
v-if="mapping.type === 'cft'"
|
||||
:loading="loading"
|
||||
:mapping="mapping"
|
||||
:destination-set="destinationSet"
|
||||
:source-set="sourceSet"
|
||||
:time-set="timeSet"
|
||||
/>
|
||||
<csc-cf-group-item
|
||||
v-for="(destination, destinationIndex) in destinationSet.destinations"
|
||||
:key="destinationIndex"
|
||||
:loading="loading"
|
||||
:destination="destination"
|
||||
:destination-previous="(destinationIndex > 0)?destinationSet.destinations[destinationIndex - 1]:null"
|
||||
:destination-index="destinationIndex"
|
||||
:mapping="mapping"
|
||||
:destination-set="destinationSet"
|
||||
:source-set="sourceSet"
|
||||
:time-set="timeSet"
|
||||
@delete-last="$refs.cfGroupTitle.deleteMappingEvent(mapping)"
|
||||
/>
|
||||
</template>
|
||||
<q-inner-loading
|
||||
:showing="$wait.is(waitIdentifier)"
|
||||
color="primary"
|
||||
class="bg-main-menu"
|
||||
>
|
||||
<csc-spinner />
|
||||
</q-inner-loading>
|
||||
</q-list>
|
||||
</template>
|
||||
<script>
|
||||
import CscCfGroupTitle from 'components/call-forwarding/CscCfGroupTitle'
|
||||
import CscCfGroupItem from 'components/call-forwarding/CscCfGroupItem'
|
||||
import CscSpinner from 'components/CscSpinner'
|
||||
import CscCfGroupItemPrimaryNumber from 'components/call-forwarding/CscCfGroupItemPrimaryNumber'
|
||||
|
||||
export default {
|
||||
name: 'CscCfGroup',
|
||||
components: {
|
||||
CscCfGroupItemPrimaryNumber,
|
||||
CscSpinner,
|
||||
CscCfGroupItem,
|
||||
CscCfGroupTitle
|
||||
},
|
||||
props: {
|
||||
mapping: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
destinationSet: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
sourceSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
timeSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
waitIdentifier () {
|
||||
return 'csc-cf-group-' + this.destinationSet.id
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,90 @@
|
||||
<template>
|
||||
<q-card
|
||||
class="bg-dark no-padding no-margin relative-position"
|
||||
>
|
||||
<q-item
|
||||
class="no-margin no-padding"
|
||||
dense
|
||||
>
|
||||
<q-item-section
|
||||
side
|
||||
>
|
||||
<q-btn
|
||||
v-if="backButton"
|
||||
icon="arrow_back"
|
||||
flat
|
||||
dense
|
||||
@click="$emit('back')"
|
||||
/>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label
|
||||
class="text-subtitle1"
|
||||
>
|
||||
<q-icon
|
||||
v-if="icon"
|
||||
:name="icon"
|
||||
/>
|
||||
{{ title }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section
|
||||
side
|
||||
>
|
||||
<q-btn
|
||||
icon="clear"
|
||||
flat
|
||||
dense
|
||||
@click="$emit('close')"
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-card-section
|
||||
class="no-padding no-margin"
|
||||
>
|
||||
<slot
|
||||
name="default"
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-actions
|
||||
align="right"
|
||||
>
|
||||
<slot
|
||||
name="actions"
|
||||
/>
|
||||
</q-card-actions>
|
||||
<q-inner-loading
|
||||
:showing="loading"
|
||||
>
|
||||
<csc-spinner />
|
||||
</q-inner-loading>
|
||||
</q-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CscSpinner from 'components/CscSpinner'
|
||||
export default {
|
||||
name: 'CscCfGroupCondition',
|
||||
components: {
|
||||
CscSpinner
|
||||
},
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
backButton: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,123 @@
|
||||
<template>
|
||||
<csc-cf-group-condition
|
||||
:title="$t('date is ...')"
|
||||
icon="today"
|
||||
:loading="$wait.is('csc-cf-time-set-create')"
|
||||
v-bind="$attrs"
|
||||
v-on="$listeners"
|
||||
>
|
||||
<q-date
|
||||
v-model="selectedDate"
|
||||
class="no-margin no-padding"
|
||||
flat
|
||||
square
|
||||
minimal
|
||||
/>
|
||||
<template
|
||||
v-slot:actions
|
||||
>
|
||||
<q-btn
|
||||
v-if="deleteButton"
|
||||
:label="$t('Delete')"
|
||||
flat
|
||||
color="negative"
|
||||
icon="delete"
|
||||
@click="deleteSourceSetEvent"
|
||||
/>
|
||||
<q-btn
|
||||
:label="$t('Save')"
|
||||
flat
|
||||
color="primary"
|
||||
icon="check"
|
||||
:disable="!selectedDate"
|
||||
@click="createTimeSetEvent"
|
||||
/>
|
||||
</template>
|
||||
</csc-cf-group-condition>
|
||||
</template>
|
||||
<script>
|
||||
import CscCfGroupCondition from 'components/call-forwarding/CscCfGroupCondition'
|
||||
import { mapActions } from 'vuex'
|
||||
import { timeSetDateExact } from 'src/filters/time-set'
|
||||
export default {
|
||||
name: 'CscCfGroupConditionDate',
|
||||
components: {
|
||||
CscCfGroupCondition
|
||||
},
|
||||
props: {
|
||||
mapping: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
destinationSet: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
sourceSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
timeSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
deleteButton: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
selectedDate: this.formattedDate
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
formattedDate () {
|
||||
if (this.timeSet) {
|
||||
return timeSetDateExact(this.timeSet.times)
|
||||
}
|
||||
return null
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.selectedDate = this.formattedDate
|
||||
},
|
||||
methods: {
|
||||
...mapActions('callForwarding', [
|
||||
'createTimeSetDate',
|
||||
'updateTimeSetDate',
|
||||
'deleteTimeSet'
|
||||
]),
|
||||
async createTimeSetEvent () {
|
||||
const dateParts = this.selectedDate.split('/')
|
||||
if (this.timeSet) {
|
||||
await this.updateTimeSetDate({
|
||||
mapping: this.mapping,
|
||||
id: this.timeSet.id,
|
||||
date: {
|
||||
date: dateParts[2],
|
||||
month: dateParts[1],
|
||||
year: dateParts[0]
|
||||
}
|
||||
})
|
||||
} else {
|
||||
await this.createTimeSetDate({
|
||||
mapping: this.mapping,
|
||||
date: {
|
||||
date: dateParts[2],
|
||||
month: dateParts[1],
|
||||
year: dateParts[0]
|
||||
}
|
||||
})
|
||||
}
|
||||
this.$emit('close')
|
||||
},
|
||||
async deleteSourceSetEvent () {
|
||||
await this.deleteTimeSet({
|
||||
mapping: this.mapping,
|
||||
id: this.timeSet.id
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,137 @@
|
||||
<template>
|
||||
<csc-cf-group-condition
|
||||
:title="$t('date range is ...')"
|
||||
icon="book_online"
|
||||
:loading="$wait.is('csc-cf-time-set-create')"
|
||||
v-bind="$attrs"
|
||||
v-on="$listeners"
|
||||
>
|
||||
<q-date
|
||||
v-model="selectedDate"
|
||||
class="no-margin no-padding"
|
||||
flat
|
||||
square
|
||||
minimal
|
||||
range
|
||||
/>
|
||||
<template
|
||||
v-slot:actions
|
||||
>
|
||||
<q-btn
|
||||
v-if="deleteButton"
|
||||
:label="$t('Delete')"
|
||||
flat
|
||||
color="negative"
|
||||
icon="delete"
|
||||
@click="deleteSourceSetEvent"
|
||||
/>
|
||||
<q-btn
|
||||
:label="$t('Save')"
|
||||
flat
|
||||
color="primary"
|
||||
icon="check"
|
||||
:disable="!selectedDate"
|
||||
@click="createTimeSetEvent"
|
||||
/>
|
||||
</template>
|
||||
</csc-cf-group-condition>
|
||||
</template>
|
||||
<script>
|
||||
import CscCfGroupCondition from 'components/call-forwarding/CscCfGroupCondition'
|
||||
import { mapActions } from 'vuex'
|
||||
import { timeSetDateRange } from 'src/filters/time-set'
|
||||
export default {
|
||||
name: 'CscCfGroupConditionDateRange',
|
||||
components: {
|
||||
CscCfGroupCondition
|
||||
},
|
||||
props: {
|
||||
mapping: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
destinationSet: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
sourceSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
timeSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
deleteButton: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
selectedDate: this.transformedDate
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
formattedDate () {
|
||||
if (this.timeSet) {
|
||||
return timeSetDateRange(this.timeSet.times)
|
||||
}
|
||||
return null
|
||||
},
|
||||
transformedDate () {
|
||||
if (this.timeSet) {
|
||||
const dateRangeParts = timeSetDateRange(this.timeSet.times).split('-')
|
||||
return {
|
||||
from: dateRangeParts[0],
|
||||
to: dateRangeParts[1]
|
||||
}
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.selectedDate = this.transformedDate
|
||||
},
|
||||
methods: {
|
||||
...mapActions('callForwarding', [
|
||||
'createTimeSetDateRange',
|
||||
'updateTimeSetDateRange',
|
||||
'deleteTimeSet'
|
||||
]),
|
||||
async createTimeSetEvent () {
|
||||
const datePartsFrom = this.selectedDate.from.split('/')
|
||||
const datePartsTo = this.selectedDate.to.split('/')
|
||||
const payload = {
|
||||
mapping: this.mapping,
|
||||
date: {
|
||||
from: {
|
||||
date: datePartsFrom[2],
|
||||
month: datePartsFrom[1],
|
||||
year: datePartsFrom[0]
|
||||
},
|
||||
to: {
|
||||
date: datePartsTo[2],
|
||||
month: datePartsTo[1],
|
||||
year: datePartsTo[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.timeSet) {
|
||||
payload.id = this.timeSet.id
|
||||
await this.updateTimeSetDateRange(payload)
|
||||
} else {
|
||||
await this.createTimeSetDateRange(payload)
|
||||
}
|
||||
this.$emit('close')
|
||||
},
|
||||
async deleteSourceSetEvent () {
|
||||
await this.deleteTimeSet({
|
||||
mapping: this.mapping,
|
||||
id: this.timeSet.id
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<csc-cf-group-condition
|
||||
:title="$t('')"
|
||||
v-on="$listeners"
|
||||
>
|
||||
<q-list
|
||||
dense
|
||||
>
|
||||
<csc-popup-menu-item
|
||||
icon="person_add"
|
||||
:label="$t('call from ...')"
|
||||
:close-popup="false"
|
||||
:disable="!!sourceSet"
|
||||
@click="$emit('step', 'call-from')"
|
||||
/>
|
||||
<csc-popup-menu-item
|
||||
icon="person_add_disabled"
|
||||
:label="$t('call not from ...')"
|
||||
:close-popup="false"
|
||||
:disable="!!sourceSet"
|
||||
@click="$emit('step', 'call-not-from')"
|
||||
/>
|
||||
<csc-popup-menu-item
|
||||
icon="today"
|
||||
:label="$t('date is ...')"
|
||||
:close-popup="false"
|
||||
:disable="!!timeSet"
|
||||
@click="$emit('step', 'date-is')"
|
||||
/>
|
||||
<csc-popup-menu-item
|
||||
icon="book_online"
|
||||
:label="$t('date range is ...')"
|
||||
:close-popup="false"
|
||||
:disable="!!timeSet"
|
||||
@click="$emit('step', 'date-range-is')"
|
||||
/>
|
||||
<csc-popup-menu-item
|
||||
icon="calendar_today"
|
||||
:label="$t('weekdays are ...')"
|
||||
:close-popup="false"
|
||||
:disable="!!timeSet"
|
||||
@click="$emit('step', 'date-weekdays')"
|
||||
/>
|
||||
<csc-popup-menu-item
|
||||
icon="access_time"
|
||||
:label="$t('office hours are ...')"
|
||||
:close-popup="false"
|
||||
:disable="!!timeSet"
|
||||
@click="$emit('step', 'office-hours-times')"
|
||||
/>
|
||||
</q-list>
|
||||
</csc-cf-group-condition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CscPopupMenuItem from 'components/CscPopupMenuItem'
|
||||
import CscCfGroupCondition from 'components/call-forwarding/CscCfGroupCondition'
|
||||
export default {
|
||||
name: 'CscCfGroupConditionMenu',
|
||||
components: { CscCfGroupCondition, CscPopupMenuItem },
|
||||
props: {
|
||||
mapping: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
destinationSet: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
sourceSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
timeSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,388 @@
|
||||
<template>
|
||||
<csc-cf-group-condition
|
||||
:title="$t('office hours are ...')"
|
||||
icon="access_time"
|
||||
:loading="$wait.is('csc-cf-time-set-create')"
|
||||
v-bind="$attrs"
|
||||
@back="back"
|
||||
@close="$emit('close')"
|
||||
>
|
||||
<div
|
||||
class="row justify-center q-pt-md"
|
||||
>
|
||||
<q-checkbox
|
||||
v-model="sameTimes"
|
||||
:label="$t('Same time for selected days')"
|
||||
/>
|
||||
</div>
|
||||
<q-list
|
||||
dense
|
||||
>
|
||||
<q-item
|
||||
class="q-mb-md q-mt-md"
|
||||
>
|
||||
<q-item-section>
|
||||
<csc-cf-selection-weekdays
|
||||
v-model="weekdays"
|
||||
:tabs="!sameTimes"
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item
|
||||
v-for="(time, index) in times"
|
||||
:key="index"
|
||||
>
|
||||
<q-item-section>
|
||||
<csc-input
|
||||
v-model="times[index].from"
|
||||
dense
|
||||
:label="$t('Start time')"
|
||||
mask="##:##"
|
||||
fill-mask
|
||||
:disable="disabled"
|
||||
>
|
||||
<template
|
||||
v-slot:append
|
||||
>
|
||||
<q-btn
|
||||
icon="access_time"
|
||||
dense
|
||||
flat
|
||||
color="primary"
|
||||
>
|
||||
<q-popup-proxy
|
||||
ref="startTimePopup"
|
||||
>
|
||||
<q-time
|
||||
v-model="times[index].from"
|
||||
flat
|
||||
now-btn
|
||||
square
|
||||
format24h
|
||||
text-color="dark"
|
||||
color="primary"
|
||||
@input="$refs.startTimePopup[index].hide()"
|
||||
/>
|
||||
</q-popup-proxy>
|
||||
</q-btn>
|
||||
</template>
|
||||
</csc-input>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<csc-input
|
||||
v-model="times[index].to"
|
||||
dense
|
||||
:label="$t('End time')"
|
||||
mask="##:##"
|
||||
fill-mask
|
||||
:disable="disabled"
|
||||
>
|
||||
<template
|
||||
v-slot:append
|
||||
>
|
||||
<q-btn
|
||||
icon="access_time"
|
||||
dense
|
||||
flat
|
||||
color="primary"
|
||||
>
|
||||
<q-popup-proxy
|
||||
ref="endTimePopup"
|
||||
>
|
||||
<q-time
|
||||
v-model="times[index].to"
|
||||
flat
|
||||
now-btn
|
||||
square
|
||||
format24h
|
||||
text-color="dark"
|
||||
color="primary"
|
||||
@input="$refs.endTimePopup[index].hide()"
|
||||
/>
|
||||
</q-popup-proxy>
|
||||
</q-btn>
|
||||
</template>
|
||||
</csc-input>
|
||||
</q-item-section>
|
||||
<q-item-section
|
||||
side
|
||||
>
|
||||
<q-btn
|
||||
flat
|
||||
dense
|
||||
color="negative"
|
||||
icon="delete"
|
||||
:disable="index === 0 || disabled"
|
||||
@click="removeTime(index)"
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item>
|
||||
<q-item-section>
|
||||
<q-btn
|
||||
color="primary"
|
||||
icon="add"
|
||||
flat
|
||||
:label="$t('Add time')"
|
||||
:disable="disabled"
|
||||
@click="addTime"
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
<template
|
||||
v-slot:actions
|
||||
>
|
||||
<q-btn
|
||||
v-if="deleteButton"
|
||||
:label="$t('Delete')"
|
||||
flat
|
||||
color="negative"
|
||||
icon="delete"
|
||||
:disable="disabled"
|
||||
@click="deleteTimeSetEvent"
|
||||
/>
|
||||
<q-btn
|
||||
:label="$t('Save')"
|
||||
flat
|
||||
color="primary"
|
||||
icon="check"
|
||||
:disable="disabled"
|
||||
@click="createTimeSetOfficeHoursEvent"
|
||||
/>
|
||||
</template>
|
||||
</csc-cf-group-condition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CscCfGroupCondition from 'components/call-forwarding/CscCfGroupCondition'
|
||||
import CscInput from 'components/form/CscInput'
|
||||
import CscCfSelectionWeekdays from 'components/call-forwarding/CscCfSelectionWeekdays'
|
||||
import { DAY_MAP, DEFAULT_WEEKDAYS } from 'src/filters/time-set'
|
||||
import { mapActions } from 'vuex'
|
||||
export default {
|
||||
name: 'CscCfGroupConditionOfficeHours',
|
||||
components: {
|
||||
CscCfSelectionWeekdays,
|
||||
CscInput,
|
||||
CscCfGroupCondition
|
||||
},
|
||||
props: {
|
||||
mapping: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
destinationSet: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
sourceSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
timeSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
deleteButton: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
sameTimes: this.isSameTimes(),
|
||||
weekdays: DEFAULT_WEEKDAYS,
|
||||
timesAll: [{
|
||||
from: '',
|
||||
to: ''
|
||||
}],
|
||||
timesDay1: [{
|
||||
from: '',
|
||||
to: ''
|
||||
}],
|
||||
timesDay2: [{
|
||||
from: '',
|
||||
to: ''
|
||||
}],
|
||||
timesDay3: [{
|
||||
from: '',
|
||||
to: ''
|
||||
}],
|
||||
timesDay4: [{
|
||||
from: '',
|
||||
to: ''
|
||||
}],
|
||||
timesDay5: [{
|
||||
from: '',
|
||||
to: ''
|
||||
}],
|
||||
timesDay6: [{
|
||||
from: '',
|
||||
to: ''
|
||||
}],
|
||||
timesDay7: [{
|
||||
from: '',
|
||||
to: ''
|
||||
}]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
disabled () {
|
||||
return this.sameTimes && this.weekdays.length === 0
|
||||
},
|
||||
times () {
|
||||
if (this.sameTimes) {
|
||||
return this.timesAll
|
||||
} else {
|
||||
return this['timesDay' + this.weekdays[0]]
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
timeSet () {
|
||||
this.transformTimeSet()
|
||||
},
|
||||
sameTimes (sameTimes) {
|
||||
this.transformTimeSet()
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.transformTimeSet()
|
||||
},
|
||||
methods: {
|
||||
...mapActions('callForwarding', [
|
||||
'createOfficeHoursSameTimes',
|
||||
'updateOfficeHoursSameTimes',
|
||||
'createOfficeHours',
|
||||
'updateOfficeHours',
|
||||
'deleteTimeSet'
|
||||
]),
|
||||
back () {
|
||||
this.$emit('back')
|
||||
},
|
||||
isSameTimes () {
|
||||
if (this.timeSet) {
|
||||
return this.timeSet.name.startsWith('csc-office-hours-same-times')
|
||||
}
|
||||
return true
|
||||
},
|
||||
transformTimeSet () {
|
||||
if (this.timeSet && this.timeSet.name.startsWith('csc-office-hours-same-times')) {
|
||||
const weekdays = new Set()
|
||||
const times = new Set()
|
||||
this.timeSet.times.forEach((time) => {
|
||||
if (time.wday !== null && time.hour !== null && time.minute !== null) {
|
||||
weekdays.add(parseInt(time.wday))
|
||||
times.add(time.hour + ':' + time.minute)
|
||||
}
|
||||
})
|
||||
this.weekdays = Array.from(weekdays)
|
||||
const timesAll = []
|
||||
Array.from(times).forEach((time) => {
|
||||
const timeParts = time.split(':')
|
||||
const hourParts = timeParts[0].split('-')
|
||||
const minuteParts = timeParts[1].split('-')
|
||||
timesAll.push({
|
||||
from: hourParts[0] + ':' + minuteParts[0],
|
||||
to: hourParts[1] + ':' + minuteParts[1]
|
||||
})
|
||||
})
|
||||
this.timesAll = timesAll
|
||||
} else if (this.timeSet && this.timeSet.name.startsWith('csc-office-hours')) {
|
||||
DAY_MAP.forEach((day) => {
|
||||
this['timesDay' + day] = []
|
||||
})
|
||||
this.timeSet.times.forEach((time) => {
|
||||
if (time.wday !== null && time.hour !== null && time.minute !== null) {
|
||||
const hourParts = time.hour.split('-')
|
||||
const minuteParts = time.minute.split('-')
|
||||
this['timesDay' + time.wday].push({
|
||||
from: hourParts[0] + ':' + minuteParts[0],
|
||||
to: hourParts[1] + ':' + minuteParts[1]
|
||||
})
|
||||
}
|
||||
})
|
||||
DAY_MAP.forEach((day) => {
|
||||
if (this['timesDay' + day].length === 0) {
|
||||
this['timesDay' + day] = [{
|
||||
from: '',
|
||||
to: ''
|
||||
}]
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
addTime () {
|
||||
if (!this.sameTimes) {
|
||||
this['timesDay' + this.weekdays[0]].push({
|
||||
from: '',
|
||||
to: ''
|
||||
})
|
||||
} else {
|
||||
this.timesAll.push({
|
||||
from: '',
|
||||
to: ''
|
||||
})
|
||||
}
|
||||
},
|
||||
removeTime (index) {
|
||||
if (!this.sameTimes) {
|
||||
this['timesDay' + this.weekdays[0]] = this['timesDay' + this.weekdays[0]].filter((time, timeIndex) => timeIndex !== index)
|
||||
} else {
|
||||
this.timesAll = this.timesAll.filter((time, timeIndex) => timeIndex !== index)
|
||||
}
|
||||
},
|
||||
resetTimesPerDay () {
|
||||
DAY_MAP.forEach((day) => {
|
||||
this['timesDay' + day] = [{
|
||||
from: '',
|
||||
to: ''
|
||||
}]
|
||||
})
|
||||
},
|
||||
async createTimeSetOfficeHoursEvent () {
|
||||
const payload = {
|
||||
mapping: this.mapping
|
||||
}
|
||||
if (this.timeSet) {
|
||||
payload.id = this.timeSet.id
|
||||
}
|
||||
if (!this.sameTimes) {
|
||||
payload.times = [
|
||||
this.timesDay1,
|
||||
this.timesDay2,
|
||||
this.timesDay3,
|
||||
this.timesDay4,
|
||||
this.timesDay5,
|
||||
this.timesDay6,
|
||||
this.timesDay7
|
||||
]
|
||||
} else {
|
||||
payload.times = this.timesAll
|
||||
payload.weekdays = this.weekdays
|
||||
}
|
||||
if (this.timeSet && this.timeSet.name.startsWith('csc-office-hours-same-times') && this.sameTimes) {
|
||||
await this.updateOfficeHoursSameTimes(payload)
|
||||
} else if (this.timeSet && this.timeSet.name.startsWith('csc-office-hours-same-times') && !this.sameTimes) {
|
||||
await this.createOfficeHours(payload)
|
||||
} else if (this.timeSet && this.timeSet.name.startsWith('csc-office-hours') && this.sameTimes) {
|
||||
await this.createOfficeHoursSameTimes(payload)
|
||||
} else if (this.timeSet && this.timeSet.name.startsWith('csc-office-hours') && !this.sameTimes) {
|
||||
await this.updateOfficeHours(payload)
|
||||
} else if (!this.timeSet && this.sameTimes) {
|
||||
await this.createOfficeHoursSameTimes(payload)
|
||||
} else {
|
||||
await this.createOfficeHours(payload)
|
||||
}
|
||||
this.$emit('close')
|
||||
},
|
||||
async deleteTimeSetEvent () {
|
||||
await this.deleteTimeSet({
|
||||
mapping: this.mapping,
|
||||
id: this.timeSet.id
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,229 @@
|
||||
<template>
|
||||
<csc-cf-group-condition
|
||||
:title="$t(title)"
|
||||
:loading="$wait.is('csc-cf-source-set-create')"
|
||||
v-bind="$attrs"
|
||||
v-on="$listeners"
|
||||
>
|
||||
<q-list
|
||||
class="no-margin q-pa-md"
|
||||
dense
|
||||
>
|
||||
<q-item
|
||||
class="no-margin no-padding"
|
||||
>
|
||||
<q-item-section>
|
||||
<csc-input
|
||||
v-model="sourceSetNameInternal"
|
||||
dense
|
||||
clearable
|
||||
:label="$t('Number list name')"
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item
|
||||
v-for="(number, index) in sourceSetNumbersInternal"
|
||||
:key="index"
|
||||
class="no-margin no-padding"
|
||||
>
|
||||
<q-item-section>
|
||||
<csc-input
|
||||
v-model="sourceSetNumbersInternal[index]"
|
||||
dense
|
||||
clearable
|
||||
:label="$t('Number')"
|
||||
>
|
||||
<template
|
||||
v-if="index > 0"
|
||||
>
|
||||
<q-btn
|
||||
flat
|
||||
dense
|
||||
color="negative"
|
||||
icon="delete"
|
||||
@click="deleteNumber(index)"
|
||||
/>
|
||||
</template>
|
||||
</csc-input>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item
|
||||
class="no-margin no-padding"
|
||||
>
|
||||
<q-item-section>
|
||||
<q-btn
|
||||
:label="$t('Add number')"
|
||||
flat
|
||||
color="primary"
|
||||
icon="add"
|
||||
@click="sourceSetNumbersInternal.push('')"
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
<template
|
||||
v-slot:actions
|
||||
>
|
||||
<q-btn
|
||||
v-if="deleteButton"
|
||||
:label="$t('Delete')"
|
||||
flat
|
||||
color="negative"
|
||||
icon="delete"
|
||||
@click="deleteSourceSetEvent"
|
||||
/>
|
||||
<q-btn
|
||||
v-if="unassignButton"
|
||||
:label="$t('Unassign')"
|
||||
flat
|
||||
color="primary"
|
||||
icon="undo"
|
||||
@click="unassignSourceSetEvent"
|
||||
/>
|
||||
<q-btn
|
||||
:label="$t('Select')"
|
||||
flat
|
||||
color="primary"
|
||||
icon="source"
|
||||
@click="$emit('select')"
|
||||
/>
|
||||
<q-btn
|
||||
:label="$t('Save')"
|
||||
flat
|
||||
color="primary"
|
||||
icon="check"
|
||||
@click="createSourceSetEvent"
|
||||
/>
|
||||
</template>
|
||||
</csc-cf-group-condition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CscInput from 'components/form/CscInput'
|
||||
import {
|
||||
mapActions
|
||||
} from 'vuex'
|
||||
import CscCfGroupCondition from 'components/call-forwarding/CscCfGroupCondition'
|
||||
export default {
|
||||
name: 'CscCfGroupConditionSourceSetCreate',
|
||||
components: {
|
||||
CscCfGroupCondition,
|
||||
CscInput
|
||||
},
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
required: true,
|
||||
validator (value) {
|
||||
return ['whitelist', 'blacklist'].includes(value.toLowerCase())
|
||||
}
|
||||
},
|
||||
mapping: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
destinationSet: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
sourceSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
timeSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
deleteButton: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
unassignButton: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
sourceSetNameInternal: this.sourceSetName,
|
||||
sourceSetNumbersInternal: this.sourceSetNumbers
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
sourceSetNumbers () {
|
||||
const numbers = []
|
||||
if (this.sourceSet && this.sourceSet.sources) {
|
||||
this.sourceSet.sources.forEach((source) => {
|
||||
numbers.push(source.source)
|
||||
})
|
||||
} else {
|
||||
numbers.push('')
|
||||
}
|
||||
return numbers
|
||||
},
|
||||
sourceSetName () {
|
||||
let name = this.$t('MyNumberList')
|
||||
if (this.sourceSet) {
|
||||
name = this.sourceSet.name
|
||||
}
|
||||
return name
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.sourceSetNameInternal = this.sourceSetName
|
||||
this.sourceSetNumbersInternal = this.sourceSetNumbers
|
||||
},
|
||||
methods: {
|
||||
...mapActions('callForwarding', [
|
||||
'createSourceSet',
|
||||
'updateSourceSet',
|
||||
'deleteSourceSet',
|
||||
'unassignSourceSet'
|
||||
]),
|
||||
deleteNumber (index) {
|
||||
this.sourceSetNumbersInternal = this.sourceSetNumbersInternal.filter((number, numberIndex) => {
|
||||
return numberIndex !== index
|
||||
})
|
||||
},
|
||||
async createSourceSetEvent () {
|
||||
if (this.sourceSet) {
|
||||
await this.updateSourceSet({
|
||||
mapping: this.mapping,
|
||||
id: this.sourceSet.id,
|
||||
name: this.sourceSetNameInternal,
|
||||
numbers: this.sourceSetNumbersInternal,
|
||||
mode: this.mode
|
||||
})
|
||||
} else {
|
||||
await this.createSourceSet({
|
||||
mapping: this.mapping,
|
||||
name: this.sourceSetNameInternal,
|
||||
numbers: this.sourceSetNumbersInternal,
|
||||
mode: this.mode
|
||||
})
|
||||
}
|
||||
this.$emit('close')
|
||||
},
|
||||
async deleteSourceSetEvent () {
|
||||
if (this.sourceSet) {
|
||||
await this.deleteSourceSet({
|
||||
mapping: this.mapping,
|
||||
id: this.sourceSet.id
|
||||
})
|
||||
}
|
||||
},
|
||||
async unassignSourceSetEvent () {
|
||||
if (this.sourceSet) {
|
||||
await this.unassignSourceSet({
|
||||
mapping: this.mapping,
|
||||
id: this.sourceSet.id
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,103 @@
|
||||
<template>
|
||||
<csc-cf-group-condition
|
||||
:title="$t(title)"
|
||||
:loading="$wait.is('csc-cf-source-set-create')"
|
||||
v-bind="$attrs"
|
||||
v-on="$listeners"
|
||||
>
|
||||
<div
|
||||
class="no-margin q-pa-md"
|
||||
>
|
||||
<csc-cf-source-set-selection
|
||||
v-model="selectedSourceSet"
|
||||
:mode="mode"
|
||||
dense
|
||||
:label="$t('Number list')"
|
||||
/>
|
||||
</div>
|
||||
<template
|
||||
v-slot:actions
|
||||
>
|
||||
<q-btn
|
||||
:label="createLabel"
|
||||
flat
|
||||
color="primary"
|
||||
icon="source"
|
||||
@click="$emit('create')"
|
||||
/>
|
||||
<q-btn
|
||||
:label="$t('Save')"
|
||||
flat
|
||||
color="primary"
|
||||
icon="check"
|
||||
:disable="!selectedSourceSet"
|
||||
@click="selectSourceSetEvent"
|
||||
/>
|
||||
</template>
|
||||
</csc-cf-group-condition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapActions
|
||||
} from 'vuex'
|
||||
import CscCfGroupCondition from 'components/call-forwarding/CscCfGroupCondition'
|
||||
import CscCfSourceSetSelection from 'components/call-forwarding/CscCfSourceSetSelection'
|
||||
export default {
|
||||
name: 'CscCfGroupConditionSourceSetSelect',
|
||||
components: {
|
||||
CscCfSourceSetSelection,
|
||||
CscCfGroupCondition
|
||||
},
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
required: true,
|
||||
validator (value) {
|
||||
return ['whitelist', 'blacklist'].includes(value.toLowerCase())
|
||||
}
|
||||
},
|
||||
mapping: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
destinationSet: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
sourceSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
timeSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
createLabel: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
selectedSourceSet: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions('callForwarding', [
|
||||
'assignSourceSet'
|
||||
]),
|
||||
async selectSourceSetEvent () {
|
||||
await this.assignSourceSet({
|
||||
mapping: this.mapping,
|
||||
id: this.selectedSourceSet
|
||||
})
|
||||
this.$emit('close')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,113 @@
|
||||
<template>
|
||||
<csc-cf-group-condition
|
||||
:title="$t('weekdays are ...')"
|
||||
icon="calendar_today"
|
||||
:loading="$wait.is('csc-cf-time-set-create')"
|
||||
v-bind="$attrs"
|
||||
v-on="$listeners"
|
||||
>
|
||||
<csc-cf-selection-weekdays
|
||||
v-model="selectedWeekdays"
|
||||
class="q-pl-md q-pr-md q-pt-sm q-pb-sm"
|
||||
/>
|
||||
<template
|
||||
v-slot:actions
|
||||
>
|
||||
<q-btn
|
||||
v-if="deleteButton"
|
||||
:label="$t('Delete')"
|
||||
flat
|
||||
color="negative"
|
||||
icon="delete"
|
||||
@click="deleteTimeSetEvent"
|
||||
/>
|
||||
<q-btn
|
||||
:label="$t('Save')"
|
||||
flat
|
||||
color="primary"
|
||||
icon="check"
|
||||
:disable="selectedWeekdays && selectedWeekdays.length === 0"
|
||||
@click="createTimeSetEvent"
|
||||
/>
|
||||
</template>
|
||||
</csc-cf-group-condition>
|
||||
</template>
|
||||
<script>
|
||||
import CscCfGroupCondition from 'components/call-forwarding/CscCfGroupCondition'
|
||||
import { mapActions } from 'vuex'
|
||||
import CscCfSelectionWeekdays from 'components/call-forwarding/CscCfSelectionWeekdays'
|
||||
export default {
|
||||
name: 'CscCfGroupConditionWeekdays',
|
||||
components: {
|
||||
CscCfSelectionWeekdays,
|
||||
CscCfGroupCondition
|
||||
},
|
||||
props: {
|
||||
mapping: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
destinationSet: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
sourceSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
timeSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
deleteButton: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
selectedWeekdays: this.weekdays
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
weekdays () {
|
||||
const weekdays = []
|
||||
if (this.timeSet) {
|
||||
this.timeSet.times.forEach((weekday) => {
|
||||
weekdays.push(parseInt(weekday.wday))
|
||||
})
|
||||
}
|
||||
return weekdays
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.selectedWeekdays = this.weekdays
|
||||
},
|
||||
methods: {
|
||||
...mapActions('callForwarding', [
|
||||
'createTimeSetWeekdays',
|
||||
'updateTimeSetWeekdays',
|
||||
'deleteTimeSet'
|
||||
]),
|
||||
async createTimeSetEvent () {
|
||||
const payload = {
|
||||
mapping: this.mapping,
|
||||
weekdays: this.selectedWeekdays
|
||||
}
|
||||
if (this.timeSet) {
|
||||
payload.id = this.timeSet.id
|
||||
await this.updateTimeSetWeekdays(payload)
|
||||
} else {
|
||||
await this.createTimeSetWeekdays(payload)
|
||||
}
|
||||
this.$emit('close')
|
||||
},
|
||||
async deleteTimeSetEvent () {
|
||||
await this.deleteTimeSet({
|
||||
mapping: this.mapping,
|
||||
id: this.timeSet.id
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,307 @@
|
||||
<template>
|
||||
<q-item
|
||||
:disable="loading || !mapping.enabled"
|
||||
>
|
||||
<q-item-section
|
||||
side
|
||||
>
|
||||
<q-icon
|
||||
name="subdirectory_arrow_right"
|
||||
/>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label>
|
||||
<template
|
||||
v-if="destinationIndex === 0 && mapping.type !== 'cft'"
|
||||
>
|
||||
{{ $t('Forwarded to') }}
|
||||
</template>
|
||||
<template
|
||||
v-else-if="destinationIndex === 0 && mapping.type === 'cft'"
|
||||
>
|
||||
{{ $t('After') }}
|
||||
<span
|
||||
class="q-pl-xs q-pr-xs text-primary text-weight-bold cursor-pointer"
|
||||
style="white-space: nowrap"
|
||||
>
|
||||
<q-icon
|
||||
name="access_time"
|
||||
/>
|
||||
{{ ringTimeout }}
|
||||
{{ $t('seconds') }}
|
||||
<q-popup-edit
|
||||
v-model="changedDestinationTimeout"
|
||||
buttons
|
||||
@save="updateRingTimeoutEvent()"
|
||||
>
|
||||
<csc-input
|
||||
v-model="changedDestinationTimeout"
|
||||
type="number"
|
||||
dense
|
||||
>
|
||||
<template
|
||||
v-slot:prepend
|
||||
>
|
||||
<q-icon
|
||||
name="access_time"
|
||||
/>
|
||||
</template>
|
||||
</csc-input>
|
||||
</q-popup-edit>
|
||||
</span>
|
||||
{{ $t('forwarded to') }}
|
||||
</template>
|
||||
<template
|
||||
v-else
|
||||
>
|
||||
{{ $t('After') }}
|
||||
<span
|
||||
class="q-pl-xs q-pr-xs text-primary text-weight-bold cursor-pointer"
|
||||
style="white-space: nowrap"
|
||||
>
|
||||
<q-icon
|
||||
name="access_time"
|
||||
/>
|
||||
{{ destinationPrevious.timeout }}
|
||||
{{ $t('seconds') }}
|
||||
<q-popup-edit
|
||||
v-model="changedDestinationTimeout"
|
||||
buttons
|
||||
@save="updateDestinationTimeoutEvent({
|
||||
destinationTimeout: changedDestinationTimeout,
|
||||
destinationIndex: destinationIndex - 1,
|
||||
destinationSetId: destinationSet.id
|
||||
})"
|
||||
>
|
||||
<csc-input
|
||||
v-model="changedDestinationTimeout"
|
||||
type="number"
|
||||
dense
|
||||
>
|
||||
<template
|
||||
v-slot:prepend
|
||||
>
|
||||
<q-icon
|
||||
name="access_time"
|
||||
/>
|
||||
</template>
|
||||
</csc-input>
|
||||
</q-popup-edit>
|
||||
</span>
|
||||
{{ $t('forwarded to') }}
|
||||
</template>
|
||||
<span
|
||||
v-if="destination.destination.endsWith('voicebox.local')"
|
||||
class="q-pl-xs text-weight-bold"
|
||||
style="white-space: nowrap"
|
||||
>
|
||||
<q-icon
|
||||
name="voicemail"
|
||||
/>
|
||||
{{ $t('Voicebox') }}
|
||||
</span>
|
||||
<span
|
||||
v-else-if="destination.destination.endsWith('fax2mail.local')"
|
||||
class="q-pl-xs text-weight-bold"
|
||||
style="white-space: nowrap"
|
||||
>
|
||||
<q-icon
|
||||
name="email"
|
||||
/>
|
||||
{{ $t('Fax2Mail') }}
|
||||
</span>
|
||||
<span
|
||||
v-else-if="destination.destination.endsWith('managersecretary.local')"
|
||||
class="q-pl-xs text-weight-bold"
|
||||
style="white-space: nowrap"
|
||||
>
|
||||
<q-icon
|
||||
name="phone_forwarded"
|
||||
/>
|
||||
{{ $t('ManagerSecretary') }}
|
||||
</span>
|
||||
<span
|
||||
v-else-if="destination.destination.endsWith('conference.local')"
|
||||
class="q-pl-xs text-weight-bold"
|
||||
style="white-space: nowrap"
|
||||
>
|
||||
<q-icon
|
||||
name="groups"
|
||||
/>
|
||||
{{ $t('Conference') }}
|
||||
</span>
|
||||
<span
|
||||
v-else-if="destination.destination.endsWith('app.local')"
|
||||
class="q-pl-xs text-weight-bold"
|
||||
style="white-space: nowrap"
|
||||
>
|
||||
<q-icon
|
||||
name="app"
|
||||
/>
|
||||
{{ $t('Application') }}
|
||||
</span>
|
||||
<span
|
||||
v-else
|
||||
class="q-pl-xs text-primary text-weight-bold cursor-pointer"
|
||||
style="white-space: nowrap"
|
||||
>
|
||||
<q-icon
|
||||
name="phone_forwarded"
|
||||
/>
|
||||
{{ destination.simple_destination }}
|
||||
<q-popup-edit
|
||||
v-model="changedDestination"
|
||||
buttons
|
||||
@save="updateDestinationEvent({
|
||||
destination: changedDestination,
|
||||
destinationIndex: destinationIndex,
|
||||
destinationSetId: destinationSet.id
|
||||
})"
|
||||
>
|
||||
<csc-input
|
||||
v-model="changedDestination"
|
||||
dense
|
||||
>
|
||||
<template
|
||||
v-slot:prepend
|
||||
>
|
||||
<q-icon
|
||||
name="phone_forwarded"
|
||||
/>
|
||||
</template>
|
||||
</csc-input>
|
||||
</q-popup-edit>
|
||||
</span>
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section
|
||||
side
|
||||
>
|
||||
<csc-more-menu>
|
||||
<csc-popup-menu-item-delete
|
||||
@click="removeDestinationEvent({
|
||||
destinationIndex: destinationIndex,
|
||||
destinationSetId: destinationSet.id
|
||||
})"
|
||||
/>
|
||||
</csc-more-menu>
|
||||
</q-item-section>
|
||||
<q-inner-loading
|
||||
:showing="$wait.is(waitIdentifier)"
|
||||
color="primary"
|
||||
class="bg-main-menu"
|
||||
>
|
||||
<csc-spinner />
|
||||
</q-inner-loading>
|
||||
</q-item>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapActions,
|
||||
mapGetters
|
||||
} from 'vuex'
|
||||
import CscMoreMenu from 'components/CscMoreMenu'
|
||||
import CscPopupMenuItemDelete from 'components/CscPopupMenuItemDelete'
|
||||
import CscInput from 'components/form/CscInput'
|
||||
import CscSpinner from 'components/CscSpinner'
|
||||
export default {
|
||||
name: 'CscCfGroupItem',
|
||||
components: { CscSpinner, CscInput, CscPopupMenuItemDelete, CscMoreMenu },
|
||||
props: {
|
||||
mapping: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
destination: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
destinationPrevious: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
destinationIndex: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
destinationSet: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
sourceSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
timeSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
changedDestination: this.destination.simple_destination,
|
||||
changedDestinationTimeout: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('callForwarding', [
|
||||
'ringTimeout'
|
||||
]),
|
||||
waitIdentifier () {
|
||||
return 'csc-cf-group-item-' + this.destinationSet.id + '-' + this.destinationIndex
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
if (this.mapping.type === 'cft' && this.destinationIndex === 0) {
|
||||
this.changedDestinationTimeout = this.ringTimeout
|
||||
} else if (this.destinationPrevious) {
|
||||
this.changedDestinationTimeout = this.destinationPrevious.timeout
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions('callForwarding', [
|
||||
'updateDestination',
|
||||
'removeDestination',
|
||||
'updateDestinationTimeout',
|
||||
'updateRingTimeout'
|
||||
]),
|
||||
async updateDestinationEvent (payload) {
|
||||
this.$wait.start(this.waitIdentifier)
|
||||
await this.updateDestination(payload)
|
||||
this.$wait.end(this.waitIdentifier)
|
||||
},
|
||||
async removeDestinationEvent (payload) {
|
||||
this.$q.dialog({
|
||||
title: this.$t('Delete destination'),
|
||||
message: 'You are about to delete this destination',
|
||||
color: 'negative',
|
||||
cancel: true,
|
||||
persistent: true
|
||||
}).onOk(async data => {
|
||||
this.$wait.start(this.waitIdentifier)
|
||||
if (this.destinationSet.destinations.length > 1) {
|
||||
await this.removeDestination(payload)
|
||||
} else {
|
||||
this.$emit('delete-last', payload)
|
||||
}
|
||||
this.$wait.end(this.waitIdentifier)
|
||||
})
|
||||
},
|
||||
async updateDestinationTimeoutEvent (payload) {
|
||||
this.$wait.start(this.waitIdentifier)
|
||||
await this.updateDestinationTimeout(payload)
|
||||
this.$wait.end(this.waitIdentifier)
|
||||
},
|
||||
async updateRingTimeoutEvent () {
|
||||
this.$wait.start('csc-cf-mappings-full')
|
||||
await this.updateRingTimeout(this.changedDestinationTimeout)
|
||||
this.$wait.end('csc-cf-mappings-full')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,78 @@
|
||||
<template>
|
||||
<q-item
|
||||
:disable="loading || (mapping && !mapping.enabled)"
|
||||
>
|
||||
<q-item-section
|
||||
side
|
||||
>
|
||||
<q-icon
|
||||
name="subdirectory_arrow_right"
|
||||
/>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label>
|
||||
{{ $t('Ring at') }}
|
||||
<span
|
||||
class="q-pl-sm text-weight-bold"
|
||||
>
|
||||
<q-icon
|
||||
name="ring_volume"
|
||||
/>
|
||||
{{ primaryNumber | number }}
|
||||
</span>
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
<q-inner-loading
|
||||
:showing="$wait.is(waitIdentifier)"
|
||||
color="primary"
|
||||
class="bg-main-menu"
|
||||
>
|
||||
<csc-spinner />
|
||||
</q-inner-loading>
|
||||
</q-item>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapGetters
|
||||
} from 'vuex'
|
||||
import CscSpinner from 'components/CscSpinner'
|
||||
export default {
|
||||
name: 'CscCfGroupItemPrimaryNumber',
|
||||
components: { CscSpinner },
|
||||
props: {
|
||||
mapping: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
destinationSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
sourceSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
timeSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('user', [
|
||||
'primaryNumber'
|
||||
]),
|
||||
waitIdentifier () {
|
||||
return 'csc'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,366 @@
|
||||
<template>
|
||||
<q-item
|
||||
:disable="loading || $wait.is(waitIdentifier)"
|
||||
>
|
||||
<q-item-section
|
||||
class="text-left"
|
||||
>
|
||||
<q-item-label
|
||||
class="text-weight-bold"
|
||||
>
|
||||
<span
|
||||
v-if="mapping.type === 'cfu' || mapping.type === 'cft'"
|
||||
>
|
||||
{{ $t('If available') }}
|
||||
</span>
|
||||
<template
|
||||
v-else-if="mapping.type === 'cfna'"
|
||||
>
|
||||
{{ $t('If not available') }}
|
||||
</template>
|
||||
<template
|
||||
v-else-if="mapping.type === 'cfb'"
|
||||
>
|
||||
{{ $t('If busy') }}
|
||||
</template>
|
||||
<template
|
||||
v-if="sourceSet"
|
||||
>
|
||||
<template
|
||||
v-if="sourceSet.mode === 'whitelist'"
|
||||
>
|
||||
{{ $t('and call from') }}
|
||||
</template>
|
||||
<template
|
||||
v-else
|
||||
>
|
||||
{{ $t('and call not from') }}
|
||||
</template>
|
||||
<span
|
||||
:class="clickableClasses"
|
||||
style="white-space: nowrap"
|
||||
>
|
||||
<q-icon
|
||||
v-if="sourceSet.mode === 'whitelist'"
|
||||
name="person_add"
|
||||
/>
|
||||
<q-icon
|
||||
v-else
|
||||
name="person_add_disabled"
|
||||
/>
|
||||
{{ sourceSet.name }}
|
||||
<csc-cf-condition-popup-call-from
|
||||
v-if="sourceSet.mode === 'whitelist'"
|
||||
:mapping="mapping"
|
||||
:destination-set="destinationSet"
|
||||
:source-set="sourceSet"
|
||||
:time-set="timeSet"
|
||||
/>
|
||||
<csc-cf-condition-popup-call-not-from
|
||||
v-else
|
||||
:mapping="mapping"
|
||||
:destination-set="destinationSet"
|
||||
:source-set="sourceSet"
|
||||
:time-set="timeSet"
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
<template
|
||||
v-if="timeSet"
|
||||
>
|
||||
{{ $t('and') }}
|
||||
<template
|
||||
v-if="timeSet.name.startsWith('csc-date-exact')"
|
||||
>
|
||||
{{ $t('date is') }}
|
||||
<span
|
||||
|
||||
:class="clickableClasses"
|
||||
>
|
||||
<q-icon
|
||||
name="today"
|
||||
/>
|
||||
{{ timeSet.times | timeSetDateExact }}
|
||||
<csc-cf-condition-popup-date
|
||||
:mapping="mapping"
|
||||
:destination-set="destinationSet"
|
||||
:source-set="sourceSet"
|
||||
:time-set="timeSet"
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
<template
|
||||
v-else-if="timeSet.name.startsWith('csc-date-range')"
|
||||
>
|
||||
{{ $t('date range is') }}
|
||||
<span
|
||||
|
||||
:class="clickableClasses"
|
||||
>
|
||||
<q-icon
|
||||
name="book_online"
|
||||
/>
|
||||
{{ timeSet.times | timeSetDateRange }}
|
||||
<csc-cf-condition-popup-date-range
|
||||
:mapping="mapping"
|
||||
:destination-set="destinationSet"
|
||||
:source-set="sourceSet"
|
||||
:time-set="timeSet"
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
<template
|
||||
v-else-if="timeSet.name.startsWith('csc-weekdays')"
|
||||
>
|
||||
{{ $t('weekdays are') }}
|
||||
<span
|
||||
|
||||
:class="clickableClasses"
|
||||
>
|
||||
<q-icon
|
||||
name="calendar_today"
|
||||
/>
|
||||
{{ timeSet.times | timeSetWeekdays }}
|
||||
<csc-cf-condition-popup-weekdays
|
||||
:mapping="mapping"
|
||||
:destination-set="destinationSet"
|
||||
:source-set="sourceSet"
|
||||
:time-set="timeSet"
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
<template
|
||||
v-else-if="timeSet.name.startsWith('csc-office-hours')"
|
||||
>
|
||||
{{ $t('office hours are') }}
|
||||
<span
|
||||
|
||||
:class="clickableClasses"
|
||||
>
|
||||
<q-icon
|
||||
name="access_time"
|
||||
/>
|
||||
{{ timeSet.times | timeSetOfficeHoursSameTime }}
|
||||
<csc-cf-condition-popup-office-hours
|
||||
:mapping="mapping"
|
||||
:destination-set="destinationSet"
|
||||
:source-set="sourceSet"
|
||||
:time-set="timeSet"
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
<span
|
||||
v-else
|
||||
:class="clickableClasses"
|
||||
>
|
||||
{{ timeSet.times | timeSetTimes }}
|
||||
</span>
|
||||
</template>
|
||||
<template
|
||||
v-if="!sourceSet || !timeSet"
|
||||
>
|
||||
<span>
|
||||
{{ $t('and') }}
|
||||
</span>
|
||||
<span
|
||||
:class="clickableClasses"
|
||||
style="white-space: nowrap"
|
||||
>
|
||||
<q-icon
|
||||
name="alt_route"
|
||||
/>
|
||||
{{ $t('condition') }}
|
||||
<csc-cf-condition-popup-all
|
||||
step="menu"
|
||||
:mapping="mapping"
|
||||
:destination-set="destinationSet"
|
||||
:source-set="sourceSet"
|
||||
:time-set="timeSet"
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section
|
||||
side
|
||||
>
|
||||
<csc-more-menu>
|
||||
<csc-popup-menu-item
|
||||
v-if="mapping.type === 'cfu'"
|
||||
icon="ring_volume"
|
||||
:label="$t('Ring primary number')"
|
||||
@click="ringPrimaryNumberEvent"
|
||||
/>
|
||||
<csc-popup-menu-item
|
||||
v-if="mapping.type === 'cft'"
|
||||
icon="phone_disabled"
|
||||
:label="$t('Do not ring primary number')"
|
||||
@click="doNotRingPrimaryNumberEvent"
|
||||
/>
|
||||
<csc-popup-menu-item
|
||||
icon="phone_forwarded"
|
||||
:label="$t('Forward to Number')"
|
||||
:disable="hasTermination"
|
||||
@click="addDestinationEvent({
|
||||
destinationSetId: destinationSet.id
|
||||
})"
|
||||
/>
|
||||
<csc-popup-menu-item
|
||||
icon="voicemail"
|
||||
:label="$t('Forward to Voicebox')"
|
||||
:disable="hasTermination"
|
||||
@click="addDestinationEvent({
|
||||
destination: 'voicebox',
|
||||
destinationSetId: destinationSet.id
|
||||
})"
|
||||
/>
|
||||
<csc-popup-menu-item
|
||||
icon="email"
|
||||
:label="$t('Forward to Fax2Mail')"
|
||||
:disable="hasTermination"
|
||||
@click="addDestinationEvent({
|
||||
destination: 'fax2mail',
|
||||
destinationSetId: destinationSet.id
|
||||
})"
|
||||
/>
|
||||
<csc-popup-menu-item
|
||||
icon="phone_forwarded"
|
||||
:label="$t('Forward to ManagerSecretary')"
|
||||
:disable="hasTermination"
|
||||
@click="addDestinationEvent({
|
||||
destination: 'managersecretary',
|
||||
destinationSetId: destinationSet.id
|
||||
})"
|
||||
/>
|
||||
<csc-popup-menu-item
|
||||
icon="groups"
|
||||
:label="$t('Forward to Conference')"
|
||||
:disable="hasTermination"
|
||||
@click="addDestinationEvent({
|
||||
destination: 'conference',
|
||||
destinationSetId: destinationSet.id
|
||||
})"
|
||||
/>
|
||||
<csc-popup-menu-item
|
||||
:icon="(mapping.enabled)?'toggle_on':'toggle_off'"
|
||||
:label="(mapping.enabled)?$t('Disable'):$t('Enable')"
|
||||
@click="toggleMappingEvent(mapping)"
|
||||
/>
|
||||
<csc-popup-menu-item-delete
|
||||
@click="deleteMappingEvent(mapping)"
|
||||
/>
|
||||
</csc-more-menu>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
import {
|
||||
mapActions
|
||||
} from 'vuex'
|
||||
import CscMoreMenu from 'components/CscMoreMenu'
|
||||
import CscPopupMenuItemDelete from 'components/CscPopupMenuItemDelete'
|
||||
import CscPopupMenuItem from 'components/CscPopupMenuItem'
|
||||
import CscCfConditionPopupAll from 'components/call-forwarding/CscCfConditionPopupAll'
|
||||
import CscCfConditionPopupDate from 'components/call-forwarding/CscCfConditionPopupDate'
|
||||
import CscCfConditionPopupCallFrom from 'components/call-forwarding/CscCfConditionPopupCallFrom'
|
||||
import CscCfConditionPopupCallNotFrom from 'components/call-forwarding/CscCfConditionPopupCallNotFrom'
|
||||
import CscCfConditionPopupDateRange from 'components/call-forwarding/CscCfConditionPopupDateRange'
|
||||
import CscCfConditionPopupWeekdays from 'components/call-forwarding/CscCfConditionPopupWeekdays'
|
||||
import CscCfConditionPopupOfficeHours from 'components/call-forwarding/CscCfConditionPopupOfficeHours'
|
||||
export default {
|
||||
name: 'CscCfGroupTitle',
|
||||
components: {
|
||||
CscCfConditionPopupOfficeHours,
|
||||
CscCfConditionPopupWeekdays,
|
||||
CscCfConditionPopupDateRange,
|
||||
CscCfConditionPopupCallNotFrom,
|
||||
CscCfConditionPopupCallFrom,
|
||||
CscCfConditionPopupDate,
|
||||
CscCfConditionPopupAll,
|
||||
CscPopupMenuItem,
|
||||
CscPopupMenuItemDelete,
|
||||
CscMoreMenu
|
||||
},
|
||||
props: {
|
||||
mapping: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
destinationSet: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
sourceSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
timeSet: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
clickableClasses () {
|
||||
return ['cursor-pointer', 'text-weight-bold', 'text-primary']
|
||||
},
|
||||
waitIdentifier () {
|
||||
return 'csc-cf-group-' + this.destinationSet.id
|
||||
},
|
||||
hasTermination () {
|
||||
return _.endsWith(_.last(this.destinationSet.destinations).destination, 'voicebox.local') ||
|
||||
_.endsWith(_.last(this.destinationSet.destinations).destination, 'fax2mail.local') ||
|
||||
_.endsWith(_.last(this.destinationSet.destinations).destination, 'managersecretary.local') ||
|
||||
_.endsWith(_.last(this.destinationSet.destinations).destination, 'conference.local') ||
|
||||
_.endsWith(_.last(this.destinationSet.destinations).destination, 'app.local')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions('callForwarding', [
|
||||
'deleteMapping',
|
||||
'toggleMapping',
|
||||
'addDestination',
|
||||
'ringPrimaryNumber',
|
||||
'doNotRingPrimaryNumber'
|
||||
]),
|
||||
async addDestinationEvent (payload) {
|
||||
this.$wait.start(this.waitIdentifier)
|
||||
await this.addDestination(payload)
|
||||
this.$wait.end(this.waitIdentifier)
|
||||
},
|
||||
async toggleMappingEvent (mapping) {
|
||||
this.$wait.start(this.waitIdentifier)
|
||||
await this.toggleMapping(mapping)
|
||||
this.$wait.end(this.waitIdentifier)
|
||||
},
|
||||
async deleteMappingEvent (mapping) {
|
||||
this.$q.dialog({
|
||||
title: this.$t('Delete forwarding'),
|
||||
message: 'You are about to delete this forwarding',
|
||||
color: 'negative',
|
||||
cancel: true,
|
||||
persistent: true
|
||||
}).onOk(async data => {
|
||||
this.$wait.start(this.waitIdentifier)
|
||||
await this.deleteMapping(mapping)
|
||||
this.$wait.end(this.waitIdentifier)
|
||||
})
|
||||
},
|
||||
async ringPrimaryNumberEvent () {
|
||||
this.$wait.start('csc-cf-mappings-full')
|
||||
await this.ringPrimaryNumber()
|
||||
this.$wait.end('csc-cf-mappings-full')
|
||||
},
|
||||
async doNotRingPrimaryNumberEvent () {
|
||||
this.$wait.start('csc-cf-mappings-full')
|
||||
await this.doNotRingPrimaryNumber()
|
||||
this.$wait.end('csc-cf-mappings-full')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,113 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
v-if="!tabs"
|
||||
class="row justify-around"
|
||||
>
|
||||
<q-btn
|
||||
v-for="(day, index) in days"
|
||||
:key="day.value"
|
||||
:label="$t(day.label)"
|
||||
:class="(index > 0)?'q-ml-sm':''"
|
||||
round
|
||||
no-caps
|
||||
unelevated
|
||||
:color="(isSelected(day))?'primary':'dark'"
|
||||
:text-color="(isSelected(day))?'dark':'primary'"
|
||||
@click="toggle(day)"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
>
|
||||
<q-tabs
|
||||
v-model="selectedTab"
|
||||
dense
|
||||
active-color="primary"
|
||||
indicator-color="primary"
|
||||
align="center"
|
||||
>
|
||||
<q-tab
|
||||
v-for="(day) in days"
|
||||
:key="day.value"
|
||||
:name="'tab-' + day.value"
|
||||
:label="$t(day.label)"
|
||||
class="text-primary no-padding"
|
||||
inline-label
|
||||
outside-arrows
|
||||
mobile-arrows
|
||||
no-caps
|
||||
/>
|
||||
</q-tabs>
|
||||
<q-separator
|
||||
v-if="tabs"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
DAY_MAP,
|
||||
DAY_NAME_MAP
|
||||
} from 'src/filters/time-set'
|
||||
|
||||
export default {
|
||||
name: 'CscCfSelectionWeekdays',
|
||||
props: {
|
||||
value: {
|
||||
type: Array,
|
||||
default: () => [DAY_MAP[0]]
|
||||
},
|
||||
tabs: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
selectedWeekdays: this.value
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
selectedTab: {
|
||||
get () {
|
||||
return 'tab-' + this.selectedWeekdays[0]
|
||||
},
|
||||
set (tab) {
|
||||
this.selectedWeekdays = [parseInt(tab.replace('tab-', ''))]
|
||||
}
|
||||
},
|
||||
days () {
|
||||
const options = []
|
||||
DAY_MAP.forEach((day, index) => {
|
||||
options.push({
|
||||
label: DAY_NAME_MAP[index].substr(0, 2),
|
||||
value: day
|
||||
})
|
||||
})
|
||||
return options
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
selectedWeekdays (weekdays) {
|
||||
this.$emit('input', weekdays)
|
||||
},
|
||||
value (weekdays) {
|
||||
this.selectedWeekdays = weekdays
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toggle (day) {
|
||||
if (this.isSelected(day)) {
|
||||
this.selectedWeekdays = this.selectedWeekdays.filter(dayValue => day.value !== dayValue)
|
||||
} else {
|
||||
this.selectedWeekdays.push(day.value)
|
||||
}
|
||||
},
|
||||
isSelected (day) {
|
||||
return this.selectedWeekdays.find(dayValue => day.value === dayValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<q-select
|
||||
:value="value"
|
||||
:options="options"
|
||||
emit-value
|
||||
use-input
|
||||
map-options
|
||||
input-debounce="300"
|
||||
v-bind="$attrs"
|
||||
@filter="filter"
|
||||
v-on="$listeners"
|
||||
/>
|
||||
</template>
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
import {
|
||||
mapActions,
|
||||
mapState
|
||||
} from 'vuex'
|
||||
export default {
|
||||
name: 'CscCfSourceSetSelection',
|
||||
props: {
|
||||
value: {
|
||||
type: [String, Number],
|
||||
default: undefined
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
options: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState('callForwarding', [
|
||||
'sourceSets'
|
||||
]),
|
||||
allOptions () {
|
||||
const options = []
|
||||
if (this.sourceSets) {
|
||||
this.sourceSets.forEach((sourceSet) => {
|
||||
if (sourceSet.mode === this.mode) {
|
||||
options.push({
|
||||
value: sourceSet.id,
|
||||
label: sourceSet.name
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
return options
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions('callForwarding', [
|
||||
'loadSourceSets'
|
||||
]),
|
||||
async filter (value, update) {
|
||||
await this.loadSourceSets()
|
||||
if (value === '' || value === null || value === undefined) {
|
||||
update(() => {
|
||||
this.options = this.allOptions
|
||||
})
|
||||
} else {
|
||||
update(() => {
|
||||
this.options = this.allOptions.filter(sourceSet =>
|
||||
_.startsWith(_.lowerCase(sourceSet.label), _.lowerCase(value)))
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,79 @@
|
||||
|
||||
import { i18n } from 'boot/i18n'
|
||||
|
||||
export const DAY_MAP = [2, 3, 4, 5, 6, 7, 1]
|
||||
export const DAY_NAME_MAP = [
|
||||
i18n.t('Monday'),
|
||||
i18n.t('Tuesday'),
|
||||
i18n.t('Wednesday'),
|
||||
i18n.t('Thursday'),
|
||||
i18n.t('Friday'),
|
||||
i18n.t('Saturday'),
|
||||
i18n.t('Sunday')
|
||||
]
|
||||
|
||||
export const DEFAULT_WEEKDAYS = [
|
||||
DAY_MAP[0],
|
||||
DAY_MAP[1],
|
||||
DAY_MAP[2],
|
||||
DAY_MAP[3],
|
||||
DAY_MAP[4]
|
||||
]
|
||||
|
||||
export function timeSetDateExact (times) {
|
||||
return times[0].year + '/' + times[0].month + '/' + times[0].mday
|
||||
}
|
||||
|
||||
export function timeSetDateRange (times) {
|
||||
const years = times[0].year.split('-')
|
||||
const months = times[0].month.split('-')
|
||||
const dates = times[0].mday.split('-')
|
||||
return years[0] + '/' + months[0] + '/' + dates[0] + '-' +
|
||||
years[1] + '/' + months[1] + '/' + dates[1]
|
||||
}
|
||||
|
||||
export function timeSetWeekdays (times) {
|
||||
const mappedWeekdays = times.map((time) => {
|
||||
return DAY_MAP.indexOf(parseInt(time.wday))
|
||||
})
|
||||
mappedWeekdays.sort()
|
||||
let weekdays = ''
|
||||
mappedWeekdays.forEach((weekday, index) => {
|
||||
if (index > 0) {
|
||||
weekdays = weekdays + ', '
|
||||
}
|
||||
weekdays = weekdays + DAY_NAME_MAP[weekday]
|
||||
})
|
||||
return weekdays
|
||||
}
|
||||
|
||||
export function timeSetOfficeHoursSameTime (times) {
|
||||
const weekdays = new Set()
|
||||
let weekdaysStr = ''
|
||||
times.forEach((time) => {
|
||||
weekdays.add(parseInt(time.wday))
|
||||
})
|
||||
const weekdaysSorted = Array.from(weekdays)
|
||||
weekdaysSorted.sort((a, b) => {
|
||||
if (a === 1) {
|
||||
return 1
|
||||
} else if (a > b) {
|
||||
return 1
|
||||
} else if (a < b) {
|
||||
return -1
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
})
|
||||
weekdaysSorted.forEach((weekday, index) => {
|
||||
if (index > 0) {
|
||||
weekdaysStr += ', '
|
||||
}
|
||||
weekdaysStr += DAY_NAME_MAP[DAY_MAP.indexOf(weekday)]
|
||||
})
|
||||
return weekdaysStr
|
||||
}
|
||||
|
||||
export function timeSetTimes () {
|
||||
|
||||
}
|
||||
@ -0,0 +1,126 @@
|
||||
<template>
|
||||
<csc-page-sticky
|
||||
id="csc-page-call-forwarding"
|
||||
class="q-pa-lg"
|
||||
>
|
||||
<template
|
||||
v-slot:header
|
||||
>
|
||||
<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
|
||||
color="primary"
|
||||
:label="$t('If available')"
|
||||
@click="createMapping({ type: 'cfu'})"
|
||||
/>
|
||||
<csc-popup-menu-item
|
||||
color="primary"
|
||||
:label="$t('If not available')"
|
||||
@click="createMapping({ type: 'cfna'})"
|
||||
/>
|
||||
<csc-popup-menu-item
|
||||
color="primary"
|
||||
:label="$t('If busy')"
|
||||
@click="createMapping({ type: 'cfb'})"
|
||||
/>
|
||||
</csc-popup-menu>
|
||||
<template
|
||||
v-slot:loading
|
||||
>
|
||||
<csc-spinner />
|
||||
</template>
|
||||
</q-btn>
|
||||
</template>
|
||||
<div
|
||||
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>
|
||||
</div>
|
||||
</csc-page-sticky>
|
||||
</template>
|
||||
<script>
|
||||
import CscCfGroup from 'components/call-forwarding/CscCfGroup'
|
||||
import {
|
||||
mapActions,
|
||||
mapState,
|
||||
mapGetters
|
||||
} from 'vuex'
|
||||
import CscPopupMenuItem from 'components/CscPopupMenuItem'
|
||||
import CscPopupMenu from 'components/CscPopupMenu'
|
||||
import CscSpinner from 'components/CscSpinner'
|
||||
import CscCfGroupItemPrimaryNumber from 'components/call-forwarding/CscCfGroupItemPrimaryNumber'
|
||||
import CscPageSticky from 'components/CscPageSticky'
|
||||
export default {
|
||||
name: 'CscPageCf',
|
||||
components: {
|
||||
CscPageSticky,
|
||||
CscCfGroupItemPrimaryNumber,
|
||||
CscSpinner,
|
||||
CscPopupMenu,
|
||||
CscPopupMenuItem,
|
||||
CscCfGroup
|
||||
},
|
||||
computed: {
|
||||
...mapState('callForwarding', [
|
||||
'mappings',
|
||||
'destinationSetMap',
|
||||
'sourceSetMap',
|
||||
'timeSetMap'
|
||||
]),
|
||||
...mapGetters('callForwarding', [
|
||||
'groups'
|
||||
])
|
||||
},
|
||||
mounted () {
|
||||
this.loadMappingsFull()
|
||||
},
|
||||
methods: {
|
||||
...mapActions('callForwarding', [
|
||||
'loadMappingsFull',
|
||||
'createMapping'
|
||||
])
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,525 @@
|
||||
import {
|
||||
cfCreateOfficeHours, cfCreateOfficeHoursSameTimes,
|
||||
cfCreateSourceSet,
|
||||
cfCreateTimeSetDate,
|
||||
cfCreateTimeSetDateRange,
|
||||
cfCreateTimeSetWeekdays,
|
||||
cfDeleteDestinationSet,
|
||||
cfDeleteSourceSet,
|
||||
cfDeleteTimeSet,
|
||||
cfLoadDestinationSets,
|
||||
cfLoadMappingsFull,
|
||||
cfLoadSourceSets,
|
||||
cfLoadTimeSets, cfUpdateOfficeHours, cfUpdateOfficeHoursSameTimes,
|
||||
cfUpdateSourceSet,
|
||||
cfUpdateTimeSetDate,
|
||||
cfUpdateTimeSetDateRange,
|
||||
cfUpdateTimeSetWeekdays
|
||||
} from 'src/api/call-forwarding'
|
||||
import {
|
||||
v4
|
||||
} from 'uuid'
|
||||
import {
|
||||
patchReplace,
|
||||
patchReplaceFull,
|
||||
post, put
|
||||
} from 'src/api/common'
|
||||
import _ from 'lodash'
|
||||
|
||||
const DEFAULT_RING_TIMEOUT = 60
|
||||
const DEFAULT_PRIORITY = 0
|
||||
const WAIT_IDENTIFIER = 'csc-cf-mappings-full'
|
||||
|
||||
function createDefaultDestination (destination) {
|
||||
let finalDestination = 'Number'
|
||||
if (destination) {
|
||||
finalDestination = destination
|
||||
}
|
||||
return {
|
||||
destination: finalDestination,
|
||||
priority: DEFAULT_PRIORITY,
|
||||
timeout: DEFAULT_RING_TIMEOUT
|
||||
}
|
||||
}
|
||||
|
||||
export async function loadMappingsFull ({ dispatch, commit, rootGetters }) {
|
||||
dispatch('wait/start', WAIT_IDENTIFIER, { root: true })
|
||||
const res = await cfLoadMappingsFull(rootGetters['user/getSubscriberId'])
|
||||
commit('dataSucceeded', {
|
||||
mappings: res[0],
|
||||
destinationSets: res[1].items,
|
||||
sourceSets: res[2].items,
|
||||
timeSets: res[3].items
|
||||
})
|
||||
dispatch('wait/end', WAIT_IDENTIFIER, { root: true })
|
||||
}
|
||||
|
||||
export async function createMapping ({ dispatch, commit, state, rootGetters }, payload) {
|
||||
dispatch('wait/start', WAIT_IDENTIFIER, { root: true })
|
||||
let type = payload.type
|
||||
if (payload.type === 'cfu' && state.mappings.cft && state.mappings.cft.length > 0) {
|
||||
type = 'cft'
|
||||
}
|
||||
const mappings = _.cloneDeep(state.mappings[type])
|
||||
const destinationSetId = await post({
|
||||
resource: 'cfdestinationsets',
|
||||
body: {
|
||||
name: 'csc-' + v4(),
|
||||
subscriber_id: rootGetters['user/getSubscriberId'],
|
||||
destinations: [createDefaultDestination()]
|
||||
}
|
||||
})
|
||||
mappings.push({
|
||||
destinationset_id: destinationSetId
|
||||
})
|
||||
const res = await Promise.all([
|
||||
patchReplaceFull({
|
||||
resource: 'cfmappings',
|
||||
resourceId: rootGetters['user/getSubscriberId'],
|
||||
fieldPath: type,
|
||||
value: mappings
|
||||
}),
|
||||
cfLoadDestinationSets(rootGetters['user/getSubscriberId'])
|
||||
])
|
||||
commit('dataSucceeded', {
|
||||
mappings: res[0],
|
||||
destinationSets: res[1].items
|
||||
})
|
||||
dispatch('wait/end', WAIT_IDENTIFIER, { root: true })
|
||||
}
|
||||
|
||||
export async function deleteMapping ({ dispatch, commit, state, rootGetters }, payload) {
|
||||
dispatch('wait/start', WAIT_IDENTIFIER, { root: true })
|
||||
const mappings = _.cloneDeep(state.mappings[payload.type])
|
||||
const updatedMappings = mappings.reduce(($updatedMappings, value, index) => {
|
||||
if (index !== payload.index) {
|
||||
$updatedMappings.push(value)
|
||||
}
|
||||
return $updatedMappings
|
||||
}, [])
|
||||
const patchRes = await patchReplaceFull({
|
||||
resource: 'cfmappings',
|
||||
resourceId: rootGetters['user/getSubscriberId'],
|
||||
fieldPath: payload.type,
|
||||
value: updatedMappings
|
||||
})
|
||||
await cfDeleteDestinationSet(payload.destinationset_id)
|
||||
const destinationSets = await cfLoadDestinationSets(rootGetters['user/getSubscriberId'])
|
||||
commit('dataSucceeded', {
|
||||
mappings: patchRes,
|
||||
destinationSets: destinationSets.items
|
||||
})
|
||||
dispatch('wait/end', WAIT_IDENTIFIER, { root: true })
|
||||
}
|
||||
|
||||
export async function toggleMapping ({ dispatch, commit, state, rootGetters }, payload) {
|
||||
dispatch('wait/start', WAIT_IDENTIFIER, { root: true })
|
||||
const updatedMappings = _.cloneDeep(state.mappings[payload.type])
|
||||
updatedMappings[payload.index].enabled = !updatedMappings[payload.index].enabled
|
||||
const patchRes = await patchReplaceFull({
|
||||
resource: 'cfmappings',
|
||||
resourceId: rootGetters['user/getSubscriberId'],
|
||||
fieldPath: payload.type,
|
||||
value: updatedMappings
|
||||
})
|
||||
commit('dataSucceeded', {
|
||||
mappings: patchRes
|
||||
})
|
||||
dispatch('wait/end', WAIT_IDENTIFIER, { root: true })
|
||||
}
|
||||
|
||||
export async function updateDestination ({ dispatch, commit, state, rootGetters }, payload) {
|
||||
dispatch('wait/start', WAIT_IDENTIFIER, { root: true })
|
||||
const destinations = _.cloneDeep(state.destinationSetMap[payload.destinationSetId].destinations)
|
||||
destinations[payload.destinationIndex].destination = payload.destination
|
||||
await patchReplace({
|
||||
resource: 'cfdestinationsets',
|
||||
resourceId: payload.destinationSetId,
|
||||
fieldPath: 'destinations',
|
||||
value: destinations
|
||||
})
|
||||
const destinationSets = await cfLoadDestinationSets(rootGetters['user/getSubscriberId'])
|
||||
commit('dataSucceeded', {
|
||||
destinationSets: destinationSets.items
|
||||
})
|
||||
dispatch('wait/end', WAIT_IDENTIFIER, { root: true })
|
||||
}
|
||||
|
||||
export async function addDestination ({ dispatch, commit, state, rootGetters }, payload) {
|
||||
dispatch('wait/start', WAIT_IDENTIFIER, { root: true })
|
||||
const destinations = _.cloneDeep(state.destinationSetMap[payload.destinationSetId].destinations)
|
||||
destinations.push(createDefaultDestination(payload.destination))
|
||||
await patchReplace({
|
||||
resource: 'cfdestinationsets',
|
||||
resourceId: payload.destinationSetId,
|
||||
fieldPath: 'destinations',
|
||||
value: destinations
|
||||
})
|
||||
const destinationSets = await cfLoadDestinationSets(rootGetters['user/getSubscriberId'])
|
||||
commit('dataSucceeded', {
|
||||
destinationSets: destinationSets.items
|
||||
})
|
||||
dispatch('wait/end', WAIT_IDENTIFIER, { root: true })
|
||||
}
|
||||
|
||||
export async function removeDestination ({ dispatch, commit, state, rootGetters }, payload) {
|
||||
dispatch('wait/start', WAIT_IDENTIFIER, { root: true })
|
||||
const destinations = _.cloneDeep(state.destinationSetMap[payload.destinationSetId].destinations)
|
||||
const updatedDestinations = destinations.reduce(($updatedDestinations, value, index) => {
|
||||
if (index !== payload.destinationIndex) {
|
||||
$updatedDestinations.push(value)
|
||||
}
|
||||
return $updatedDestinations
|
||||
}, [])
|
||||
await patchReplace({
|
||||
resource: 'cfdestinationsets',
|
||||
resourceId: payload.destinationSetId,
|
||||
fieldPath: 'destinations',
|
||||
value: updatedDestinations
|
||||
})
|
||||
const destinationSets = await cfLoadDestinationSets(rootGetters['user/getSubscriberId'])
|
||||
commit('dataSucceeded', {
|
||||
destinationSets: destinationSets.items
|
||||
})
|
||||
dispatch('wait/end', WAIT_IDENTIFIER, { root: true })
|
||||
}
|
||||
|
||||
export async function updateDestinationTimeout ({ dispatch, commit, state, rootGetters }, payload) {
|
||||
dispatch('wait/start', WAIT_IDENTIFIER, { root: true })
|
||||
const destinations = _.cloneDeep(state.destinationSetMap[payload.destinationSetId].destinations)
|
||||
destinations[payload.destinationIndex].timeout = payload.destinationTimeout
|
||||
await patchReplace({
|
||||
resource: 'cfdestinationsets',
|
||||
resourceId: payload.destinationSetId,
|
||||
fieldPath: 'destinations',
|
||||
value: destinations
|
||||
})
|
||||
const destinationSets = await cfLoadDestinationSets(rootGetters['user/getSubscriberId'])
|
||||
commit('dataSucceeded', {
|
||||
destinationSets: destinationSets.items
|
||||
})
|
||||
dispatch('wait/end', WAIT_IDENTIFIER, { root: true })
|
||||
}
|
||||
|
||||
export async function loadSourceSets ({ dispatch, commit, rootGetters }) {
|
||||
dispatch('wait/start', 'csc-cf-sourcesets', { root: true })
|
||||
const sourceSets = await cfLoadSourceSets(rootGetters['user/getSubscriberId'])
|
||||
commit('dataSucceeded', {
|
||||
sourceSets: sourceSets.items
|
||||
})
|
||||
dispatch('wait/end', 'csc-cf-sourcesets', { root: true })
|
||||
}
|
||||
|
||||
export async function createSourceSet ({ dispatch, commit, rootGetters, state }, payload) {
|
||||
try {
|
||||
dispatch('wait/start', 'csc-cf-source-set-create', { root: true })
|
||||
const sourceSetId = await cfCreateSourceSet(rootGetters['user/getSubscriberId'], payload)
|
||||
const updatedMapping = _.cloneDeep(state.mappings[payload.mapping.type])
|
||||
updatedMapping[payload.mapping.index].sourceset_id = sourceSetId
|
||||
const updatedMappings = await patchReplaceFull({
|
||||
resource: 'cfmappings',
|
||||
resourceId: rootGetters['user/getSubscriberId'],
|
||||
fieldPath: payload.mapping.type,
|
||||
value: updatedMapping
|
||||
})
|
||||
const sourceSets = await cfLoadSourceSets(rootGetters['user/getSubscriberId'])
|
||||
commit('dataSucceeded', {
|
||||
mappings: updatedMappings,
|
||||
sourceSets: sourceSets.items
|
||||
})
|
||||
} finally {
|
||||
dispatch('wait/end', 'csc-cf-source-set-create', { root: true })
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateSourceSet ({ dispatch, commit, rootGetters, state }, payload) {
|
||||
try {
|
||||
dispatch('wait/start', 'csc-cf-source-set-create', { root: true })
|
||||
await cfUpdateSourceSet(rootGetters['user/getSubscriberId'], payload)
|
||||
const sourceSets = await cfLoadSourceSets(rootGetters['user/getSubscriberId'])
|
||||
commit('dataSucceeded', {
|
||||
sourceSets: sourceSets.items
|
||||
})
|
||||
} finally {
|
||||
dispatch('wait/end', 'csc-cf-source-set-create', { root: true })
|
||||
}
|
||||
}
|
||||
|
||||
export async function deleteSourceSet ({ dispatch, commit, rootGetters, state }, payload) {
|
||||
try {
|
||||
dispatch('wait/start', 'csc-cf-source-set-create', { root: true })
|
||||
const updatedMapping = _.cloneDeep(state.mappings[payload.mapping.type])
|
||||
updatedMapping[payload.mapping.index].sourceset_id = null
|
||||
updatedMapping[payload.mapping.index].sourceset = null
|
||||
const updatedMappings = await patchReplaceFull({
|
||||
resource: 'cfmappings',
|
||||
resourceId: rootGetters['user/getSubscriberId'],
|
||||
fieldPath: payload.mapping.type,
|
||||
value: updatedMapping
|
||||
})
|
||||
await cfDeleteSourceSet(payload.id)
|
||||
const sourceSets = await cfLoadSourceSets(rootGetters['user/getSubscriberId'])
|
||||
commit('dataSucceeded', {
|
||||
mappings: updatedMappings,
|
||||
sourceSets: sourceSets.items
|
||||
})
|
||||
} finally {
|
||||
dispatch('wait/end', 'csc-cf-source-set-create', { root: true })
|
||||
}
|
||||
}
|
||||
|
||||
export async function assignSourceSet ({ dispatch, commit, rootGetters, state }, payload) {
|
||||
try {
|
||||
dispatch('wait/start', 'csc-cf-source-set-create', { root: true })
|
||||
const updatedMapping = _.cloneDeep(state.mappings[payload.mapping.type])
|
||||
updatedMapping[payload.mapping.index].sourceset_id = payload.id
|
||||
const updatedMappings = await patchReplaceFull({
|
||||
resource: 'cfmappings',
|
||||
resourceId: rootGetters['user/getSubscriberId'],
|
||||
fieldPath: payload.mapping.type,
|
||||
value: updatedMapping
|
||||
})
|
||||
commit('dataSucceeded', {
|
||||
mappings: updatedMappings
|
||||
})
|
||||
} finally {
|
||||
dispatch('wait/end', 'csc-cf-source-set-create', { root: true })
|
||||
}
|
||||
}
|
||||
|
||||
export async function unassignSourceSet ({ dispatch, commit, rootGetters, state }, payload) {
|
||||
try {
|
||||
dispatch('wait/start', 'csc-cf-source-set-create', { root: true })
|
||||
const updatedMapping = _.cloneDeep(state.mappings[payload.mapping.type])
|
||||
updatedMapping[payload.mapping.index].sourceset_id = null
|
||||
updatedMapping[payload.mapping.index].sourceset = null
|
||||
const updatedMappings = await patchReplaceFull({
|
||||
resource: 'cfmappings',
|
||||
resourceId: rootGetters['user/getSubscriberId'],
|
||||
fieldPath: payload.mapping.type,
|
||||
value: updatedMapping
|
||||
})
|
||||
commit('dataSucceeded', {
|
||||
mappings: updatedMappings
|
||||
})
|
||||
} finally {
|
||||
dispatch('wait/end', 'csc-cf-source-set-create', { root: true })
|
||||
}
|
||||
}
|
||||
|
||||
export async function createTimeSetDate ({ dispatch, commit, rootGetters, state }, payload) {
|
||||
dispatch('wait/start', 'csc-cf-time-set-create', { root: true })
|
||||
const timeSetId = await cfCreateTimeSetDate(rootGetters['user/getSubscriberId'], payload.date)
|
||||
const updatedMapping = _.cloneDeep(state.mappings[payload.mapping.type])
|
||||
updatedMapping[payload.mapping.index].timeset_id = timeSetId
|
||||
const updatedMappings = await patchReplaceFull({
|
||||
resource: 'cfmappings',
|
||||
resourceId: rootGetters['user/getSubscriberId'],
|
||||
fieldPath: payload.mapping.type,
|
||||
value: updatedMapping
|
||||
})
|
||||
const timeSets = await cfLoadTimeSets(rootGetters['user/getSubscriberId'])
|
||||
commit('dataSucceeded', {
|
||||
mappings: updatedMappings,
|
||||
timeSets: timeSets.items
|
||||
})
|
||||
dispatch('wait/end', 'csc-cf-time-set-create', { root: true })
|
||||
}
|
||||
|
||||
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'])
|
||||
commit('dataSucceeded', {
|
||||
timeSets: timeSets.items
|
||||
})
|
||||
dispatch('wait/end', 'csc-cf-time-set-create', { root: true })
|
||||
}
|
||||
|
||||
export async function deleteTimeSet ({ dispatch, commit, rootGetters, state }, payload) {
|
||||
dispatch('wait/start', 'csc-cf-time-set-create', { root: true })
|
||||
const updatedMapping = _.cloneDeep(state.mappings[payload.mapping.type])
|
||||
updatedMapping[payload.mapping.index].timeset_id = null
|
||||
updatedMapping[payload.mapping.index].timeset = null
|
||||
const updatedMappings = await patchReplaceFull({
|
||||
resource: 'cfmappings',
|
||||
resourceId: rootGetters['user/getSubscriberId'],
|
||||
fieldPath: payload.mapping.type,
|
||||
value: updatedMapping
|
||||
})
|
||||
await cfDeleteTimeSet(payload.id)
|
||||
const timeSets = await cfLoadTimeSets(rootGetters['user/getSubscriberId'])
|
||||
commit('dataSucceeded', {
|
||||
mappings: updatedMappings,
|
||||
timeSets: timeSets.items
|
||||
})
|
||||
dispatch('wait/end', 'csc-cf-time-set-create', { root: true })
|
||||
}
|
||||
|
||||
export async function ringPrimaryNumber ({ commit, rootGetters, state }) {
|
||||
const mappings = _.cloneDeep(state.mappings)
|
||||
mappings.cft = mappings.cfu
|
||||
mappings.cfu = []
|
||||
mappings.cft_ringtimeout = 60
|
||||
const updatedMappings = await put({
|
||||
resource: 'cfmappings',
|
||||
resourceId: rootGetters['user/getSubscriberId'],
|
||||
body: mappings
|
||||
})
|
||||
commit('dataSucceeded', {
|
||||
mappings: updatedMappings
|
||||
})
|
||||
}
|
||||
|
||||
export async function doNotRingPrimaryNumber ({ commit, rootGetters, state }) {
|
||||
const mappings = _.cloneDeep(state.mappings)
|
||||
mappings.cfu = mappings.cft
|
||||
mappings.cft = []
|
||||
mappings.cft_ringtimeout = null
|
||||
const updatedMappings = await put({
|
||||
resource: 'cfmappings',
|
||||
resourceId: rootGetters['user/getSubscriberId'],
|
||||
body: mappings
|
||||
})
|
||||
commit('dataSucceeded', {
|
||||
mappings: updatedMappings
|
||||
})
|
||||
}
|
||||
|
||||
export async function updateRingTimeout ({ commit, rootGetters, state }, ringTimeout) {
|
||||
const updatedMappings = await patchReplaceFull({
|
||||
resource: 'cfmappings',
|
||||
resourceId: rootGetters['user/getSubscriberId'],
|
||||
fieldPath: 'cft_ringtimeout',
|
||||
value: ringTimeout
|
||||
})
|
||||
commit('dataSucceeded', {
|
||||
mappings: updatedMappings
|
||||
})
|
||||
}
|
||||
|
||||
export async function createTimeSetDateRange ({ dispatch, commit, rootGetters, state }, payload) {
|
||||
dispatch('wait/start', 'csc-cf-time-set-create', { root: true })
|
||||
const timeSetId = await cfCreateTimeSetDateRange(rootGetters['user/getSubscriberId'], payload.date)
|
||||
const updatedMapping = _.cloneDeep(state.mappings[payload.mapping.type])
|
||||
updatedMapping[payload.mapping.index].timeset_id = timeSetId
|
||||
const updatedMappings = await patchReplaceFull({
|
||||
resource: 'cfmappings',
|
||||
resourceId: rootGetters['user/getSubscriberId'],
|
||||
fieldPath: payload.mapping.type,
|
||||
value: updatedMapping
|
||||
})
|
||||
const timeSets = await cfLoadTimeSets(rootGetters['user/getSubscriberId'])
|
||||
commit('dataSucceeded', {
|
||||
mappings: updatedMappings,
|
||||
timeSets: timeSets.items
|
||||
})
|
||||
dispatch('wait/end', 'csc-cf-time-set-create', { root: true })
|
||||
}
|
||||
|
||||
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'])
|
||||
commit('dataSucceeded', {
|
||||
timeSets: timeSets.items
|
||||
})
|
||||
dispatch('wait/end', 'csc-cf-time-set-create', { root: true })
|
||||
}
|
||||
|
||||
export async function createTimeSetWeekdays ({ dispatch, commit, rootGetters, state }, payload) {
|
||||
dispatch('wait/start', 'csc-cf-time-set-create', { root: true })
|
||||
const timeSetId = await cfCreateTimeSetWeekdays(rootGetters['user/getSubscriberId'], payload.weekdays)
|
||||
const updatedMapping = _.cloneDeep(state.mappings[payload.mapping.type])
|
||||
updatedMapping[payload.mapping.index].timeset_id = timeSetId
|
||||
const updatedMappings = await patchReplaceFull({
|
||||
resource: 'cfmappings',
|
||||
resourceId: rootGetters['user/getSubscriberId'],
|
||||
fieldPath: payload.mapping.type,
|
||||
value: updatedMapping
|
||||
})
|
||||
const timeSets = await cfLoadTimeSets(rootGetters['user/getSubscriberId'])
|
||||
commit('dataSucceeded', {
|
||||
mappings: updatedMappings,
|
||||
timeSets: timeSets.items
|
||||
})
|
||||
dispatch('wait/end', 'csc-cf-time-set-create', { root: true })
|
||||
}
|
||||
|
||||
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'])
|
||||
commit('dataSucceeded', {
|
||||
timeSets: timeSets.items
|
||||
})
|
||||
dispatch('wait/end', 'csc-cf-time-set-create', { root: true })
|
||||
}
|
||||
|
||||
export async function createOfficeHours ({ dispatch, commit, rootGetters, state }, payload) {
|
||||
dispatch('wait/start', 'csc-cf-time-set-create', { root: true })
|
||||
const timeSetId = await cfCreateOfficeHours(rootGetters['user/getSubscriberId'], payload.times)
|
||||
const updatedMapping = _.cloneDeep(state.mappings[payload.mapping.type])
|
||||
updatedMapping[payload.mapping.index].timeset_id = timeSetId
|
||||
const updatedMappings = await patchReplaceFull({
|
||||
resource: 'cfmappings',
|
||||
resourceId: rootGetters['user/getSubscriberId'],
|
||||
fieldPath: payload.mapping.type,
|
||||
value: updatedMapping
|
||||
})
|
||||
if (payload.id) {
|
||||
await cfDeleteTimeSet(payload.id)
|
||||
}
|
||||
const timeSets = await cfLoadTimeSets(rootGetters['user/getSubscriberId'])
|
||||
commit('dataSucceeded', {
|
||||
mappings: updatedMappings,
|
||||
timeSets: timeSets.items
|
||||
})
|
||||
dispatch('wait/end', 'csc-cf-time-set-create', { root: true })
|
||||
}
|
||||
|
||||
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'])
|
||||
commit('dataSucceeded', {
|
||||
timeSets: timeSets.items
|
||||
})
|
||||
dispatch('wait/end', 'csc-cf-time-set-create', { root: true })
|
||||
}
|
||||
|
||||
export async function createOfficeHoursSameTimes ({ dispatch, commit, rootGetters, state }, payload) {
|
||||
dispatch('wait/start', 'csc-cf-time-set-create', { root: true })
|
||||
const timeSetId = await cfCreateOfficeHoursSameTimes(
|
||||
rootGetters['user/getSubscriberId'],
|
||||
payload.times,
|
||||
payload.weekdays
|
||||
)
|
||||
const updatedMapping = _.cloneDeep(state.mappings[payload.mapping.type])
|
||||
updatedMapping[payload.mapping.index].timeset_id = timeSetId
|
||||
const updatedMappings = await patchReplaceFull({
|
||||
resource: 'cfmappings',
|
||||
resourceId: rootGetters['user/getSubscriberId'],
|
||||
fieldPath: payload.mapping.type,
|
||||
value: updatedMapping
|
||||
})
|
||||
if (payload.id) {
|
||||
await cfDeleteTimeSet(payload.id)
|
||||
}
|
||||
const timeSets = await cfLoadTimeSets(rootGetters['user/getSubscriberId'])
|
||||
commit('dataSucceeded', {
|
||||
mappings: updatedMappings,
|
||||
timeSets: timeSets.items
|
||||
})
|
||||
dispatch('wait/end', 'csc-cf-time-set-create', { root: true })
|
||||
}
|
||||
|
||||
export async function updateOfficeHoursSameTimes ({ dispatch, commit, rootGetters, state }, payload) {
|
||||
dispatch('wait/start', 'csc-cf-time-set-create', { root: true })
|
||||
await cfUpdateOfficeHoursSameTimes(payload.id, payload.times, payload.weekdays)
|
||||
const timeSets = await cfLoadTimeSets(rootGetters['user/getSubscriberId'])
|
||||
commit('dataSucceeded', {
|
||||
timeSets: timeSets.items
|
||||
})
|
||||
dispatch('wait/end', 'csc-cf-time-set-create', { root: true })
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
import _ from 'lodash'
|
||||
|
||||
export function groups (state) {
|
||||
const types = ['cfu', 'cft', 'cfna', 'cfb']
|
||||
const mappings = []
|
||||
types.forEach((type) => {
|
||||
state.mappings[type].forEach((mapping, index) => {
|
||||
const clonedMapping = _.clone(mapping)
|
||||
clonedMapping.type = type
|
||||
clonedMapping.index = index
|
||||
mappings.push(clonedMapping)
|
||||
})
|
||||
})
|
||||
return mappings
|
||||
}
|
||||
|
||||
export function ringTimeout (state) {
|
||||
return state.mappings.cft_ringtimeout
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
import state from './state'
|
||||
import * as getters from './getters'
|
||||
import * as mutations from './mutations'
|
||||
import * as actions from './actions'
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state,
|
||||
getters,
|
||||
mutations,
|
||||
actions
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
|
||||
export function dataSucceeded (state, res) {
|
||||
if (res.destinationSets) {
|
||||
const destinationSetMap = {}
|
||||
res.destinationSets.forEach((destinationSet) => {
|
||||
destinationSetMap[destinationSet.id] = destinationSet
|
||||
})
|
||||
state.destinationSetMap = destinationSetMap
|
||||
}
|
||||
if (res.sourceSets) {
|
||||
const sourceSetMap = {}
|
||||
res.sourceSets.forEach((sourceSet) => {
|
||||
sourceSetMap[sourceSet.id] = sourceSet
|
||||
})
|
||||
state.sourceSetMap = sourceSetMap
|
||||
state.sourceSets = res.sourceSets
|
||||
}
|
||||
if (res.timeSets) {
|
||||
const timeSetMap = {}
|
||||
res.timeSets.forEach((timeSet) => {
|
||||
timeSetMap[timeSet.id] = timeSet
|
||||
})
|
||||
state.timeSetMap = timeSetMap
|
||||
state.timeSets = res.timeSets
|
||||
}
|
||||
if (res.mappings) {
|
||||
state.mappings = res.mappings
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
export default function () {
|
||||
return {
|
||||
mappings: {
|
||||
cfb: [],
|
||||
cfna: [],
|
||||
cfo: [],
|
||||
cfr: [],
|
||||
cfs: [],
|
||||
cft: [],
|
||||
cft_ringtimeout: null,
|
||||
cfu: []
|
||||
},
|
||||
destinationSets: null,
|
||||
destinationSetMap: {},
|
||||
sourceSets: null,
|
||||
sourceSetMap: {},
|
||||
timeSets: null,
|
||||
timeSetMap: {}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in new issue