TT#94101 CSC: Upgrade new Call Forwarding to latest Quasar

Change-Id: I383a67d94d2ca6e31b8afcdbd1a2d6d7e70db2c3
mr9.1.1
Carlo Venusino 5 years ago
parent 88b66464c6
commit 3aabf8c3c9

@ -119,7 +119,7 @@ export default {
default: null
},
sourcesetId: {
type: Number,
type: [Number, String],
default: null
}
},

@ -33,7 +33,7 @@ export default {
name: 'CscSourcesetsForm',
props: {
sourcesetId: {
type: Number,
type: [Number, String],
default: null
}
},

@ -4,10 +4,10 @@
class="csc-cf-group"
>
<div
class="row csc-cf-destination-cont"
class="row csc-cf-destination-cont csc-cf-group-header"
>
<div
class="col col-xs-12 col-md-4 text-right csc-cf-group-title-bold"
class="col-xs-4 col-md-4 text-right csc-cf-group-title-bold"
>
{{ groupTitle }}
<span
@ -17,19 +17,21 @@
<span class="csc-cf-from-link">
{{ $t('pages.newCallForward.fromLabelShort') +'"'+ groupSourceset +'"' }}
</span>
<q-popover
<q-menu
ref="sourcesList"
class="csc-cf-number-form"
@open="showSources()"
:target="$refs.target"
@show="showSources()"
>
<csc-new-call-forward-edit-sources
ref="editSources"
class="q-pa-md"
:source-set-name="groupSourceset"
:source-set-id="sourceSet.id"
:group-name="group.name"
:group-id="group.id"
@close="()=>{this.$refs.sourcesList.hide}"
/>
</q-popover>
</q-menu>
</span>
<span
@ -39,18 +41,35 @@
<span class="csc-cf-from-link">
{{ $t('pages.newCallForward.dateIsShort') + groupTimeset }}
</span>
<q-popover
ref="day"
class="csc-cf-popover-top-valign"
@open="showQDate()"
<q-menu
ref="dayWidget"
>
<q-datetime
ref="dayWidget"
<q-date
v-model="dayModel"
clear-label="REMOVE"
:min="today"
/>
</q-popover>
:options="minDate"
:no-unset="true"
>
<div class="row items-center justify-end q-gutter-sm">
<q-btn
v-close-popup
flat
color="primary"
icon="clear"
>
{{ $t('buttons.close') }}
</q-btn>
<q-btn
v-close-popup
flat
color="red"
icon="delete"
@click="showConfirmDeleteTimesetDialog"
>
{{ $t('buttons.remove') }}
</q-btn>
</div>
</q-date>
</q-menu>
<csc-confirm-dialog
ref="confirmDeleteTimesetDialog"
title-icon="delete"
@ -69,28 +88,28 @@
class="csc-cf-from-link"
>
{{ $t('pages.newCallForward.dateRangeShort') + groupTimeRange }}
<q-menu
ref="daterange"
@hide="resetAction()"
>
<csc-new-call-forward-date-range
ref="dateRangePopover"
class="q-pa-md"
:group-name="group.name"
:group-id="group.id"
:group-time-range="groupTimeRangeObj"
@confirm-delete="showConfirmDeleteTimesetDialog()"
@close="() => {this.$refs.daterange.hide()}"
/>
<csc-confirm-dialog
ref="confirmDeleteTimesetDialog"
title-icon="delete"
:title="$t('pages.newCallForward.cancelTimesetDialogTitle', {name: groupTimeRange})"
:message="$t('pages.newCallForward.cancelTimesetText', {name: groupTimeRange})"
@confirm="deleteTimeset"
/>
</q-menu>
</span>
<q-popover
ref="daterange"
class="csc-cf-calendar-day"
@open="showDateRange()"
>
<csc-new-call-forward-date-range
ref="dateRangePopover"
:group-name="group.name"
:group-id="group.id"
:group-time-range="groupTimeRangeObj"
@open-daterange-popover="rangeChanged()"
@confirm-delete="showConfirmDeleteTimesetDialog()"
/>
<csc-confirm-dialog
ref="confirmDeleteTimesetDialog"
title-icon="delete"
:title="$t('pages.newCallForward.cancelTimesetDialogTitle', {name: groupTimeRange})"
:message="$t('pages.newCallForward.cancelTimesetText', {name: groupTimeRange})"
@confirm="deleteTimeset"
/>
</q-popover>
</span>
<span
v-if="isWeekdays"
@ -102,20 +121,20 @@
>
{{ weekdaysLabelShort + groupWeekdays }}
</span>
<q-popover
<q-menu
ref="weekdayEditPanel"
class="csc-cf-number-form"
@open="showWeekdayEditForm()"
@show="showWeekdayEditForm()"
>
<csc-new-call-forward-add-weekday-form
:id="timeSet.id"
ref="weekdayEditForm"
class="q-pa-md"
:days="times"
:enabled="true"
:group-name="group.name"
:group-id="group.id"
/>
</q-popover>
</q-menu>
</span>
<span
v-if="isTempGroup || (!isTempGroup && !(groupSourceset && groupTimeset || groupSourceset && isWeekdays || groupTimeset && isWeekdays ))"
@ -125,97 +144,134 @@
<span class="csc-cf-from-link">
{{ $t('pages.newCallForward.conditionBtnLabel') }}
</span>
<q-popover
<q-menu
ref="conditions"
@open="showConditions()"
@close="showConditionForm()"
:auto-close="true"
@hide="showConditionForm()"
>
<csc-new-call-forward-condition-type-select
ref="addCondition"
:disable-sourceset-menu="isTempGroup || !groupSourceset"
:disable-timeset-menu="isTempGroup || !groupTimeset && !isRange && !isWeekdays"
:disable-date-range-menu="isTempGroup || !groupTimeset && !isRange && !isWeekdays"
:disable-weekdays-menu="isTempGroup || !groupTimeset && !isRange && !isWeekdays"
:enabled="true"
:group-name="group.name"
:group-id="group.id"
/>
</q-popover>
<q-list>
<q-item
v-if="isTempGroup || !groupSourceset"
ref="addFromConditionItem"
v-close-popup
clickable
@click="()=>{action = 'addFromCondition'}"
>
<q-item-section>{{ $t('pages.newCallForward.fromLabel') }}</q-item-section>
</q-item>
<q-item
v-if="isTempGroup || !groupTimeset && !isRange && !isWeekdays"
v-close-popup
clickable
@click="()=>{action = 'addDateIsCondition'}"
>
<q-item-section>{{ $t('pages.newCallForward.dateIsLabel') }}</q-item-section>
</q-item>
<q-item
v-if="isTempGroup || !groupTimeset && !isRange && !isWeekdays"
v-close-popup
clickable
@click="()=>{action = 'addDateRangeCondition'}"
>
<q-item-section>{{ $t('pages.newCallForward.dateRangeLabel') }}</q-item-section>
</q-item>
<q-item
v-if="isTempGroup || !groupTimeset && !isRange && !isWeekdays"
v-close-popup
clickable
@click="()=>{action = 'addWeekdayCondition'}"
>
<q-item-section>{{ $t('pages.newCallForward.weekdaysLabel') }}</q-item-section>
</q-item>
</q-list>
</q-menu>
<span>
<q-popover
<q-menu
ref="onlineSourceset"
class="csc-cf-number-form csc-cf-popover-left-align"
:class="{ 'csc-cf-popover-hide': toggleConditionFromForm}"
@open="showSourcesetForm()"
@close="resetToggleCondition(); resetAction()"
@show="showSourcesetForm()"
@hide="resetToggleCondition(); resetAction()"
>
<csc-new-call-forward-add-sourceset-form
ref="addSourceSet"
class="q-pa-md"
:enabled="true"
:group-name="group.name"
:group-id="group.id"
@close="()=>{this.$refs.onlineSourceset.hide()}"
/>
</q-popover>
</q-menu>
</span>
<span>
<q-popover
ref="day"
class="csc-cf-popover-left-align csc-cf-popover-top-valign"
:class="{ 'csc-cf-popover-hide': toggleIsDatePanel}"
@open="showQDate()"
@close="resetAction()"
<q-menu
ref="dayWidgetFromMenu"
@hide="resetAction()"
>
<q-datetime
ref="dayWidget"
<q-date
v-model="dayModel"
anchor="bottom right"
no-clear
:min="today"
/>
</q-popover>
:options="minDate"
:no-unset="true"
>
<div class="row items-center justify-end q-gutter-sm">
<q-btn
v-close-popup
flat
color="primary"
icon="clear"
>
{{ $t('buttons.close') }}
</q-btn>
<q-btn
v-close-popup
flat
color="red"
icon="delete"
@click="showConfirmDeleteTimesetDialog"
>
{{ $t('buttons.remove') }}
</q-btn>
</div>
</q-date>
</q-menu>
</span>
<span>
<q-popover
ref="daterange"
class="csc-cf-popover-left-align csc-cf-calendar-day"
:class="{ 'csc-cf-popover-hide': toggleIsRangePanel}"
@open="showDateRange()"
@close="resetAction()"
<q-menu
ref="daterangeFromMenu"
@hide="resetAction()"
>
<csc-new-call-forward-date-range
ref="dateRangePopover"
class="q-pa-md"
:group-name="group.name"
:group-id="group.id"
:no-clear="true"
@open-daterange-popover="rangeChanged()"
@close="() => {this.$refs.daterangeFromMenu.hide()}"
/>
</q-popover>
</q-menu>
</span>
<span>
<q-popover
<q-menu
ref="weekdayPanel"
class="csc-cf-number-form csc-cf-popover-left-align"
:class="{ 'csc-cf-popover-hide': toggleWeekdayPanel}"
@open="showWeekdayPanel()"
@close="resetWeekdayCondition(); resetAction()"
@show="showWeekdayPanel()"
@hide="resetWeekdayCondition(); resetAction()"
>
<csc-new-call-forward-add-weekday-form
ref="weekdayForm"
class="q-pa-md"
:enabled="true"
:group-name="group.name"
:group-id="group.id"
/>
</q-popover>
</q-menu>
</span>
</span>
</div>
<div class="col text-left col-xs-12 col-md-2 csc-cf-dest-number-cont">
<div class="text-left col-xs-2 col-md-2 csc-cf-dest-number-cont csc-cf-toggle-group">
<q-toggle
v-model="isEnabled"
@input="toggleGroupChange"
/>
</div>
<div class="col col-xs-12 col-md-5 csc-cf-group-actions">
<div class="col-xs-5 col-md-5 csc-cf-group-actions">
<q-icon
name="delete"
color="negative"
@ -231,7 +287,7 @@
/>
<q-spinner-dots
v-if="groupIsLoading"
class="csc-call-spinner"
class="q-ml-auto"
color="primary"
:size="24"
/>
@ -241,27 +297,27 @@
<div
v-if="isTimeoutOrUnconditional"
class="csc-cf-destination-cont row"
:class="{ 'csc-cf-destination-disabled': !isEnabled }"
>
<div
class="col col-xs-12 col-md-4 text-right"
:class="{ 'csc-cf-destination-disabled': !isEnabled }"
class="col-xs-4 col-md-4 text-right"
>
{{ toggleLabel }}
</div>
<div
class="col col-xs-12 col-md-2 text-left csc-cf-self-number-cont"
class="text-left col-xs-2 col-md-2 csc-cf-dest-number-cont"
>
{{ subscriberDisplayName }}
</div>
<div
class="col col-xs-12 col-md-6"
class="col-xs-6 col-md-6"
/>
</div>
<div
v-for="(destination, index) in group.destinations"
:key="index"
:key="destination.display_id"
>
<csc-new-call-forward-destination
ref="destination"
@ -276,47 +332,54 @@
<div
class="row csc-cf-destination-cont"
>
<div class="col col-xs-12 col-md-4 text-right" />
<div class="col-xs-4 col-md-4 text-right" />
<div
v-if="showAddDestBtn"
class="col col-xs-12 col-md-2 text-left"
class="col-xs-2 col-md-2 text-left"
:class="{ 'csc-cf-destination-disabled': !isEnabled }"
>
<div
class="csc-cf-destination-add-destination"
>
<q-icon
name="add"
<q-btn
flat
color="primary"
size="24px"
/>
{{ $t('pages.newCallForward.addDestinationLabel') }}
class=""
>
<q-icon
name="add"
color="primary"
size="24px"
/>
{{ $t('pages.newCallForward.addDestinationLabel') }}
<q-menu
ref="destTypeForm"
:auto-close="true"
@show="showDestTypeForm()"
@hide="showNext()"
>
<csc-new-call-forward-destination-type-form
ref="selectDestinationType"
/>
</q-menu>
</q-btn>
</div>
<q-popover
ref="destTypeForm"
class="csc-cf-group-popover-bottom"
@open="showDestTypeForm()"
@close="showNext()"
>
<csc-new-call-forward-destination-type-form
ref="selectDestinationType"
/>
</q-popover>
<q-popover
<q-menu
ref="numberForm"
class="csc-cf-number-form csc-cf-group-popover-bottom"
:no-parent-event="true"
:class="{ 'csc-cf-popover-hide': toggleNumberForm }"
@open="showNewDestNumber()"
@show="showNewDestNumber()"
>
<csc-new-call-forward-add-destination-form
ref="addDestinationForm"
class="q-pa-md"
:enabled="true"
:group-name="group.name"
:group-id="group.id"
/>
</q-popover>
</q-menu>
</div>
<div class="col col-xs-12 col-md-6 " />
<div class="col-xs-6 col-md-6 " />
</div>
</div>
</template>
@ -336,7 +399,6 @@ import CscNewCallForwardAddDestinationForm from './CscNewCallForwardAddDestinati
import CscNewCallForwardEditSources from './CscNewCallForwardEditSources'
import CscNewCallForwardAddSourcesetForm from './CscNewCallForwardAddSourcesetForm'
import CscNewCallForwardAddWeekdayForm from './CscNewCallForwardAddWeekdayForm'
import CscNewCallForwardConditionTypeSelect from './CscNewCallForwardConditionTypeSelect'
import CscNewCallForwardDestinationTypeForm from './CscNewCallForwardDestinationTypeForm'
import CscNewCallForwardDateRange from './CscNewCallForwardDateRange'
export default {
@ -348,7 +410,6 @@ export default {
CscNewCallForwardEditSources,
CscNewCallForwardAddSourcesetForm,
CscNewCallForwardAddWeekdayForm,
CscNewCallForwardConditionTypeSelect,
CscNewCallForwardDestinationTypeForm,
CscNewCallForwardDateRange
},
@ -380,7 +441,7 @@ export default {
action: null,
enabled: false,
day: null,
today: new Date()
today: new Date().toString()
}
},
computed: {
@ -393,9 +454,13 @@ export default {
'getGroupsLoaders',
'getSourcesets',
'getTimesets',
'getFirstDestinationInCreation'
'getFirstDestinationInCreation',
'getSelectedDestinationType'
]),
showAddDestBtn () {
if (this.isTempGroup) {
return false
}
for (const destination of this.group.destinations) {
const dest = _.get(destination, 'destination', '')
if (_.endsWith(dest, 'voicebox.local')) {
@ -449,12 +514,24 @@ export default {
return retVal
},
groupTimeRangeObj () {
let retVal = false, time
let retVal = false, time, fromYear, fromMonth, fromDay, fromHour, fromMinute, toYear, toMonth, toDay, toHour, toMinute, dateFrom, dateTo
if (this.timeSet && this.timeSet.times && this.timeSet.times.length > 0) {
time = this.timeSet.times[0]
fromYear = parseInt(time.year.split('-')[0])
fromMonth = parseInt(time.month.split('-')[0]) - 1
fromDay = parseInt(time.mday.split('-')[0])
fromHour = time.hour && time.hour.includes('-') ? parseInt(time.hour.split('-')[0]) : null
fromMinute = time.minute && time.minute.includes('-') ? parseInt(time.minute.split('-')[0]) : null
toYear = parseInt(time.year.split('-')[1])
toMonth = parseInt(time.month.split('-')[1]) - 1
toDay = parseInt(time.mday.split('-')[1])
toHour = time.hour && time.hour.includes('-') ? parseInt(time.hour.split('-')[1]) : null
toMinute = time.minute && time.minute.includes('-') ? parseInt(time.minute.split('-')[1]) : null
dateFrom = moment(new Date(fromYear, fromMonth, fromDay, fromHour, fromMinute), 0, 0)
dateTo = moment(new Date(toYear, toMonth, toDay, toHour, toMinute), 0, 0)
retVal = {
dateFrom: moment(new Date(parseInt(time.year.split('-')[0]), parseInt(time.month.split('-')[0]) - 1, parseInt(time.mday.split('-')[0]), parseInt(time.hour.split('-')[0]), parseInt(time.minute.split('-')[0]), 0, 0)).format(),
dateTo: moment(new Date(parseInt(time.year.split('-')[1]), parseInt(time.month.split('-')[1]) - 1, parseInt(time.mday.split('-')[1]), parseInt(time.hour.split('-')[1]), parseInt(time.minute.split('-')[1]), 0, 0)).format()
dateFrom: fromHour ? dateFrom.format() : dateFrom.format('YYYY-MM-DD'),
dateTo: toHour ? dateTo.format() : dateTo.format('YYYY-MM-DD')
}
}
return retVal
@ -474,7 +551,7 @@ export default {
},
groupWeekdays () {
let retVal = ''
let times = _.get(this.timeSet, 'times', [])
let times = _.cloneDeep(_.get(this.timeSet, 'times', []))
times = times.sort((a, b) => (parseInt(a.wday) > parseInt(b.wday)) ? 1 : ((parseInt(b.wday) > parseInt(a.wday)) ? -1 : 0))
times.forEach((time, index) => {
const separator = (index === times.length - 1) ? '' : ', '
@ -528,11 +605,11 @@ export default {
dayModel: {
get () {
if (!this.timeSet) {
return
return ''
}
const time = this.timeSet.times[0]
const dateN = new Date(parseInt(time.year), parseInt(time.month) - 1, parseInt(time.mday), 0, 0, 0, 0)
return dateN
return date.formatDate(dateN, 'YYYY/MM/DD')
},
set (value) {
if (value !== '') {
@ -556,7 +633,7 @@ export default {
},
getFirstDestinationInCreation: function () {
if (this.getFirstDestinationInCreation === this.group.id.toString() && this.$refs.conditions) {
this.$refs.conditions.open()
this.$refs.conditions.show()
}
}
},
@ -565,8 +642,10 @@ export default {
if (!this.firstDestinationInCreation) {
this.isEnabled = await this.$store.dispatch('newCallForward/isGroupEnabled', { groupName: this.group.name, id: this.group.id })
}
this.$store.dispatch('newCallForward/addGroupLoader', this.group.id)
await this.updateSourcesetNames()
await this.updateTimeSetNames()
this.$store.dispatch('newCallForward/removeGroupLoader', this.group.id)
} catch (err) {
console.log(err)
}
@ -580,10 +659,10 @@ export default {
this.$refs.addDestinationForm.add()
},
async showNext () {
switch (this.$refs.selectDestinationType.action) {
switch (this.getSelectedDestinationType) {
case 'destination':
this.toggleNumberForm = false
this.$refs.numberForm.open()
this.$refs.numberForm.show()
break
case 'voicemail':
this.$store.dispatch('newCallForward/addGroupLoader', this.group.id)
@ -602,30 +681,34 @@ export default {
firstDestinationCmp.movePopoverToTop()
}
firstDestinationCmp.$refs.destTypeForm.open()
firstDestinationCmp.$refs.destTypeForm.show()
},
setCondition (action) {
this.action = action
this.$refs.conditions.hide()
},
showConditionForm () {
if (this.isTempGroup) {
this.showFirstDestMenu()
return
}
const action = this.$refs.addCondition.action
const action = this.action
switch (action) {
case 'addFromCondition':
this.toggleConditionFromForm = false
this.$refs.onlineSourceset.open()
this.$refs.onlineSourceset.show()
break
case 'addDateIsCondition':
this.toggleIsDatePanel = false
this.$refs.day.open()
this.$refs.dayWidgetFromMenu.show()
break
case 'addDateRangeCondition':
this.toggleIsRangePanel = false
this.$refs.daterange.open()
this.$refs.daterangeFromMenu.show()
break
case 'addWeekdayCondition':
this.toggleWeekdayPanel = false
this.$refs.weekdayPanel.open()
this.$refs.weekdayPanel.show()
break
}
},
@ -658,7 +741,7 @@ export default {
this.$store.dispatch('newCallForward/removeGroupLoader', this.group.id)
},
openConditionsPopover () {
this.$refs.conditions.open()
this.$refs.conditions.show()
},
showConditions () {
this.$refs.addCondition.add()
@ -676,7 +759,7 @@ export default {
this.toggleConditionFromForm = true
},
resetAction () {
this.$refs.addCondition.action = null
this.action = null
},
resetWeekdayCondition () {
this.toggleWeekdayPanel = true
@ -731,16 +814,6 @@ export default {
console.log(e)
}
},
showQDateContainer () {
this.toggleIsDatePanel = false
this.$refs.day.open()
},
showQDate () {
this.$refs.dayWidget.open()
},
showDateRange () {
this.$refs.dateRangePopover.add()
},
showConfirmDeleteTimesetDialog () {
this.$refs.confirmDeleteTimesetDialog.open()
},
@ -775,7 +848,7 @@ export default {
})
if (!this.timeSet) {
this.$store.dispatch('newCallForward/addTimesetToGroup', {
await this.$store.dispatch('newCallForward/addTimesetToGroup', {
name: this.group.name,
groupId: this.group.id,
timeSetId: timseSetId
@ -788,7 +861,10 @@ export default {
}
},
rangeChanged () {
this.$refs.daterange.open()
this.$refs.daterange.show()
},
minDate (day) {
return day >= date.formatDate(new Date(), 'YYYY/MM/DD')
}
}
}
@ -797,8 +873,12 @@ export default {
<style lang="stylus" rel="stylesheet/stylus">
.csc-cf-group
width 100%
.csc-cf-toggle-group
height 25px !important
.csc-cf-destination-cont
width 100%
margin-bottom 4px
.csc-cf-group-title-bold
text-align right
font-weight bold
.csc-cf-group-cont
position relative
@ -807,21 +887,14 @@ export default {
.csc-cf-destination-value
text-align center
.csc-cf-destination-add-condition
font-size 16px
font-size 14px
.csc-cf-destination-add-destination
padding-left 25px
width 250px
white-space nowrap
overflow hidden
text-overflow ellipsis
color $primary
cursor pointer
.csc-cf-group-popover-bottom
margin-left 30px
.csc-cf-popover-left-align
margin-left -120px
.csc-cf-popover-top-valign
margin-top -40px
.csc-cf-from-link
color $primary
cursor pointer

@ -3,15 +3,14 @@
v-if="enabled"
class="csc-form"
>
<csc-new-call-forward-input
<csc-input
v-model="number"
:label="$t('callBlocking.number')"
:prefilled="destination"
@submit="save"
@error="error"
/>
<div
class="csc-form-actions row justify-center csc-actions-cont"
class="row justify-center csc-actions-cont"
>
<q-btn
flat
@ -42,7 +41,7 @@
</template>
<script>
import CscNewCallForwardInput from './CscNewCallForwardInput'
import CscInput from '../../form/CscInput'
import CscSpinner from '../../CscSpinner'
import {
showGlobalError
@ -54,12 +53,12 @@ import {
export default {
name: 'CscNewCallForwardAddDestinationForm',
components: {
CscNewCallForwardInput,
CscInput,
CscSpinner
},
props: {
destination: {
type: Object,
type: String,
default: null
},
index: {
@ -79,7 +78,7 @@ export default {
default: ''
},
groupId: {
type: String,
type: [String, Number],
default: null
},
firstDestinationInCreation: {
@ -105,6 +104,9 @@ export default {
return this.numberError || this.disable || this.loading
}
},
mounted () {
this.number = this.destination
},
updated () {
if (Number.isInteger(this.index)) {
this.destinationIndex = this.index
@ -126,14 +128,11 @@ export default {
})
} else {
if (forwardGroup.id.toString().includes('temp-')) { // unexisting group
forwardGroup.destinations[0].simple_destination = this.number // optimistic UI update :)
const newGroupId = await this.$store.dispatch('newCallForward/addForwardGroup', {
name: forwardGroupName,
destination: this.number
})
await this.$store.dispatch('newCallForward/loadForwardGroups')
if (this.destinationIndex === 0 && this.firstDestinationInCreation) {
await this.$store.dispatch('newCallForward/setFirstDestinationInCreation', newGroupId)
}
@ -148,17 +147,13 @@ export default {
this.$store.dispatch('newCallForward/removeGroupLoader', this.groupId)
},
cancel () {
this.number = ''
this.enabled = false
this.$parent.close()
},
add () {
this.number = ''
this.enabled = true
},
close () {
this.enabled = false
this.$parent.close()
},
reset () {
this.cancel()
@ -171,6 +166,4 @@ export default {
</script>
<style lang="stylus" rel="stylesheet/stylus">
.csc-actions-cont
margin-bottom 15px
</style>

@ -3,14 +3,14 @@
v-if="enabled"
class="csc-form"
>
<csc-new-call-forward-input-text
<csc-input
v-model="name"
:label="$t('pages.newCallForward.sourcesetName')"
@submit="save"
@error="errorName"
/>
<csc-new-call-forward-input
<csc-call-input
v-model="number"
:label="$t('callBlocking.number')"
@submit="save"
@ -18,7 +18,7 @@
/>
<div
class="csc-form-actions row justify-center csc-actions-cont"
class="row justify-center csc-actions-cont"
>
<q-btn
flat
@ -49,8 +49,8 @@
</template>
<script>
import CscNewCallForwardInput from './CscNewCallForwardInput'
import CscNewCallForwardInputText from './CscNewCallForwardInputText'
import CscCallInput from '../../form/CscCallInput'
import CscInput from '../../form/CscInput'
import CscSpinner from '../../CscSpinner'
import {
showGlobalError
@ -62,8 +62,8 @@ import {
export default {
name: 'CscNewCallForwardAddSourcesetForm',
components: {
CscNewCallForwardInput,
CscNewCallForwardInputText,
CscCallInput,
CscInput,
CscSpinner
},
props: {
@ -72,7 +72,7 @@ export default {
default: ''
},
groupId: {
type: String,
type: [String, Number],
default: null
}
},
@ -112,7 +112,7 @@ export default {
return
}
try {
this.close()
this.$emit('close')
this.$store.dispatch('newCallForward/addGroupLoader', forwardGroupId)
sourceSetId = await this.$store.dispatch('newCallForward/createSourceSet', {
name: this.name,
@ -133,7 +133,7 @@ export default {
this.number = ''
this.name = ''
this.enabled = false
this.$parent.close()
this.$emit('close')
},
add () {
this.number = ''
@ -142,7 +142,7 @@ export default {
},
close () {
this.enabled = false
this.$parent.close()
this.$emit('close')
},
reset () {
this.cancel()
@ -158,6 +158,4 @@ export default {
</script>
<style lang="stylus" rel="stylesheet/stylus">
.csc-actions-cont
margin-bottom 15px
</style>

@ -16,7 +16,7 @@
/>
</div>
<div
class="csc-form-actions row justify-center csc-actions-cont"
class="row justify-center csc-actions-cont"
>
<q-btn
class="day-btn"
@ -76,7 +76,7 @@
</q-btn>
</div>
<div
class="csc-form-actions row justify-center csc-actions-cont"
class="row justify-center csc-actions-cont"
>
<q-btn
:disabled="weekdays.length < 1"
@ -130,7 +130,7 @@ export default {
default: ''
},
groupId: {
type: String,
type: [String, Number],
default: null
},
id: {
@ -180,7 +180,7 @@ export default {
this.timeSetId = await this.$store.dispatch('newCallForward/createTimeSet', this.timesetName)
}
this.$store.dispatch('newCallForward/addTimesetToGroup', {
await this.$store.dispatch('newCallForward/addTimesetToGroup', {
name: this.groupName,
groupId: this.groupId,
timeSetId: this.timeSetId
@ -208,7 +208,7 @@ export default {
this.close()
},
close () {
this.$parent.close()
this.$emit('close')
this.enabled = false
},
add () {
@ -237,14 +237,12 @@ export default {
</script>
<style lang="stylus" rel="stylesheet/stylus">
.csc-actions-cont
margin-bottom 15px
.day-btn
margin 5px
background rgba(37,51,85,0.8)
width 35px
.day-selected-btn
background $primary
.day-btn
margin 5px
background rgba(37,51,85,0.8)
width 35px
.day-selected-btn
background $primary
.csc-cf-delete-weekdays-btn
float right
margin-top -10px

@ -1,133 +0,0 @@
<template>
<div
v-if="enabled"
>
<div
v-if="disableSourcesetMenu"
class="csc-cf-dest-type"
@click="addFromCondition()"
>
{{ $t('pages.newCallForward.fromLabel') }}
</div>
<div
v-if="disableTimesetMenu"
class="csc-cf-dest-type"
@click="addDateIsCondition()"
>
{{ $t('pages.newCallForward.dateIsLabel') }}
</div>
<div
v-if="disableDateRangeMenu"
ref="daterangeItem"
class="csc-cf-dest-type"
@click="addDateRangeCondition()"
>
{{ $t('pages.newCallForward.dateRangeLabel') }}
</div>
<div
v-if="disableWeekdaysMenu"
class="csc-cf-dest-type"
@click="addWeekdayCondition()"
>
{{ $t('pages.newCallForward.weekdaysLabel') }}
</div>
</div>
</template>
<script>
export default {
name: 'CscNewCallForwardConditionTypeSelect',
props: {
groupId: {
type: String,
default: null
},
groupName: {
type: String,
default: ''
},
disableSourcesetMenu: {
type: Boolean,
default: false
},
disableTimesetMenu: {
type: Boolean,
default: false
},
disableDateRangeMenu: {
type: Boolean,
default: false
},
disableWeekdaysMenu: {
type: Boolean,
default: false
}
},
data () {
return {
enabled: true,
action: null,
timesetName: null
}
},
computed: {
allFieldsFilled () {
return this.rangeDateModel.from !== null &&
this.rangeDateModel.to !== null &&
this.rangeTimeModel.from !== null &&
this.rangeTimeModel.to !== null
}
},
mounted () {
this.timesetName = 'timeset-' + this.groupId
},
methods: {
addFromCondition () {
this.action = 'addFromCondition'
this.$parent.close()
},
addDateIsCondition () {
this.action = 'addDateIsCondition'
this.$parent.close()
},
addDateRangeCondition () {
this.action = 'addDateRangeCondition'
this.$parent.close()
},
addWeekdayCondition () {
this.action = 'addWeekdayCondition'
this.$parent.close()
},
cancel () {
this.action = null
this.enabled = false
this.$parent.close()
},
add () {
this.enabled = true
},
close () {
this.action = null
this.enabled = false
this.$parent.close()
},
showQDate () {
this.$refs.dayWidget.open()
}
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
.csc-cf-dest-type
min-width 100px
padding 10px
cursor pointer
.csc-cf-dest-type:hover
background $main-menu-item-hover-background
.csc-cf-calendar-day
padding 20px
min-width 400px
.q-datetime-weekdays
color $tertiary
</style>

@ -1,120 +1,161 @@
<template>
<div
v-if="enabled"
class="csc-form"
>
<div
class="csc-cf-daterange-popovers-container"
>
<q-datetime
ref="dayFrom"
v-model="dayFrom"
<q-popup-proxy
ref="dayFromProxy"
class="csc-cf-datetime"
type="date"
format="DD/MM/YYYY"
:min="today"
@blur="openParent()"
/>
<q-datetime
ref="dayTo"
v-model="dayTo"
>
<q-date
ref="dayFrom"
v-model="dayFrom"
mask="YYYY/MM/DD"
:options="minDateFrom"
:no-unset="true"
>
<div class="row items-center justify-end q-gutter-sm">
<q-btn
v-close-popup
flat
color="primary"
icon="done"
>
{{ $t('buttons.confirm') }}
</q-btn>
</div>
</q-date>
</q-popup-proxy>
<q-popup-proxy
ref="dayToProxy"
class="csc-cf-datetime"
type="date"
format="DD/MM/YYYY"
:min="dayFrom"
@blur="openParent()"
/>
<q-datetime
ref="hourFrom"
v-model="hourFrom"
>
<q-date
ref="dayTo"
v-model="dayTo"
mask="YYYY/MM/DD"
:options="minDateTo"
:no-unset="true"
>
<div class="row items-center justify-end q-gutter-sm">
<q-btn
v-close-popup
flat
color="primary"
icon="done"
>
{{ $t('buttons.confirm') }}
</q-btn>
</div>
</q-date>
</q-popup-proxy>
<q-popup-proxy
ref="hourFromProxy"
class="csc-cf-datetime"
type="time"
format="HH:MM"
@blur="openParent()"
/>
<q-datetime
ref="hourTo"
v-model="hourTo"
>
<q-time
ref="hourFrom"
v-model="hourFrom"
:no-unset="true"
>
<div class="row items-center justify-end q-gutter-sm">
<q-btn
v-close-popup
flat
color="primary"
icon="done"
>
{{ $t('buttons.confirm') }}
</q-btn>
</div>
</q-time>
</q-popup-proxy>
<q-popup-proxy
ref="hourToProxy"
class="csc-cf-datetime"
type="time"
format="HH:MM"
:min="hourFrom"
@blur="openParent()"
/>
</div>
<div
class="csc-cf-daterange-fields-cont csc-form-actions row justify-center csc-actions-cont"
>
<q-field
dark
label="Date range"
:label-width="11"
class="csc-cf-popover-daterange-title"
/>
>
<q-time
ref="hourTo"
v-model="hourTo"
:no-unset="true"
>
<div class="row items-center justify-end q-gutter-sm">
<q-btn
v-close-popup
flat
color="primary"
icon="done"
>
{{ $t('buttons.confirm') }}
</q-btn>
</div>
</q-time>
</q-popup-proxy>
</div>
<div
class="csc-cf-daterange-fields-cont csc-form-actions row justify-center csc-actions-cont"
class="csc-actions-cont row justify-center"
>
<q-input
v-model="dayFromFormatted"
dark
:placeholder="$t('pages.newCallForward.dateRangeStartDate')"
:after="[
{
icon: 'today',
handler () {
openDayFrom();
}
}
]"
@click="openDayFrom()"
/>
>
<template v-slot:append>
<q-icon
name="today"
@click="openDayFrom()"
/>
</template>
</q-input>
<q-input
v-model="dayToFormatted"
:disable="!dayFrom"
dark
:placeholder="$t('pages.newCallForward.dateRangeEndDate')"
:after="[
{
icon: 'today',
handler () {
openDayTo();
}
}
]"
@click="openDayTo()"
/>
>
<template v-slot:append>
<q-icon
name="today"
@click="openDayTo()"
/>
</template>
</q-input>
</div>
<div
class="csc-form-actions row justify-center csc-actions-cont"
class="csc-actions-cont row justify-center"
>
<q-input
v-model="hourFromFormatted"
dark
:disable="!dayFrom"
:placeholder="$t('pages.newCallForward.dateRangeStartTime')"
:after="[
{
icon: 'access_time',
handler () {
openHourFrom();
}
}
]"
@click="openHourFrom()"
/>
>
<template v-slot:append>
<q-icon
name="access_time"
@click="openHourFrom()"
/>
</template>
</q-input>
<q-input
v-model="hourToFormatted"
dark
:placeholder="$t('pages.newCallForward.dateRangeEndTime')"
:after="[
{
icon: 'access_time',
handler () {
openHourTo();
}
}
]"
:disable="!dayTo"
@click="openHourTo()"
/>
>
<template v-slot:append>
<q-icon
name="access_time"
@click="openHourTo()"
/>
</template>
</q-input>
</div>
<div
class="csc-cf-daterange-btn-cont"
@ -139,7 +180,7 @@
flat
color="default"
icon="clear"
@click="cancelTimerange(); resetTimeRange()"
@click="resetTimeRange(); close()"
>
{{ $t('buttons.cancel') }}
</q-btn>
@ -147,7 +188,7 @@
flat
color="primary"
icon="done"
:disable="!allFieldsFilled"
:disable="!isDateReadyForSubmit"
@click="save();"
>
{{ $t('buttons.save') }}
@ -172,7 +213,7 @@ export default {
default: ''
},
groupId: {
type: String,
type: [String, Number],
default: null
},
groupTimeRange: {
@ -190,14 +231,13 @@ export default {
},
data () {
return {
enabled: false,
timesetId: null,
timesetName: null,
dayFrom: null,
dayTo: null,
hourFrom: null,
hourTo: null,
today: new Date(),
dayFrom: '',
dayTo: '',
hourFrom: '',
hourTo: '',
dayRegExp: /^([0-2][0-9]|(3)[0-1])(\/)(((0)[0-9])|((1)[0-2]))(\/)\d{4}$/i,
timeRegExp: /^(0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]$/
}
@ -219,6 +259,9 @@ export default {
},
hourFromFormatted () {
let time = this.hourFrom ? this.hourFrom : ''
if (!time.toString().includes(':')) {
return ''
}
if (time.toString().length > 0 && !time.match(this.timeRegExp)) {
time = date.formatDate(time, 'hh:mm')
}
@ -226,67 +269,60 @@ export default {
},
hourToFormatted () {
let time = this.hourTo ? this.hourTo : ''
if (!time.toString().includes(':')) {
return ''
}
if (time.toString().length > 0 && !time.match(this.timeRegExp)) {
time = date.formatDate(time, 'hh:mm')
}
return time
},
allFieldsFilled () {
return this.dayFrom !== null &&
this.dayTo !== null &&
this.hourFrom !== null &&
this.hourTo !== null
isDateReadyForSubmit () {
if (this.dayFrom !== '' && this.dayTo !== '') {
const ret = (this.hourFrom !== '' && this.hourTo !== '') || (this.hourFrom === '' && this.hourTo === '')
return ret
}
return false
}
},
mounted () {
this.setDaysAndTimes()
},
methods: {
openParent () {
this.$emit('open-daterange-popover')
},
openDayFrom () {
this.$refs.dayFrom.open()
const splitDate = this.dayFromFormatted.split('/')
this.dayFrom = [splitDate[2], splitDate[1], splitDate[0]].join('/')
this.$refs.dayFromProxy.show()
},
openDayTo () {
this.$refs.dayTo.open()
const splitDate = this.dayToFormatted.split('/')
this.dayTo = [splitDate[2], splitDate[1], splitDate[0]].join('/')
this.$refs.dayToProxy.show()
},
openHourFrom () {
this.$refs.hourFrom.open()
this.hourFrom = this.hourFromFormatted
this.$refs.hourFromProxy.show()
},
openHourTo () {
this.$refs.hourTo.open()
},
cancel () {
this.close()
},
close () {
this.$parent.close()
this.enabled = false
},
add () {
this.enabled = true
},
showRemoveDialog () {
this.hourTo = this.hourToFormatted
this.$refs.hourToProxy.show()
},
formatRange (startDate, endDate, startTime, endTime) {
const startDateOnly = startDate.toString().split('T')[0]
const endDateOnly = endDate.toString().split('T')[0]
const startTimeOnly = startTime.toString().split('T')[1]
const endTimeOnly = endTime.toString().split('T')[1]
const getDateObj = date => (([year, month, day]) => ({ day, year, month }))(date.split('-'))
startTime = startTime.includes('T') ? date.formatDate(startTime, 'hh:mm') : startTime
endTime = endTime.includes('T') ? date.formatDate(endTime, 'hh:mm') : endTime
const getDateObj = date => (([year, month, day]) => ({ day, year, month }))(date.includes('T') ? date.split('T')[0].split('-') : date.includes('/') ? date.split('/') : date.split('-'))
const getTimeObj = time => (([hour, minute, second]) => ({ hour, minute, second }))(time.split(':'))
const startDateObj = getDateObj(startDateOnly)
const endDateObj = getDateObj(endDateOnly)
const startTimeObj = getTimeObj(startTimeOnly)
const endTimeObj = getTimeObj(endTimeOnly)
const startDateObj = getDateObj(startDate)
const endDateObj = getDateObj(endDate)
const startTimeObj = getTimeObj(startTime)
const endTimeObj = getTimeObj(endTime)
return [
{
year: startDateObj.year + '-' + endDateObj.year,
month: startDateObj.month + '-' + endDateObj.month,
mday: startDateObj.day + '-' + endDateObj.day,
hour: startTimeObj.hour + '-' + endTimeObj.hour,
minute: startTimeObj.minute + '-' + endTimeObj.minute
hour: startTimeObj.hour && endTimeObj.hour ? startTimeObj.hour + '-' + endTimeObj.hour : null,
minute: startTimeObj.minute && endTimeObj.minute ? startTimeObj.minute + '-' + endTimeObj.minute : null
}
]
},
@ -298,7 +334,7 @@ export default {
}
const timeSetId = await this.$store.dispatch('newCallForward/createTimeSet', this.timesetName)
this.$store.dispatch('newCallForward/addTimesetToGroup', {
await this.$store.dispatch('newCallForward/addTimesetToGroup', {
name: this.groupName,
groupId: this.groupId,
timeSetId: timeSetId
@ -309,7 +345,7 @@ export default {
})
this.$store.dispatch('newCallForward/setTimeset', updatedTimeset)
this.$store.dispatch('newCallForward/removeGroupLoader', this.groupId)
this.cancelTimerange()
this.close()
},
async deleteTimeset () {
try {
@ -322,79 +358,58 @@ export default {
}
},
resetTimeRange () {
this.dayFrom = null
this.dayTo = null
this.hourFrom = null
this.hourTo = null
},
cancelTimerange () {
this.$parent.close()
this.action = null
this.enabled = false
this.dayFrom = ''
this.dayTo = ''
this.hourFrom = ''
this.hourTo = ''
},
setDaysAndTimes () {
if (this.groupTimeRange) {
this.dayFrom = this.groupTimeRange.dateFrom
this.dayTo = this.groupTimeRange.dateTo
this.hourFrom = this.groupTimeRange.dateFrom
this.hourTo = this.groupTimeRange.dateTo
this.hourFrom = this.groupTimeRange.dateFrom.includes('T') ? this.groupTimeRange.dateFrom : ''
this.hourTo = this.groupTimeRange.dateTo.includes('T') ? this.groupTimeRange.dateTo : ''
} else {
this.resetTimeRange()
}
},
showRemoveDateRangeDialog () {
this.$parent.close()
this.$emit('confirm-delete')
},
minDateFrom (day) {
return day >= date.formatDate(new Date(), 'YYYY/MM/DD')
},
minDateTo (day) {
return date.getDateDiff(day, this.dayFrom) > 0
},
close () {
this.$emit('close')
}
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
.csc-cf-popover-daterange-title
text-align center
width 100%
margin-left 40px
margin-top 50px
margin-bottom -60px
.q-field-label-inner
color $white
margin-top -25px
margin-bottom 10px
font-weight bold
span
width 100%
text-align center
.csc-actions-cont
margin-bottom 15px
.q-input
margin-left 10px
margin-right 20px
max-width 160px
.csc-cf-daterange-fields-cont
margin-top 73px !important
.csc-cf-daterange-popovers-container
width 100%
height 1px !important
margin-top -70px !important
margin-bottom -30px !important
position relative
.csc-cf-datetime
position absolute
top 0
left 0
.csc-cf-daterange-btn-cont
width 100%
text-align center
.q-datetime-days div:not(.q-datetime-day-active),
.q-datetime-dark,
.q-datetime-range .q-datetime-input .q-input-target,
.q-datetime-range .q-icon,
.q-datetime-range .q-if:before,
.q-item-icon
color $white !important
.q-datetime-range.row .q-datetime-range-right,
.q-datetime-range.row .q-datetime-range-left
padding-left 20px
.csc-cf-daterange-btn-cont
margin-top 10px
width 100%
text-align center
.q-menu
min-width auto !important
.q-datetime-days div:not(.q-datetime-day-active),
.q-datetime-dark,
.q-datetime-range .q-datetime-input .q-input-target,
.q-datetime-range .q-icon,
.q-datetime-range .q-if:before,
.q-item-icon
color $white !important
.q-datetime-range.row .q-datetime-range-right,
.q-datetime-range.row .q-datetime-range-left
padding-left 20px
.csc-actions-cont
.q-input
margin-left 10px
margin-right 20px
max-width 160px
</style>

@ -3,46 +3,54 @@
class="row csc-cf-destination-cont"
:class="{ 'csc-cf-removed-destination': removeInProgress }"
>
<div class="col col-xs-12 col-md-4 text-right">
<div class="col-xs-4 col-md-4 text-right">
{{ labelTimeout }}
<span
v-if="!allCallsFwd"
class="csc-cf-timeout csc-cf-destination-link"
>
{{ destinationTimeout }}
<q-popover
<q-menu
ref="timeoutForm"
self="top left"
class="csc-cf-timeout-form"
@close="saveTimeout()"
class="csc-cf-timeout-menu"
@hide="saveTimeout()"
>
<q-slider
v-model="destinationTimeout"
label
label-always
:step="5"
:min="5"
:max="60"
markers
snap
/>
</q-popover>
<q-item
class="csc-cf-timeout-item"
>
<q-slider
ref="timeout"
v-model="destinationTimeout"
label
label-always
:step="5"
:min="5"
:max="60"
label-text-color="secondary"
markers
snap
/>
</q-item>
</q-menu>
</span>
{{ labelFront }}
</div>
<div class="col text-left col-xs-12 col-md-2 csc-cf-dest-number-cont">
<div class="text-left col-xs-2 col-md-2 csc-cf-dest-number-cont">
<div
:class="{ 'csc-cf-destination-link': !isVoiceMail() }"
class="csc-cf-destination"
@click="toggleDestMenu()"
>
{{ labelNumber }}
<q-popover
<q-menu
v-if="!isVoiceMail()"
ref="destTypeForm"
class="csc-cf-dest-popover-bottom"
:class="{ 'csc-cf-popover-hide': disableDestType, 'csc-cf-popover-to-top': popoverToTop, 'csc-cf-popover-timeout-to-top': popoverTimeoutToTop }"
@open="showDestTypeForm()"
@close="showNext()"
:auto-close="true"
:no-parent-event="true"
@show="showDestTypeForm()"
@hide="showNext()"
>
<div
v-if="firstDestinationInCreation && (popoverToTop || popoverTimeoutToTop)"
@ -53,27 +61,29 @@
<csc-new-call-forward-destination-type-form
ref="selectDestinationType"
/>
</q-popover>
<q-popover
</q-menu>
<q-menu
v-if="!isVoiceMail()"
ref="numberForm"
class="csc-cf-number-form csc-cf-dest-popover-bottom"
:no-parent-event="true"
class="csc-cf-dest-popover-bottom"
:class="{ 'csc-cf-popover-hide': disableNumberPopover, 'csc-cf-popover-to-top': popoverToTop, 'csc-cf-popover-timeout-to-top': popoverTimeoutToTop }"
@open="showNumberForm()"
@close="movePopoverToInitialPos(); movePopoverTimeoutToInitialPos()"
@show="showNumberForm()"
@hide="movePopoverToInitialPos(); movePopoverTimeoutToInitialPos()"
>
<csc-new-call-forward-add-destination-form
ref="addDestinationForm"
class="q-pa-md"
:index="destinationIndex"
:destination="destinationNumber"
:group-name="groupName"
:group-id="groupId"
:first-destination-in-creation="firstDestinationInCreation"
/>
</q-popover>
</q-menu>
</div>
</div>
<div class="col col-xs-12 col-md-5 csc-cf-destination-actions">
<div class="col col-xs-5 col-md-5 csc-cf-destination-actions">
<q-icon
name="delete"
color="negative"
@ -111,7 +121,7 @@ export default {
default: false
},
groupId: {
type: String,
type: [String, Number],
default: null
},
groupName: {
@ -141,6 +151,7 @@ export default {
},
computed: {
...mapGetters('newCallForward', [
'getSelectedDestinationType',
'getOwnPhoneTimeout'
]),
disableDestType () {
@ -187,10 +198,10 @@ export default {
this.destinationIndex = this.index
},
async showNext () {
switch (this.$refs.selectDestinationType.action) {
switch (this.getSelectedDestinationType) {
case 'destination':
this.toggleNumberForm = false
this.$refs.numberForm.open()
this.$refs.numberForm.show()
break
case 'voicemail':
this.$store.dispatch('newCallForward/addGroupLoader', this.groupId)
@ -218,6 +229,16 @@ export default {
this.popoverTimeoutToTop = false
}
},
toggleDestMenu () {
if (this.destinationNumber === 'Voicemail') {
return
}
if (this.destinationNumber && this.destinationNumber !== ' ') {
this.$refs.numberForm.show()
} else {
this.$refs.destTypeForm.show()
}
},
showNumberForm () {
this.$refs.addDestinationForm.add()
},
@ -282,9 +303,6 @@ export default {
</script>
<style lang="stylus" rel="stylesheet/stylus">
.csc-cf-destination-cont
width 100%
padding 5px
.csc-cf-timeout,
.csc-cf-destination
width 100px
@ -295,13 +313,15 @@ export default {
.csc-cf-destination-link
color $primary
cursor pointer
.csc-cf-timeout-form
.csc-cf-timeout-menu
height 40px
.csc-cf-timeout-item
min-width 200px
padding 0 20px 20px 20px
.csc-cf-number-form
padding 0 20px 0 20px
padding 30px 20px 20px 20px
.csc-cf-dest-number-cont
padding-left 30px
.q-toggle__inner
top -8px
.csc-cf-destination-actions
text-align left
cursor pointer

@ -4,13 +4,13 @@
>
<div
class="csc-cf-dest-type"
@click="showNumberForm()"
@click="setSelectedDestinationType('destination')"
>
{{ $t('pages.newCallForward.numberLabel') }}
</div>
<div
class="csc-cf-dest-type"
@click="addVoiceMail()"
@click="setSelectedDestinationType('voicemail')"
>
{{ $t('pages.newCallForward.voiceMailLabel') }}
</div>
@ -18,23 +18,23 @@
</template>
<script>
import {
mapActions
} from 'vuex'
export default {
name: 'CscNewCallForwardDestinationTypeForm',
data () {
return {
enabled: false,
action: null
enabled: false
}
},
mounted () {
this.setSelectedDestinationType(null)
},
methods: {
showNumberForm () {
this.action = 'destination'
this.$parent.close()
},
addVoiceMail () {
this.action = 'voicemail'
this.$parent.close()
},
...mapActions('newCallForward', [
'setSelectedDestinationType'
]),
cancel () {
this.enabled = false
},

@ -47,19 +47,15 @@ export default {
methods: {
async addDestinationsetUnconditional () {
await this.$store.dispatch('newCallForward/setSelectedDestType', 'unconditional')
this.$parent.close()
},
async addDestinationsetUnconditionalFrom () {
await this.$store.dispatch('newCallForward/setSelectedDestType', 'unconditional-from')
this.$parent.close()
},
async addDestinationsetOffline () {
await this.$store.dispatch('newCallForward/setSelectedDestType', 'offline')
this.$parent.close()
},
async addDestinationsetBusy () {
await this.$store.dispatch('newCallForward/setSelectedDestType', 'busy')
this.$parent.close()
},
cancel () {

@ -1,7 +1,7 @@
<template>
<div
v-if="enabled"
class="csc-form"
class="csc-form q-pa-lg"
:class="{ 'csc-cf-popover-hide': toggleFormVisibility}"
>
<div class="col text-left col-xs-12 col-md-12 ">
@ -40,7 +40,7 @@
<div
class="csc-cf-row row"
>
<csc-new-call-forward-input
<csc-input
ref="sourceInputField"
v-model="number"
:label="$t('callBlocking.number')"
@ -59,7 +59,7 @@
</div>
<div
class="csc-form-actions row justify-center csc-actions-cont"
class="row justify-center csc-actions-cont"
>
<q-btn
flat
@ -91,7 +91,7 @@
import {
mapGetters
} from 'vuex'
import CscNewCallForwardInput from './CscNewCallForwardInput'
import CscInput from '../../form/CscInput'
import CscNewCallForwardSource from './CscNewCallForwardSource'
import CscConfirmDialog from '../../CscConfirmationDialog'
import CscSpinner from '../../CscSpinner'
@ -105,7 +105,7 @@ import {
export default {
name: 'CscNewCallForwardEditSources',
components: {
CscNewCallForwardInput,
CscInput,
CscNewCallForwardSource,
CscConfirmDialog,
CscSpinner
@ -116,7 +116,7 @@ export default {
default: ''
},
groupId: {
type: String,
type: [String, Number],
default: ''
},
sourceSetName: {
@ -124,7 +124,7 @@ export default {
default: ''
},
sourceSetId: {
type: String,
type: [String, Number],
default: ''
}
},
@ -170,21 +170,18 @@ export default {
},
methods: {
async save () {
const sources = this.sources
if (this.numberError || this.saveDisabled) {
showGlobalError(this.$t('validationErrors.generic'))
}
sources.push({
source: this.number
})
try {
this.$store.dispatch('newCallForward/addGroupLoader', this.groupId)
this.$refs.sourceInputField.reset()
await this.$store.dispatch('newCallForward/addSourceToSourceset', {
id: this.sourceSetId,
sources: sources
sources: [...this.sources, {
source: this.number
}]
})
this.$refs.sourceInputField.clear()
await this.$store.dispatch('newCallForward/loadSourcesets')
} catch (err) {
console.log(err)
@ -210,7 +207,7 @@ export default {
cancel () {
this.number = ''
this.enabled = false
this.$parent.close()
this.$emit('close')
},
add () {
this.number = ''
@ -218,7 +215,7 @@ export default {
},
close () {
this.enabled = false
this.$parent.close()
this.$emit('close')
},
reset () {
this.cancel()
@ -242,6 +239,4 @@ export default {
.csc-cf-btn-reduced-size
.on-left
margin-right 0px
.csc-actions-cont
margin-bottom 15px
</style>

@ -1,119 +0,0 @@
<template>
<q-field
:error-label="errorMessage"
>
<q-input
ref="inputField"
v-model="inputValue"
dark
clearable
type="text"
:float-label="label"
:error="$v.inputValue.$error"
:before="beforeButtons"
@keyup.enter="submit"
@keypress.space.prevent
@keydown.space.prevent
@keyup.space.prevent
@input="input"
@blur="blur"
/>
</q-field>
</template>
<script>
import {
userInfoAndEmpty
} from 'src/helpers/validation'
import {
maxLength,
required
} from 'vuelidate/lib/validators'
export default {
name: 'CscNewCallForwardInput',
props: {
label: {
type: String,
default: ''
},
prefilled: {
type: String,
default: ''
},
before: {
type: Array,
default () {
return []
}
}
},
data () {
return {
inputValue: '',
error: ''
}
},
validations: {
inputValue: {
userInfoAndEmpty,
maxLength: maxLength(64),
required
}
},
computed: {
errorMessage () {
if (!this.$v.inputValue.required) {
return this.$t('validationErrors.fieldRequired', {
field: this.label
})
} else if (!this.$v.inputValue.maxLength) {
return this.$t('validationErrors.maxLength', {
field: this.label,
maxLength: this.$v.inputValue.$params.maxLength.max
})
} else if (!this.$v.inputValue.userInfoAndEmpty) {
return this.$t('validationErrors.inputValidNumber')
} else {
return ''
}
},
beforeButtons () {
return this.before ? this.before : []
}
},
watch: {
error (state) {
this.$emit('error', state)
}
},
mounted () {
if (this.prefilled) {
this.inputValue = this.prefilled === ' ' ? '' : this.prefilled
this.$v.$reset()
}
},
methods: {
submit () {
this.$emit('submit')
},
input () {
this.$v.inputValue.$touch()
this.error = this.$v.inputValue.$error
this.$emit('input', this.inputValue)
},
blur () {
this.$v.inputValue.$touch()
this.error = this.$v.inputValue.$error
},
reset () {
this.$refs.inputField.clear()
this.$v.$reset()
}
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
</style>

@ -1,113 +0,0 @@
<template>
<q-field
:error-label="errorMessage"
>
<q-input
v-model="inputValue"
dark
clearable
type="text"
:float-label="label"
:error="$v.inputValue.$error"
:before="beforeButtons"
@keyup.enter="submit"
@keypress.space.prevent
@keydown.space.prevent
@keyup.space.prevent
@input="input"
@blur="blur"
/>
</q-field>
</template>
<script>
import {
userInfoAndEmpty
} from 'src/helpers/validation'
import {
maxLength,
required
} from 'vuelidate/lib/validators'
export default {
name: 'CscNewCallForwardInputText',
props: {
label: {
type: String,
default: ''
},
prefilled: {
type: String,
default: ''
},
before: {
type: Array,
default () {
return []
}
}
},
data () {
return {
inputValue: '',
error: ''
}
},
validations: {
inputValue: {
userInfoAndEmpty,
maxLength: maxLength(64),
required
}
},
computed: {
errorMessage () {
if (!this.$v.inputValue.required) {
return this.$t('validationErrors.fieldRequired', {
field: this.label
})
} else if (!this.$v.inputValue.maxLength) {
return this.$t('validationErrors.maxLength', {
field: this.label,
maxLength: this.$v.inputValue.$params.maxLength.max
})
} else if (!this.$v.inputValue.userInfoAndEmpty) {
return this.$t('validationErrors.inputValidNumber')
} else {
return ''
}
},
beforeButtons () {
return this.before ? this.before : []
}
},
watch: {
error (state) {
this.$emit('error', state)
}
},
mounted () {
if (this.prefilled) {
this.inputValue = this.prefilled === ' ' ? '' : this.prefilled
}
},
methods: {
submit () {
this.$emit('submit')
},
input () {
this.$v.inputValue.$touch()
this.error = this.$v.inputValue.$error
this.$emit('input', this.inputValue)
},
blur () {
this.$v.inputValue.$touch()
this.error = this.$v.inputValue.$error
}
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
</style>

@ -3,14 +3,14 @@
class="row csc-cf-source-cont"
:class="{ 'csc-cf-removed-source': removeInProgress }"
>
<div class="col text-left col-xs-12 col-md-10 ">
<div class="col text-left col-xs-10 col-md-10 ">
<div
class="csc-cf-source"
>
{{ source }}
</div>
</div>
<div class="col col-xs-12 col-md-2 csc-cf-source-actions">
<div class="col col-xs-2 col-md-2 csc-cf-source-actions">
<q-icon
name="delete"
color="negative"
@ -29,7 +29,7 @@ export default {
name: 'CscNewCallForwardSource',
props: {
groupId: {
type: String,
type: [String, Number],
default: null
},
groupName: {
@ -45,7 +45,7 @@ export default {
default: ''
},
sourceSetId: {
type: String,
type: [String, Number],
default: null
}
},
@ -92,9 +92,6 @@ export default {
white-space nowrap
overflow hidden
text-overflow ellipsis
.csc-cf-number-form
padding 0 20px 0 20px
min-width 120px
.csc-cf-source-actions
text-align left
cursor pointer

@ -1,39 +1,39 @@
<template>
<csc-page
class="csc-simple-page"
class="q-pa-lg"
>
<div
class="csc-cf-row row"
class="row q-mb-lg"
>
<div
v-if="groupsCount > 0"
class="col col-xs-12 col-md-4 csc-cf-group-title"
class="col-xs-4 col-md-4 text-right"
>
{{ $t('pages.newCallForward.titles.mainTitle', {number: subscriberDisplayName}) }}
</div>
<div
v-else
class="col col-xs-12 col-md-4 csc-cf-group-title"
class="col-xs-4 col-md-4 text-right"
>
{{ $t('pages.newCallForward.primarNumberEnabled') }} {{ subscriberDisplayName }}
</div>
<div
class="col col-xs-12 col-md-2 text-left csc-cf-self-number-cont"
class="col-xs-2 col-md-2 text-left csc-cf-self-number-cont"
>
<q-toggle
v-if="forwardGroups.length > 0"
v-if="groups.length > 0"
v-model="toggleDefaultNumber"
@input="toggleChange"
/>
</div>
<div
class="col col-xs-12 col-md-6"
class="col-xs-6 col-md-6"
/>
</div>
<div
v-for="forwardGroup in forwardGroups"
v-for="forwardGroup in groups"
:key="forwardGroup.id"
class="csc-cf-row row"
class="row q-mb-lg"
>
<csc-cf-group
v-if="!groupInCreation"
@ -41,49 +41,53 @@
:toggle-default-number="toggleDefaultNumber"
/>
</div>
<div class="csc-cf-row row">
<div class="row q-mb-md">
<div
class="column col col-xs-12 col-md-4"
class="col-xs-4 col-md-4 text-right"
>
<q-spinner-dots
v-if="groupsLoading"
class="csc-call-spinner"
class="q-ml-auto"
color="primary"
:size="24"
/>
</div>
</div>
<div class="csc-cf-row row">
<div
v-if="!groupsLoading"
class="row q-mb-lg"
>
<div
class="column col col-xs-12 col-md-4 items-end"
v-if="!groupsLoading"
class="col-xs-4 col-md-4"
>
<div
class="csc-text-action"
<q-btn
flat
color="primary"
class="csc-cf-add-forwarding-btn"
>
<q-icon
name="add"
color="primary"
size="24px"
/>
{{ $t('pages.newCallForward.forwardBtnLabel') }}
<q-spinner-dots
v-if="groupInCreation"
color="primary"
:size="24"
/>
<q-menu
ref="destsetTypeForm"
:auto-close="true"
class="cf-popover-bottom"
@open="resetSelectFwdGroup()"
@close="addForwardGroup()"
@show="resetSelectFwdGroup()"
@hide="addForwardGroup()"
>
<csc-new-call-forward-destinationset-type-select
ref="destsetTypeForm"
/>
</q-menu>
</div>
</q-btn>
<q-spinner-dots
v-if="groupInCreation"
color="primary"
:size="24"
/>
</div>
</div>
</csc-page>
@ -107,8 +111,11 @@ export default {
},
data () {
return {
groups: [],
// TODO move to store
groupInCreation: false,
groupsLoading: false,
//
toggleDefaultNumber: true
}
},
@ -119,13 +126,18 @@ export default {
'selectedDestType'
]),
groupsCount () {
return this.forwardGroups.length
return this.groups.length
}
},
watch: {
forwardGroups () {
this.groups = this.forwardGroups
}
},
async mounted () {
this.groupsLoading = true
this.$store.dispatch('newCallForward/loadMappings')
// here we need to wait for the groups to be available in client
// waits for the groups to be available
await this.$store.dispatch('newCallForward/loadForwardGroups')
const unconditionalGroups = await this.$store.dispatch('newCallForward/getForwardGroupByName', 'unconditional')
this.toggleDefaultNumber = !unconditionalGroups
@ -137,10 +149,9 @@ export default {
async addForwardGroup () {
this.groupInCreation = true
const selectedDestType = this.selectedDestType
const tempGroups = this.forwardGroups.filter(($group) => {
const tempGroups = this.groups.filter(($group) => {
return $group.id.toString().indexOf('temp-') > -1
})
if (tempGroups.length > 0) {
showGlobalWarning(`${this.$t('pages.newCallForward.addDestinationAlert')}`, 5000)
} else {
@ -181,10 +192,6 @@ export default {
}
this.groupInCreation = false
},
showForm () {
this.$refs.destinationType.close()
this.$refs.addDestinationForm.add()
},
toggleChange () {
this.groupInCreation = true
this.$store.dispatch('newCallForward/forwardAllCalls', !this.toggleDefaultNumber)
@ -198,17 +205,8 @@ export default {
</script>
<style lang="stylus" rel="stylesheet/stylus">
.csc-cf-flat-btn
color $primary
float right
.csc-cf-group-title
text-align right
.csc-cf-destinations-cont
margin-top 25px
.csc-cf-field-toggle
margin-top 0px
.csc-call-spinner
margin-left auto
.csc-cf-add-forwarding-btn
float right
.csc-cf-self-number-cont
padding-left 30px
width 150px
@ -218,5 +216,7 @@ export default {
.cf-popover-bottom
min-width 150px
margin-left 5px
.csc-actions-cont
margin-top 10px
</style>

@ -21,7 +21,9 @@ import {
deleteTimesetById
} from '../api/call-forward'
import { getSubscriberId } from 'src/auth'
import {
randInRange
} from 'src/helpers/math-helper'
const ForwardGroup = {
unconditional: {
name: 'csc-unconditional',
@ -58,7 +60,8 @@ export default {
forwardGroups: [],
groupsLoaders: [],
selectedDestType: null,
firstDestinationInCreation: null
firstDestinationInCreation: null,
selectedDestinationType: null
},
getters: {
getGroupsLoaders (state) {
@ -141,9 +144,21 @@ export default {
},
getTimesets (state) {
return state.timeSets
},
getSelectedDestType (state) {
return state.selectedDestType
},
getSelectedDestinationType (state) {
return state.selectedDestinationType
}
},
mutations: {
addGroup (state, data) {
state.forwardGroups.push(data)
},
addFirstGroup (state, data) {
state.forwardGroups.unshift(data)
},
addDestination (state, forwardGroupId, destination) {
const group = state.forwardGroups.find((group) => {
return group.id === forwardGroupId
@ -188,6 +203,9 @@ export default {
return group.id === data.groupId
})
group.destinations = data.destinations
for (const destination of group.destinations) {
destination.display_id = randInRange(100000, 999999)
}
},
setMappings (state, mappings) {
state.mappings = mappings
@ -195,6 +213,9 @@ export default {
setSelectedDestType (state, destType) {
state.selectedDestType = destType
},
setSelectedDestinationType (state, type) {
state.selectedDestinationType = type
},
setSourceSets (state, sourceSets) {
state.sourceSets = sourceSets
},
@ -257,7 +278,7 @@ export default {
const subscriberId = getSubscriberId()
const groupMappingId = ForwardGroup[data.name] ? ForwardGroup[data.name].mapping : await context.dispatch('getMappingIdByGroupName', data.name)
const allMappings = context.getters.getMappings
const groupMappings = allMappings[groupMappingId]
const groupMappings = _.cloneDeep(allMappings[groupMappingId])
if (data.replaceMapping) {
for (const mapping of groupMappings) {
if (mapping.destinationset_id === data.groupId) {
@ -286,7 +307,6 @@ export default {
async addForwardGroup (context, data) {
try {
const newForwardGroupId = await addNewDestinationsetWithName(ForwardGroup[data.name] ? ForwardGroup[data.name].name : data.name)
const destination = {
announcement_id: null,
simple_destination: data.destination || ' ',
@ -298,7 +318,6 @@ export default {
name: data.name,
groupId: newForwardGroupId
})
await addDestinationToDestinationset({
id: newForwardGroupId,
data: [destination]
@ -350,9 +369,9 @@ export default {
}]
}
if (groupName.includes('timeout') || groupName.includes('unconditional')) {
context.state.forwardGroups.unshift(data)
context.commit('addFirstGroup', data)
} else {
context.state.forwardGroups.push(data)
context.commit('addGroup', data)
}
},
async addDestination (context, data) {
@ -589,13 +608,14 @@ export default {
const subscriberId = getSubscriberId()
const mappingId = await context.dispatch('getMappingIdByGroupName', data.groupName)
const groupMappings = await context.state.mappings[mappingId]
for (const group of groupMappings) {
const clonedGroupMappings = _.cloneDeep(groupMappings)
for (const group of clonedGroupMappings) {
if (group.destinationset_id === data.id) {
group.enabled = data.enabled
}
}
const updatedMappings = await addNewMapping({
mappings: groupMappings,
mappings: clonedGroupMappings,
group: mappingId,
subscriberId: subscriberId
})
@ -668,7 +688,6 @@ export default {
},
async createTimeSet (context, timesetName) {
try {
// const subscriberId = getSubscriberId();
const timesetId = await addNewTimeset(timesetName)
return timesetId
} catch (err) {
@ -716,6 +735,9 @@ export default {
} catch (err) {
console.log(err)
}
},
setSelectedDestinationType (context, type) {
context.commit('setSelectedDestinationType', type)
}
}
}

Loading…
Cancel
Save