TT#28056 List all company hours destinations

What has been done:
- TT#31193, CallForwarding: Create store mutation unit test
- TT#31191, CallForwarding: Implement API requests
- TT#31192, CallForwarding: Implement store
- TT#31175, CallForwarding: Implement vue component

Change-Id: I971e06cea0b930f57ede43b7a56c6766a790e651
changes/40/18640/9
raxelsen 7 years ago
parent 3463789805
commit cefb66b549

@ -84,31 +84,37 @@ export function getDestinationsets(id) {
});
}
export function loadAlwaysEverybodyDestinations(subscriberId) {
export function loadAlwaysDestinations(options) {
return new Promise((resolve, reject)=>{
let cfuTimeset = null;
let cfnaTimeset = null;
let cfbTimeset = null;
Promise.resolve().then(()=>{
return getMappings(subscriberId);
}).then((mappings) => {
return getMappings(options.subscriberId);
}).then((mappings)=>{
let cfuPromises = [];
let cfnaPromises = [];
let cfbPromises = [];
if(_.has(mappings, 'cfu') && _.isArray(mappings.cfu) && mappings.cfu.length > 0) {
mappings.cfu.forEach((cfuMapping)=>{
if (cfuMapping.timeset_id === null && cfuMapping.sourceset_id === null) {
if (cfuMapping.timeset === options.timeset && cfuMapping.sourceset_id === null) {
cfuTimeset = cfuMapping.timeset_id;
cfuPromises.push(getDestinationsetById(cfuMapping.destinationset_id));
}
});
}
if(_.has(mappings, 'cfna') && _.isArray(mappings.cfna) && mappings.cfna.length > 0) {
mappings.cfna.forEach((cfnaMapping)=>{
if (cfnaMapping.timeset_id === null && cfnaMapping.sourceset_id === null) {
if (cfnaMapping.timeset === options.timeset && cfnaMapping.sourceset_id === null) {
cfnaTimeset = cfnaMapping.timeset_id;
cfnaPromises.push(getDestinationsetById(cfnaMapping.destinationset_id));
}
});
}
if(_.has(mappings, 'cfb') && _.isArray(mappings.cfb) && mappings.cfb.length > 0) {
mappings.cfb.forEach((cfbMapping)=>{
if (cfbMapping.timeset_id === null && cfbMapping.sourceset_id === null) {
if (cfbMapping.timeset === options.timeset && cfbMapping.sourceset_id === null) {
cfbTimeset = cfbMapping.timeset_id;
cfbPromises.push(getDestinationsetById(cfbMapping.destinationset_id));
}
});
@ -119,9 +125,9 @@ export function loadAlwaysEverybodyDestinations(subscriberId) {
Promise.all(cfbPromises)
]);
}).then((res)=>{
addGroupNames(res[0], 'cfu');
addGroupNames(res[1], 'cfna');
addGroupNames(res[2], 'cfb');
addGroupNamesAndTimeset({ group: res[0], groupName: 'cfu', timesetId: cfuTimeset });
addGroupNamesAndTimeset({ group: res[1], groupName: 'cfna', timesetId: cfnaTimeset });
addGroupNamesAndTimeset({ group: res[2], groupName: 'cfb', timesetId: cfbTimeset });
resolve({
online: res[0],
offline: res[1],
@ -133,11 +139,12 @@ export function loadAlwaysEverybodyDestinations(subscriberId) {
});
}
export function addGroupNames(group, groupName) {
group.forEach(destinationset => {
destinationset.groupName = groupName;
export function addGroupNamesAndTimeset(options) {
options.group.forEach(destinationset => {
destinationset.groupName = options.groupName;
destinationset.timesetId = options.timesetId;
});
return group;
return options.group;
}
export function getDestinationsetById(id) {
@ -247,18 +254,17 @@ export function addDestinationToEmptyGroup(options) {
return addDestinationToDestinationset({
id: id, data: [options.data]
});
//}).then(() => {
// return getMappings(subscriberId);
//}).then((mappings) => {
// return addNewMapping({
// destinationsetId: destinationsetId,
// group: options.groupName,
// subscriberId: options.subscriberId,
// mappings: mappings
// });
}).then(() => {
return getMappings(options.subscriberId);
}).then((mappings) => {
let updatedMappings = mappings[options.groupName];
updatedMappings.push({
destinationset_id: destinationsetId,
sourceset_id: null,
timeset_id: options.timesetId
});
return addNewMapping({
destinationsetId: destinationsetId,
mappings: updatedMappings,
group: options.groupName,
subscriberId: options.subscriberId
});
@ -271,19 +277,12 @@ export function addDestinationToEmptyGroup(options) {
}
export function addNewMapping(options) {
let headers = {
'Content-Type': 'application/json-patch+json'
};
let headers = { 'Content-Type': 'application/json-patch+json' };
return new Promise((resolve, reject) => {
let mappingsToSend = [{
destinationset_id: options.destinationsetId,
sourceset_id: null,
timeset_id: null
}];
Vue.http.patch('/api/cfmappings/' + options.subscriberId, [{
op: 'replace',
path: '/' + options.group,
value: mappingsToSend
value: options.mappings
}], { headers: headers }).then(result => {
resolve(result);
}).catch(err => {

@ -4,16 +4,19 @@
<csc-destinations :title="$t('pages.callForward.whenOnline')"
:group="destinations.online"
group-name="cfu"
timeset="null"
icon="signal_wifi_4_bar">
</csc-destinations>
<csc-destinations :title="$t('pages.callForward.whenBusy')"
:group="destinations.busy"
group-name="cfb"
timeset="null"
icon="record_voice_over">
</csc-destinations>
<csc-destinations :title="$t('pages.callForward.whenOffline')"
:group="destinations.offline"
group-name="cfna"
timeset="null"
icon="signal_wifi_off">
</csc-destinations>
</q-card>
@ -21,11 +24,15 @@
</template>
<script>
import numberFormat from '../../../filters/number-format'
import { mapState } from 'vuex'
import { startLoading, stopLoading,
showGlobalError, showToast } from '../../../helpers/ui'
import CscPage from '../../CscPage'
import CscDestinations from './CscDestinations'
import { QCard } from 'quasar-framework'
export default {
mounted() {
created() {
this.$store.dispatch('callForward/loadAlwaysEverybodyDestinations');
},
data () {
@ -38,8 +45,58 @@
CscDestinations
},
computed: {
destinations() {
return this.$store.state.callForward.alwaysEverybodyDestinations;
...mapState('callForward', {
removeDestinationState: 'removeDestinationState',
addDestinationState: 'addDestinationState',
changeDestinationState: 'changeDestinationState',
destinations: 'alwaysEverybodyDestinations',
lastRemovedDestination: 'lastRemovedDestination',
lastAddedDestination: 'lastAddedDestination',
addDestinationError(state) {
return state.addDestinationError ||
this.$t('pages.callForward.addErrorMessage');
}
})
},
watch: {
removeDestinationState(state) {
if (state === 'requesting') {
startLoading();
} else if (state === 'failed') {
stopLoading();
showGlobalError(this.removeDestinationError);
} else if (state === 'succeeded') {
stopLoading();
showToast(this.$t('pages.callForward.removeSuccessMessage', {
destination: this.lastRemovedDestination
}));
this.$store.dispatch('callForward/loadAlwaysEverybodyDestinations');
}
},
addDestinationState(state) {
if (state === 'requesting') {
startLoading();
} else if (state === 'failed') {
stopLoading();
showGlobalError(this.addDestinationError);
} else if (state === 'succeeded') {
stopLoading();
showToast(this.$t('pages.callForward.addDestinationSuccessMessage', {
destination: this.lastAddedDestination
}));
this.$store.dispatch('callForward/loadAlwaysEverybodyDestinations');
}
},
changeDestinationState(state) {
if (state === 'requesting') {
startLoading();
} else if (state === 'failed') {
stopLoading();
showGlobalError(this.changeDestinationError);
} else if (state === 'succeeded') {
stopLoading();
this.$store.dispatch('callForward/loadAlwaysEverybodyDestinations');
}
}
}
}

@ -1,19 +1,106 @@
<template>
<csc-page :title="$t('pages.callForward.titles.companyHours')">
<q-card class="dest-card">
<csc-destinations :title="$t('pages.callForward.whenOnline')"
:group="destinations.online"
group-name="cfu"
timeset="Company Hours"
icon="signal_wifi_4_bar">
</csc-destinations>
<csc-destinations :title="$t('pages.callForward.whenBusy')"
:group="destinations.busy"
group-name="cfb"
timeset="Company Hours"
icon="record_voice_over">
</csc-destinations>
<csc-destinations :title="$t('pages.callForward.whenOffline')"
:group="destinations.offline"
group-name="cfna"
timeset="Company Hours"
icon="signal_wifi_off">
</csc-destinations>
</q-card>
</csc-page>
</template>
<script>
import numberFormat from '../../../filters/number-format'
import { mapState } from 'vuex'
import { startLoading, stopLoading,
showGlobalError, showToast } from '../../../helpers/ui'
import CscPage from '../../CscPage'
import CscDestinations from './CscDestinations'
import { QCard } from 'quasar-framework'
export default {
created() {
this.$store.dispatch('callForward/loadCompanyHoursEverybodyDestinations');
},
data () {
return {}
return {
}
},
components: {
CscPage
QCard,
CscPage,
CscDestinations
},
computed: {
...mapState('callForward', {
removeDestinationState: 'removeDestinationState',
addDestinationState: 'addDestinationState',
changeDestinationState: 'changeDestinationState',
destinations: 'companyHoursEverybodyDestinations',
lastRemovedDestination: 'lastRemovedDestination',
lastAddedDestination: 'lastAddedDestination',
addDestinationError(state) {
return state.addDestinationError ||
this.$t('pages.callForward.addErrorMessage');
}
})
},
watch: {
removeDestinationState(state) {
if (state === 'requesting') {
startLoading();
} else if (state === 'failed') {
stopLoading();
showGlobalError(this.removeDestinationError);
} else if (state === 'succeeded') {
stopLoading();
showToast(this.$t('pages.callForward.removeSuccessMessage', {
destination: this.lastRemovedDestination
}));
this.$store.dispatch('callForward/loadCompanyHoursEverybodyDestinations');
}
},
addDestinationState(state) {
if (state === 'requesting') {
startLoading();
} else if (state === 'failed') {
stopLoading();
showGlobalError(this.addDestinationError);
} else if (state === 'succeeded') {
stopLoading();
showToast(this.$t('pages.callForward.addDestinationSuccessMessage', {
destination: this.lastAddedDestination
}));
this.$store.dispatch('callForward/loadCompanyHoursEverybodyDestinations');
}
},
changeDestinationState(state) {
if (state === 'requesting') {
startLoading();
} else if (state === 'failed') {
stopLoading();
showGlobalError(this.changeDestinationError);
} else if (state === 'succeeded') {
stopLoading();
this.$store.dispatch('callForward/loadCompanyHoursEverybodyDestinations');
}
}
}
}
</script>
<style>
<style lang="stylus">
</style>

@ -54,7 +54,9 @@
'destinations',
'id',
'groupName',
'priority'
'priority',
'timeset',
'timesetId'
],
data () {
return {
@ -81,9 +83,7 @@
...mapState('callForward', [
'activeForm',
'formType',
'addDestinationState',
'addDestinationError',
'lastAddedDestination'
'addDestinationState'
]),
...mapGetters('callForward', [
'hasFaxCapability'
@ -97,9 +97,6 @@
addDestinationIsRequesting() {
return this.addDestinationState === 'requesting';
},
addDestinationError() {
return this.$store.state.callForward.addDestinationError || this.$t('pages.callForward.addErrorMessage');
},
beforeIconTimeout() {
return [{
icon: 'schedule'
@ -113,17 +110,8 @@
},
watch: {
addDestinationState(state) {
if (state === 'failed') {
stopLoading();
showGlobalError(this.addDestinationError);
} else if (state === 'succeeded') {
stopLoading();
showToast(this.$t('pages.callForward.addDestinationSuccessMessage', {
destination: this.lastAddedDestination
}));
if (state === 'succeeded') {
this.disableForm();
} else if (state === 'button') {
stopLoading();
}
}
},
@ -155,7 +143,9 @@
startLoading();
this.$store.dispatch('callForward/addDestination', {
form: this.destinationForm,
destinations: this.destinations
destinations: this.destinations,
timeset: this.timeset,
timesetId: this.timesetId
});
}
}

@ -119,9 +119,10 @@
},
deleteDestination(index) {
let clonedDestinations = _.cloneDeep(this.destinations);
let clonedDestination = clonedDestinations[index].destination;
let indexInt = parseInt(index);
let store = this.$store;
let removeDestination = numberFormat(this.destinations[index].destination);
let removeDestination = numberFormat(clonedDestination);
let self = this;
let isLastDestination = this.destinations.length === 1;
clonedDestinations.splice(indexInt, 1);
@ -139,14 +140,9 @@
store.dispatch('callForward/deleteDestinationFromDestinationset', {
id: self.id,
data: clonedDestinations,
deleteDestinationset: isLastDestination }).then((result) => {
store.dispatch('callForward/loadAlwaysEverybodyDestinations');
showToast(self.$t('pages.callForward.removeSuccessMessage', {
destination: removeDestination
}));
}).catch((err) => {
showToast(self.$t('pages.callForward.removeErrorMessage'));
});
deleteDestinationset: isLastDestination,
removeDestination: removeDestination
})
}
}
]

@ -39,7 +39,8 @@
'title',
'icon',
'group',
'groupName'
'groupName',
'timeset'
],
components: {
QCardTitle,
@ -54,6 +55,8 @@
lastDestinationset() {
let destinationset = _.findLast(this.group) || {};
destinationset.groupName = this.groupName;
destinationset.priority = destinationset.lowestPriority || 1;
destinationset.timeset = this.timeset;
return destinationset;
}
},

@ -3,7 +3,7 @@
import _ from 'lodash'; import { getSourcesets, getDestinationsets,
getTimesets,
getMappings,
loadAlwaysEverybodyDestinations,
loadAlwaysDestinations,
deleteDestinationFromDestinationset,
addDestinationToDestinationset,
addDestinationToEmptyGroup,
@ -12,14 +12,7 @@ import _ from 'lodash'; import { getSourcesets, getDestinationsets,
moveDestinationUp,
moveDestinationDown } from '../api/call-forward';
const AddDestinationState = {
button: 'button',
requesting: 'requesting',
succeeded: 'succeeded',
failed: 'failed'
};
const ChangeDestinationState = {
const DestinationState = {
button: 'button',
requesting: 'requesting',
succeeded: 'succeeded',
@ -34,13 +27,22 @@ export default {
timesets: null,
destinationsets: null,
alwaysEverybodyDestinations: {
online: [{}],
busy: [{}],
offline: [{}]
},
addDestinationState: AddDestinationState.button,
online: [],
busy: [],
offline: []
},
companyHoursEverybodyDestinations: {
online: [],
busy: [],
offline: []
},
removeDestinationState: DestinationState.button,
removeDestinationError: null,
lastRemovedDestination: null,
addDestinationState: DestinationState.button,
addDestinationError: null,
changeDestinationState: ChangeDestinationState.button,
lastAddedDestination: null,
changeDestinationState: DestinationState.button,
changeDestinationError: null,
activeForm: '',
formType: '',
@ -51,8 +53,7 @@ export default {
destination: '',
priority: 1,
timeout: ''
},
lastAddedDestination: null
}
},
getters: {
hasFaxCapability(state, getters, rootState, rootGetters) {
@ -72,6 +73,17 @@ export default {
},
getDestinationsetId(state) {
return state.destinationsetId;
},
getCompanyHoursId(state) {
let timeset;
for (let group in state.companyHoursEverybodyDestinations) {
if (!timeset) {
timeset = _.find(state.companyHoursEverybodyDestinations[group], (o) => {
return o.timesetId > 0;
});
};
};
return timeset ? timeset.timesetId : null;
}
},
mutations: {
@ -90,6 +102,9 @@ export default {
loadAlwaysEverybodyDestinations(state, result) {
state.alwaysEverybodyDestinations = result;
},
loadCompanyHoursEverybodyDestinations(state, result) {
state.companyHoursEverybodyDestinations = result;
},
setActiveForm(state, value) {
state.activeForm = value;
},
@ -121,31 +136,48 @@ export default {
state.formType = '';
state.destinationsetId = '';
state.groupName = '';
state.addDestinationState = AddDestinationState.button;
state.addDestinationState = DestinationState.button;
state.changeDestinationState = DestinationState.button;
state.removeDestinationState = DestinationState.button;
},
addDestinationRequesting(state) {
state.addDestinationState = AddDestinationState.requesting;
state.addDestinationState = DestinationState.requesting;
state.addDestinationError = null;
},
addDestinationSucceeded(state) {
state.addDestinationState = AddDestinationState.succeeded;
state.addDestinationState = DestinationState.succeeded;
state.addDestinationError = null;
},
addDestinationFailed(state, error) {
state.addDestinationState = AddDestinationState.failed;
state.addDestinationState = DestinationState.failed;
state.addDestinationError = error;
},
changeDestinationRequesting(state) {
state.changeDestinationState = ChangeDestinationState.requesting;
state.changeDestinationState = DestinationState.requesting;
state.changeDestinationError = null;
},
changeDestinationSucceeded(state) {
state.changeDestinationState = ChangeDestinationState.succeeded;
state.changeDestinationState = DestinationState.succeeded;
state.changeDestinationError = null;
},
changeDestinationFailed(state, error) {
state.changeDestinationState = ChangeDestinationState.failed;
state.changeDestinationState = DestinationState.failed;
state.changeDestinationError = error;
},
removeDestinationRequesting(state) {
state.removeDestinationState = DestinationState.requesting;
state.removeDestinationError = null;
},
removeDestinationSucceeded(state) {
state.removeDestinationState = DestinationState.succeeded;
state.removeDestinationError = null;
},
removeDestinationFailed(state, error) {
state.removeDestinationState = DestinationState.failed;
state.removeDestinationError = error;
},
setLastRemovedDestination(state, value) {
state.lastRemovedDestination = value;
}
},
actions: {
@ -191,18 +223,34 @@ export default {
},
loadAlwaysEverybodyDestinations(context) {
return new Promise((resolve, reject)=>{
loadAlwaysEverybodyDestinations(localStorage.getItem('subscriberId')).then((result)=>{
loadAlwaysDestinations({
subscriberId: localStorage.getItem('subscriberId'),
timeset: null
}).then((result)=>{
context.commit('loadAlwaysEverybodyDestinations', result);
})
});
},
loadCompanyHoursEverybodyDestinations(context) {
return new Promise((resolve, reject)=>{
loadAlwaysDestinations({
subscriberId: localStorage.getItem('subscriberId'),
timeset: 'Company Hours'
}).then((result)=>{
context.commit('loadCompanyHoursEverybodyDestinations', result);
})
});
},
deleteDestinationFromDestinationset(context, options) {
let removedDestination = options.removeDestination;
context.commit('removeDestinationRequesting');
return new Promise((resolve, reject) => {
deleteDestinationFromDestinationset(options)
.then((result) => {
resolve(result);
.then(() => {
context.commit('setLastRemovedDestination', removedDestination);
context.commit('removeDestinationSucceeded');
}).catch((err) => {
reject(err);
context.commit('removeDestinationFailed', err.message);
});
});
},
@ -220,6 +268,12 @@ export default {
let form = _.clone(context.getters.getForm);
let updatedOptions;
let type = context.getters.getFormType;
let timeset = null;
if (options.timeset === 'Company Hours') {
timeset = context.getters.getCompanyHoursId;
} else if (options.timeset === 'After Hours') {
timeset = context.getters.getAfterHoursId;
};
context.commit('addDestinationRequesting');
if (type !== 'number') {
delete form.timeout;
@ -232,14 +286,14 @@ export default {
subscriberId: context.getters.getSubscriberId,
data: form,
groupName: context.getters.getGroupName,
id: context.getters.getDestinationsetId
id: context.getters.getDestinationsetId,
timesetId: timeset
};
if (options.destinations) {
return new Promise((resolve, reject) => {
addDestinationToExistingGroup(updatedOptions).then(() => {
context.commit('setLastAddedDestination', options.form.destination);
context.commit('addDestinationSucceeded');
context.dispatch('loadAlwaysEverybodyDestinations');
}).catch((err) => {
context.commit('addDestinationFailed', err.message);
});
@ -247,8 +301,8 @@ export default {
} else {
return new Promise((resolve, reject) => {
addDestinationToEmptyGroup(updatedOptions).then((result) => {
context.commit('setLastAddedDestination', options.form.destination);
context.commit('addDestinationSucceeded');
context.dispatch('loadAlwaysEverybodyDestinations');
}).catch((err) => {
context.commit('addDestinationFailed', err.message);
});
@ -269,7 +323,6 @@ export default {
destination: clonedDestination
}).then(() => {
context.commit('changeDestinationSucceeded');
context.dispatch('loadAlwaysEverybodyDestinations');
}).catch((err) => {
context.commit('changeDestinationFailed', err.message);
});
@ -282,7 +335,6 @@ export default {
destination: clonedDestination
}).then(() => {
context.commit('changeDestinationSucceeded');
context.dispatch('loadAlwaysEverybodyDestinations');
}).catch((err) => {
context.commit('changeDestinationFailed', err.message);
});
@ -306,7 +358,6 @@ export default {
subscriberId: context.getters.getSubscriberId
}).then(() => {
context.commit('changeDestinationSucceeded');
context.dispatch('loadAlwaysEverybodyDestinations');
}).catch((err) => {
context.commit('changeDestinationFailed', err.message);
});

@ -50,6 +50,36 @@ describe('CallForward', function(){
};
CallForwardModule.mutations.resetFormState(state);
assert.deepEqual(state.form, data);
it('should load always company hours destinations', function(){
let state = {
alwaysCompanyHoursDestinations: [
]
};
let data = {
busy: [],
offline: [{
destinations: [{
"announcement_id": null,
"destination": "sip:3333@192.168.178.23",
"priority": 1,
"simple_destination": "3333",
"timeout": 60
},
{
"announcement_id": null,
"destination": "sip:2222@192.168.178.23",
"priority": 1,
"simple_destination": "2222",
"timeout": 300
}],
id: 3,
name: "csc_destinationset_1"
}],
online: []
};
CallForwardModule.mutations.loadAlwaysCompanyHoursDestinations(state, data);
assert.deepEqual(state.alwaysCompanyHoursDestinations, data);
});
});

Loading…
Cancel
Save