TT#20512 PBXConfig: As a Customer, I want to edit PBX Groups

Change-Id: I36d7b4a80f16c36aa044d9d7adb2cfddc0e053be
changes/15/20115/1
Hans-Peter Herzog 8 years ago
parent fdd04ee89d
commit d04cbe3d1b

@ -3,7 +3,9 @@ import _ from 'lodash';
import Vue from 'vue'; import Vue from 'vue';
import { getJsonBody } from './utils'; import { getJsonBody } from './utils';
import { getNumbers, assignNumbers } from './user'; import { getNumbers, assignNumbers } from './user';
import { createSubscriber, deleteSubscriber } from './subscriber'; import { createSubscriber, deleteSubscriber, setDisplayName,
setPbxExtension, setPbxHuntPolicy, setPbxHuntTimeout,
setPbxGroupMemberIds } from './subscriber';
import uuid from 'uuid'; import uuid from 'uuid';
var createId = uuid.v4; var createId = uuid.v4;
@ -132,3 +134,23 @@ export function addSeat(seat) {
export function removeSeat(id) { export function removeSeat(id) {
return deleteSubscriber(id); return deleteSubscriber(id);
} }
export function setGroupName(id, groupName) {
return setDisplayName(id, groupName);
}
export function setGroupExtension(id, groupExtension) {
return setPbxExtension(id, groupExtension);
}
export function setGroupHuntPolicy(id, huntPolicy) {
return setPbxHuntPolicy(id, huntPolicy);
}
export function setGroupHuntTimeout(id, huntTimeout) {
return setPbxHuntTimeout(id, huntTimeout);
}
export function updateGroupSeats(id, seatIds) {
return setPbxGroupMemberIds(id, seatIds);
}

@ -215,3 +215,48 @@ export function deleteSubscriber(id) {
}); });
}); });
} }
export function setField(id, field, value) {
return new Promise((resolve, reject)=>{
Vue.http.patch('/api/subscribers/' + id, [{
op: 'replace',
path: '/'+ field,
value: value
}], {
headers: {
'Content-Type': 'application/json-patch+json',
'Prefer': 'return=minimal'
}
}).then((result)=>{
resolve(result);
}).catch((err)=>{
if(err.status >= 400) {
reject(new Error(err.body.message));
}
else {
reject(err);
}
});
});
}
export function setDisplayName(id, displayName) {
return setField(id, 'display_name', displayName);
}
export function setPbxExtension(id, pbxExtension) {
return setField(id, 'pbx_extension', pbxExtension);
}
export function setPbxHuntPolicy(id, pbxHuntPolicy) {
return setField(id, 'pbx_hunt_policy', pbxHuntPolicy);
}
export function setPbxHuntTimeout(id, pbxHuntTimeout) {
return setField(id, 'pbx_hunt_timeout', pbxHuntTimeout);
}
export function setPbxGroupMemberIds(id, ids) {
return setField(id, 'pbx_groupmember_ids', ids);
}

@ -1,5 +1,5 @@
<template> <template>
<csc-page :title="$t('pages.home.title')"> <csc-page :title="$t('pages.home.title')" id="csc-page-home">
<div class="row md-gutter"> <div class="row md-gutter">
<div class="col-lg-4 col-md-6 col-sm-6 col-xs-6"> <div class="col-lg-4 col-md-6 col-sm-6 col-xs-6">
<div @click="call()"> <div @click="call()">
@ -148,9 +148,10 @@
} }
</script> </script>
<style lang="stylus" scoped rel="stylesheet/stylus"> <style lang="stylus" rel="stylesheet/stylus">
@import '../../themes/quasar.variables.styl' @import '../../themes/quasar.variables.styl'
#csc-page-home
.q-card-actions .q-card-actions
font-size 22px font-size 22px
padding 0 10px 35px 10px padding 0 10px 35px 10px
@ -178,6 +179,7 @@
color $grey color $grey
@media (max-width: $breakpoint-sm) @media (max-width: $breakpoint-sm)
#csc-page-home
.q-card-actions .q-card-actions
font-size 16px font-size 16px
padding 0 10px 25px 10px padding 0 10px 25px 10px

@ -3,36 +3,38 @@
<q-card-title class="cursor-pointer" @click="toggleMain()"> <q-card-title class="cursor-pointer" @click="toggleMain()">
<q-icon name="group" color="primary" size="24px"/> <q-icon name="group" color="primary" size="24px"/>
<span v-if="!expanded" class="csc-pbx-group-title">{{ group.display_name }}</span> <span v-if="!expanded" class="csc-pbx-group-title">{{ group.display_name }}</span>
<q-chip v-if="!expanded" pointing="left" color="primary"> <q-chip v-if="!expanded" pointing="left" color="primary" class="gt-md">
{{ $t('pbxConfig.extension') }}: <span class="csc-important">{{ group.pbx_extension }}</span> {{ $t('pbxConfig.extension') }}: <span class="csc-important">{{ group.pbx_extension }}</span>
</q-chip> </q-chip>
<q-icon :name="titleIcon" color="primary" size="22px" slot="right"/> <q-icon :name="titleIcon" color="primary" size="22px" slot="right"/>
</q-card-title> </q-card-title>
<q-card-main v-if="expanded" class="transition-generic"> <q-card-main v-if="expanded" class="transition-generic">
<q-field :label="$t('pbxConfig.groupName')"> <q-field :label="$t('pbxConfig.groupName')">
<q-input v-model="name" readonly /> <q-input v-model="changes.name" :after="nameButtons" />
</q-field> </q-field>
<q-field :label="$t('pbxConfig.extension')"> <q-field :label="$t('pbxConfig.extension')">
<q-input v-model="extension" readonly /> <q-input v-model="changes.extension" type="number" :after="extensionButtons" />
</q-field> </q-field>
<q-field :label="$t('pbxConfig.huntPolicy')"> <q-field :label="$t('pbxConfig.huntPolicy')">
<q-select v-model="huntPolicy" :options="huntPolicyOptions" readonly radio /> <q-select v-model="changes.huntPolicy" :options="huntPolicyOptions" radio @change="huntPolicyChanged"/>
</q-field> </q-field>
<q-field :label="$t('pbxConfig.huntTimeout')"> <q-field :label="$t('pbxConfig.huntTimeout')">
<q-input v-model="huntTimeout" readonly suffix="seconds" readonly min="0" /> <q-input v-model="changes.huntTimeout" type="number" suffix="seconds" :after="huntTimeoutButtons" min="0" />
</q-field> </q-field>
<q-field :label="$t('pbxConfig.primaryNumber')"> <q-field :label="$t('pbxConfig.primaryNumber')">
<q-input v-model="primaryNumber" readonly disabled /> <q-input v-model="primaryNumber" readonly disabled />
</q-field> </q-field>
<q-field :label="$t('pbxConfig.aliasNumbers')"> <q-field :label="$t('pbxConfig.aliasNumbers')">
<q-select v-model="aliasNumbers" :options="aliasNumberOptions" multiple chips readonly clearable /> <q-select ref="aliasNumbers" v-model="changes.aliasNumbers" :options="aliasNumberOptions"
multiple chips clearable :after="aliasNumberButtons" @change="aliasNumberChange"/>
</q-field> </q-field>
<q-field :label="$t('pbxConfig.seats')"> <q-field :label="$t('pbxConfig.seats')">
<q-select v-model="seats" :options="seatOptions" multiple chips readonly clearable /> <q-select v-model="changes.seats" :options="seatOptions" multiple chips clearable
:after="seatButtons" @change="seatChange" />
</q-field> </q-field>
</q-card-main> </q-card-main>
<q-card-actions align="center"> <q-card-actions align="center">
<q-btn :loader="isLoading" v-model="isLoading" flat :small="isMobile" :round="isMobile" <q-btn flat :small="isMobile" :round="isMobile"
color="negative" icon="delete" @click="remove()">Delete</q-btn> color="negative" icon="delete" @click="remove()">Delete</q-btn>
</q-card-actions> </q-card-actions>
<q-inner-loading :visible="isLoading"> <q-inner-loading :visible="isLoading">
@ -71,7 +73,8 @@
], ],
data () { data () {
return { return {
expanded: false expanded: false,
changes: this.getGroup()
} }
}, },
components: { components: {
@ -108,34 +111,16 @@
primaryNumber() { primaryNumber() {
return numberFilter(this.group.primary_number); return numberFilter(this.group.primary_number);
}, },
aliasNumbers() {
let numbers = [];
if(_.isArray(this.group.alias_numbers)) {
this.group.alias_numbers.forEach((number) => {
numbers.push(number.number_id);
});
}
return numbers;
},
seats() {
let seats = [];
if(_.isArray(this.group.seats)) {
this.group.seats.forEach((seat) => {
seats.push(seat.id);
});
}
return seats;
},
groupModel() { groupModel() {
return { return {
id: this.id, id: this.id,
name: this.name, name: this.changes.name,
extension: this.extension, extension: this.changes.extension,
huntPolicy: this.huntPolicy, huntPolicy: this.changes.huntPolicy,
huntTimeout: this.huntTimeout, huntTimeout: this.changes.huntTimeout,
primaryNumber: this.primaryNumber, primaryNumber: this.primaryNumber,
aliasNumbers: this.aliasNumbers, aliasNumbers: this.changes.aliasNumbers,
seats: this.seats seats: this.changes.seats
} }
}, },
isLoading() { isLoading() {
@ -158,6 +143,164 @@
}, },
isMobile() { isMobile() {
return Platform.is.mobile; return Platform.is.mobile;
},
nameHasChanges() {
return this.name !== this.changes.name;
},
nameButtons() {
let buttons = [];
let self = this;
if(this.nameHasChanges) {
buttons.push({
icon: 'check',
error: false,
handler (event) {
event.stopPropagation();
self.saveName();
}
}, {
icon: 'clear',
error: false,
handler (event) {
event.stopPropagation();
self.resetName();
}
}
);
}
return buttons;
},
extensionHasChanges() {
return this.extension + "" !== this.changes.extension + "";
},
extensionButtons() {
let buttons = [];
let self = this;
if(this.extensionHasChanges) {
buttons.push({
icon: 'check',
error: false,
handler (event) {
event.stopPropagation();
self.saveExtension();
}
}, {
icon: 'clear',
error: false,
handler (event) {
event.stopPropagation();
self.resetExtension();
}
}
);
}
return buttons;
},
huntPolicyHasChanges() {
return this.huntPolicy !== this.changes.huntPolicy;
},
huntPolicyButtons() {
let buttons = [];
let self = this;
if(this.huntPolicyHasChanges) {
buttons.push({
icon: 'check',
error: false,
handler (event) {
event.stopPropagation();
self.saveHuntPolicy();
}
}, {
icon: 'clear',
error: false,
handler (event) {
event.stopPropagation();
self.resetHuntPolicy();
}
}
);
}
return buttons;
},
huntTimeoutHasChanges() {
return this.huntTimeout !== this.changes.huntTimeout;
},
huntTimeoutButtons() {
let buttons = [];
let self = this;
if(this.huntTimeoutHasChanges) {
buttons.push({
icon: 'check',
error: false,
handler (event) {
event.stopPropagation();
self.saveHuntTimeout();
}
}, {
icon: 'clear',
error: false,
handler (event) {
event.stopPropagation();
self.resetHuntTimeout();
}
}
);
}
return buttons;
},
aliasNumbersChanges() {
return !_.isEqual(this.changes.aliasNumbers.sort(),
this.numbersToIds(this.group.alias_numbers).sort());
},
aliasNumberButtons() {
let buttons = [];
let self = this;
if(this.aliasNumbersChanges) {
buttons.push({
icon: 'check',
error: false,
handler (event) {
event.stopPropagation();
self.saveAliasNumbers();
}
}, {
icon: 'clear',
error: false,
handler (event) {
event.stopPropagation();
self.resetAliasNumbers();
}
}
);
}
return buttons;
},
seatChanges() {
return !_.isEqual(this.changes.seats.sort(),
this.numbersToIds(this.group.seats).sort());
},
seatButtons() {
let buttons = [];
let self = this;
if(this.seatChanges) {
buttons.push({
icon: 'check',
error: false,
handler (event) {
event.stopPropagation();
self.saveSeats();
}
}, {
icon: 'clear',
error: false,
handler (event) {
event.stopPropagation();
self.resetSeats();
}
}
);
}
return buttons;
} }
}, },
methods: { methods: {
@ -171,6 +314,85 @@
}, },
remove() { remove() {
this.$emit('remove', this.groupModel); this.$emit('remove', this.groupModel);
},
resetName() {
this.changes.name = this.group.display_name;
},
saveName() {
this.$emit('save-name', this.groupModel);
},
resetExtension() {
this.changes.extension = this.group.pbx_extension;
},
saveExtension() {
this.$emit('save-extension', this.groupModel);
},
resetHuntPolicy() {
this.changes.huntPolicy = this.group.pbx_hunt_policy;
},
saveHuntPolicy() {
this.$emit('save-hunt-policy', this.groupModel);
},
resetHuntTimeout() {
this.changes.huntTimeout = this.group.pbx_hunt_timeout;
},
saveHuntTimeout() {
this.$emit('save-hunt-timeout', this.groupModel);
},
huntPolicyChanged() {
this.saveHuntPolicy();
},
numbersToIds(aliasNumbers) {
let numbers = [];
if(_.isArray(aliasNumbers)) {
aliasNumbers.forEach((number) => {
numbers.push(number.number_id);
});
}
return numbers;
},
resetAliasNumbers() {
this.changes.aliasNumbers = this.numbersToIds(this.group.alias_numbers);
},
saveAliasNumbers() {
var oldNumbers = this.numbersToIds(this.group.alias_numbers);
var numbersToAdd = _.difference(this.changes.aliasNumbers, oldNumbers);
var numbersToRemove = _.difference(oldNumbers, this.changes.aliasNumbers);
this.$emit('save-alias-numbers', {
group: this.groupModel,
add: numbersToAdd,
remove: numbersToRemove
});
},
getGroup() {
return {
name: this.group.display_name,
extension: this.group.pbx_extension,
huntPolicy: this.group.pbx_hunt_policy,
huntTimeout: this.group.pbx_hunt_timeout,
aliasNumbers: this.numbersToIds(this.group.alias_numbers),
seats: this.seatsToIds(this.group.seats)
}
},
seatsToIds(seats) {
let seatIds = [];
if(_.isArray(seats)) {
seats.forEach((seat) => {
seatIds.push(seat.id);
});
}
return seatIds;
},
resetSeats() {
this.changes.seats = this.seatsToIds(this.group.seats);
},
saveSeats() {
this.$emit('save-seats', this.groupModel);
},
},
watch: {
group() {
this.changes = this.getGroup()
} }
} }
} }

@ -45,19 +45,21 @@
<q-btn color="primary" icon="add" flat @click="enableGroupForm">{{ $t('pbxConfig.addGroup') }}</q-btn> <q-btn color="primary" icon="add" flat @click="enableGroupForm">{{ $t('pbxConfig.addGroup') }}</q-btn>
</q-card-actions> </q-card-actions>
</q-card> </q-card>
<q-card v-if="listIsRequesting && !removeGroupIsRequesting && !addGroupIsRequesting" flat> <q-card v-if="listIsRequesting && !listLoadingSilently" flat>
<q-card-actions align="center"> <q-card-actions align="center">
<q-spinner-dots color="primary" :size="40"/> <q-spinner-dots color="primary" :size="40"/>
</q-card-actions> </q-card-actions>
</q-card> </q-card>
<csc-pbx-group v-for="group in groups" :group="group" :alias-number-options="aliasNumberOptions" <csc-pbx-group v-for="group in groups" :key="group.id" :group="group" :alias-number-options="aliasNumberOptions"
:seat-options="seatOptions" :hunt-policy-options="huntPolicyOptions" @remove="removeGroup" :seat-options="seatOptions" :hunt-policy-options="huntPolicyOptions" @remove="removeGroup"
:loading="removeGroupIsRequesting && group.id == removeGroupId" /> :loading="isGroupUpdating(group.id)" @save-name="setGroupName" @save-extension="setGroupExtension"
@save-hunt-policy="setGroupHuntPolicy" @save-hunt-timeout="setGroupHuntTimeout"
@save-alias-numbers="updateAliasNumbers" @save-seats="updateSeats" />
</csc-page> </csc-page>
</template> </template>
<script> <script>
import { mapGetters } from 'vuex'
import { showGlobalError } from '../../../helpers/ui' import { showGlobalError } from '../../../helpers/ui'
import CscPage from '../../CscPage' import CscPage from '../../CscPage'
import CscPbxGroup from './CscPbxGroup' import CscPbxGroup from './CscPbxGroup'
@ -217,7 +219,13 @@
}, },
removeGroupId() { removeGroupId() {
return this.$store.state.pbxConfig.removeGroupItem.id; return this.$store.state.pbxConfig.removeGroupItem.id;
} },
...mapGetters('pbxConfig', [
'listItemUpdating',
'listItemUpdateState',
'listItemUpdateError',
'listLoadingSilently'
])
}, },
watch: { watch: {
addGroupState(state) { addGroupState(state) {
@ -232,9 +240,19 @@
if(state === 'failed') { if(state === 'failed') {
showGlobalError(this.removeGroupError); showGlobalError(this.removeGroupError);
} }
},
listItemUpdateState(state) {
if(state === 'failed') {
showGlobalError(this.listItemUpdateError);
}
} }
}, },
methods: { methods: {
isGroupUpdating(groupId) {
return this.listItemUpdateState === 'requesting' &&
this.listItemUpdating !== null &&
this.listItemUpdating.id === groupId;
},
resetGroupForm() { resetGroupForm() {
this.groupForm = { this.groupForm = {
name: '', name: '',
@ -273,6 +291,24 @@
} }
] ]
}); });
},
setGroupName(group) {
this.$store.dispatch('pbxConfig/setGroupName', group);
},
setGroupExtension(group) {
this.$store.dispatch('pbxConfig/setGroupExtension', group);
},
setGroupHuntPolicy(group) {
this.$store.dispatch('pbxConfig/setGroupHuntPolicy', group);
},
setGroupHuntTimeout(group) {
this.$store.dispatch('pbxConfig/setGroupHuntTimeout', group);
},
updateAliasNumbers(data) {
this.$store.dispatch('pbxConfig/updateAliasNumbers', data);
},
updateSeats(data) {
this.$store.dispatch('pbxConfig/updateSeats', data);
} }
} }
} }

@ -0,0 +1,24 @@
'use strict';
export const RequestState = {
requesting: 'requesting',
succeeded: 'succeeded',
failed: 'failed'
};
export const ListState = {
initiated: 'initiated',
requesting: 'requesting',
succeeded: 'succeeded',
failed: 'failed'
};
export const AddState = {
button: 'button',
input: 'input',
requesting: 'requesting',
succeeded: 'succeeded',
failed: 'failed'
};
export const RemoveState = ListState;

@ -7,7 +7,7 @@ import CallForwardModule from './call-forward'
import CallModule from './call' import CallModule from './call'
import ConversationsModule from './conversations' import ConversationsModule from './conversations'
import LayoutModule from './layout' import LayoutModule from './layout'
import PbxConfigModule from './pbx-config' import PbxConfigModule from './pbx-config/index'
import ReminderModule from './reminder' import ReminderModule from './reminder'
import UserModule from './user' import UserModule from './user'

@ -1,247 +0,0 @@
import _ from 'lodash';
import { getPbxConfiguration, addGroup,
removeGroup, addSeat, removeSeat } from '../api/pbx-config'
const ListState = {
initiated: 'initiated',
requesting: 'requesting',
succeeded: 'succeeded',
failed: 'failed'
};
const AddState = {
button: 'button',
input: 'input',
requesting: 'requesting',
succeeded: 'succeeded',
failed: 'failed'
};
const RemoveState = {
initiated: 'initiated',
requesting: 'requesting',
succeeded: 'succeeded',
failed: 'failed'
};
export default {
namespaced: true,
state: {
pilot: null,
groups: {},
groupsOrdered: [],
seats: {},
seatsOrdered: [],
numbers: [],
numbersMap : {},
listAllState: ListState.initiated,
listAllError: null,
addGroupState: AddState.button,
addGroupError: null,
removeGroupState: RemoveState.initiated,
removeGroupError: null,
removeGroupItem: null,
addSeatState: AddState.button,
addSeatError: null,
removeSeatState: RemoveState.initiated,
removeSeatError: null,
removeSeatItem: null
},
getters: {
groups(state) {
return state.groupsOrdered;
},
seats(state) {
return state.seatsOrdered;
},
numbers(state) {
return _.get(state, 'numbers', []);
},
primaryNumbers(state, getters) {
let numbers = getters.numbers;
let primaryNumbers = [];
if(_.isArray(numbers)) {
numbers.forEach((number)=>{
if(number.is_primary) {
primaryNumbers.push(number);
}
});
}
return primaryNumbers;
},
aliasNumbers(state, getters) {
let numbers = getters.numbers;
let aliasNumbers = [];
if(_.isArray(numbers) && numbers.length) {
numbers.forEach((number)=>{
if(!number.is_primary) {
aliasNumbers.push(number);
}
});
}
return aliasNumbers;
}
},
mutations: {
listAllRequesting(state) {
state.listAllState = ListState.requesting;
},
listAllSucceeded(state, all) {
state.RemoveState = RemoveState.initiated;
state.listAllState = ListState.succeeded;
state.listAllError = null;
state.pilot = all.pilot;
state.groups = {};
state.groupsOrdered = [];
state.seats = {};
state.seatsOrdered = [];
state.numbersMap = {};
all.groups.forEach((group)=>{
state.groups[group.id] = group;
state.groupsOrdered.push(group);
});
all.seats.forEach((seat)=>{
seat.pbx_group_ids.forEach((groupId)=>{
let group = state.groups[groupId];
let seats = _.get(group, 'seats', []);
seats.push(seat);
_.set(group, 'seats', seats);
let groups = _.get(seat, 'groups', []);
groups.push(group);
_.set(seat, 'groups', groups);
});
state.seats[seat.id] = seat;
state.seatsOrdered.push(seat);
});
if(_.isArray(all.numbers) && all.numbers.length > 0) {
all.numbers.forEach((number)=>{
if(_.has(state.groups, number.subscriber_id)) {
number.subscriber = state.groups[number.subscriber_id];
}
else if (_.has(state.seats, number.subscriber_id)) {
number.subscriber = state.seats[number.subscriber_id];
}
else if (state.pilot.id === number.subscriber_id) {
number.subscriber = state.pilot;
}
else {
number.subscriber = null;
}
state.numbersMap[number.id] = number;
});
state.numbers = all.numbers;
}
_.reverse(state.groupsOrdered);
_.reverse(state.seatsOrdered);
},
listAllFailed(state, error) {
state.listAllState = ListState.failed;
state.listAllError = error;
},
addGroupRequesting(state){
state.addGroupState = AddState.requesting;
state.addGroupError = null;
},
addGroupSucceeded(state){
state.addGroupState = AddState.succeeded;
state.addGroupError = null;
},
addGroupFailed(state, error) {
state.addGroupState = AddState.failed;
state.addGroupError = error;
},
removeGroupRequesting(state, group) {
state.removeGroupState = RemoveState.requesting;
state.removeGroupError = null;
state.removeGroupItem = group;
},
removeGroupSucceeded(state) {
state.removeGroupState = RemoveState.succeeded;
state.removeGroupError = null;
},
removeGroupFailed(state, message) {
state.removeGroupState = RemoveState.failed;
state.removeGroupError = message;
},
addSeatRequesting(state){
state.addSeatState = AddState.requesting;
state.addSeatError = null;
},
addSeatSucceeded(state){
state.addSeatState = AddState.succeeded;
state.addSeatError = null;
},
addSeatFailed(state, error) {
state.addSeatState = AddState.failed;
state.addSeatError = error;
},
removeSeatRequesting(state, seat) {
state.removeSeatState = RemoveState.requesting;
state.removeSeatError = null;
state.removeSeatItem = seat;
},
removeSeatSucceeded(state) {
state.removeSeatState = RemoveState.succeeded;
state.removeSeatError = null;
},
removeSeatFailed(state, message) {
state.removeSeatState = RemoveState.failed;
state.removeSeatError = message;
state.removeSeatItem = null;
},
},
actions: {
listSeats(context) {
return context.dispatch('listGroups');
},
listGroups(context) {
context.commit('listAllRequesting');
getPbxConfiguration().then((config)=>{
context.commit('listAllSucceeded', config);
}).catch((err)=>{
context.commit('listAllFailed', err.message);
});
},
addGroup(context, group) {
context.commit('addGroupRequesting');
group.customerId = context.state.pilot.customer_id;
group.domainId = context.state.pilot.domain_id;
addGroup(group).then(()=>{
context.commit('addGroupSucceeded');
context.dispatch('listGroups');
}).catch((err)=>{
context.commit('addGroupFailed', err.message);
});
},
removeGroup(context, group) {
context.commit('removeGroupRequesting', group);
removeGroup(group.id).then(()=>{
context.commit('removeGroupSucceeded');
context.dispatch('listGroups');
}).catch((err)=>{
context.commit('removeGroupFailed', err.message);
});
},
addSeat(context, seat) {
seat.customerId = context.state.pilot.customer_id;
seat.domainId = context.state.pilot.domain_id;
context.commit('addSeatRequesting', seat);
addSeat(seat).then(()=>{
context.commit('addSeatSucceeded', seat);
context.dispatch('listGroups');
}).catch((err)=>{
context.commit('addSeatFailed', err.message);
});
},
removeSeat(context, seat) {
context.commit('removeSeatRequesting', seat);
removeSeat(seat.id).then(()=>{
context.commit('removeSeatSucceeded');
context.dispatch('listGroups');
}).catch((err)=>{
context.commit('removeSeatFailed', err.message);
});
}
}
};

@ -0,0 +1,130 @@
'use strict';
import { assignNumbers } from '../../api/user';
import { getPbxConfiguration, addGroup,
removeGroup, addSeat, removeSeat, setGroupName,
setGroupExtension, setGroupHuntPolicy, setGroupHuntTimeout, updateGroupSeats } from '../../api/pbx-config'
export default {
listSeats(context, silent) {
return context.dispatch('listGroups', silent);
},
listGroups(context, silent) {
return new Promise((resolve, reject)=>{
context.commit('listAllRequesting', silent);
getPbxConfiguration().then((config)=>{
context.commit('listAllSucceeded', config);
resolve();
}).catch((err)=>{
context.commit('listAllFailed', err.message);
reject(err);
});
});
},
addGroup(context, group) {
context.commit('addGroupRequesting');
group.customerId = context.state.pilot.customer_id;
group.domainId = context.state.pilot.domain_id;
addGroup(group).then(()=>{
return context.dispatch('listGroups', true);
}).then(()=>{
context.commit('addGroupSucceeded');
}).catch((err)=>{
context.commit('addGroupFailed', err.message);
});
},
removeGroup(context, group) {
context.commit('updateListItemStarted', group);
removeGroup(group.id).then(()=>{
return context.dispatch('listGroups', true);
}).then(()=>{
context.commit('removeGroup', group);
context.commit('updateListItemSucceeded');
}).catch((err)=>{
context.commit('updateListItemFailed', err.message);
});
},
addSeat(context, seat) {
seat.customerId = context.state.pilot.customer_id;
seat.domainId = context.state.pilot.domain_id;
context.commit('addSeatRequesting', seat);
addSeat(seat).then(()=>{
context.commit('addSeatSucceeded', seat);
context.dispatch('listSeats', true);
}).catch((err)=>{
context.commit('addSeatFailed', err.message);
});
},
removeSeat(context, seat) {
context.commit('removeSeatRequesting', seat);
removeSeat(seat.id).then(()=>{
context.commit('removeSeatSucceeded');
context.dispatch('listSeats', true);
}).catch((err)=>{
context.commit('removeSeatFailed', err.message);
});
},
setGroupName(context, group) {
context.commit('updateListItemStarted', group);
setGroupName(group.id, group.name).then(() => {
return context.dispatch('listGroups', true);
}).then(()=>{
context.commit('updateListItemSucceeded');
}).catch((err) => {
context.commit('updateListItemFailed', err.message);
});
},
setGroupExtension(context, group) {
context.commit('updateListItemStarted', group);
setGroupExtension(group.id, group.extension).then(()=>{
return context.dispatch('listGroups', true);
}).then(() => {
context.commit('updateListItemSucceeded');
}).catch((err) => {
context.commit('updateListItemFailed', err.message);
});
},
setGroupHuntPolicy(context, group) {
context.commit('updateListItemStarted', group);
setGroupHuntPolicy(group.id, group.huntPolicy).then(() => {
return context.dispatch('listGroups', true);
}).then(()=>{
context.commit('updateListItemSucceeded');
}).catch((err) => {
context.commit('updateListItemFailed', err.message);
});
},
setGroupHuntTimeout(context, group) {
context.commit('updateListItemStarted', group);
setGroupHuntTimeout(group.id, group.huntTimeout).then(()=>{
return context.dispatch('listGroups', true);
}).then(() => {
context.commit('updateListItemSucceeded');
}).catch((err) => {
context.commit('updateListItemFailed', err.message);
});
},
updateAliasNumbers(context, data) {
context.commit('updateListItemStarted', data.group);
Promise.all([
assignNumbers(data.add, data.group.id),
assignNumbers(data.remove, context.getters.pilotId)
]).then(()=>{
return context.dispatch('listGroups', true);
}).then(()=>{
context.commit('updateListItemSucceeded');
}).catch((err)=>{
context.commit('updateListItemFailed', err.message);
});
},
updateSeats(context, group) {
context.commit('updateListItemStarted', group);
updateGroupSeats(group.id, group.seats).then(()=>{
return context.dispatch('listGroups', true);
}).then(() => {
context.commit('updateListItemSucceeded');
}).catch((err) => {
context.commit('updateListItemFailed', err.message);
});
}
}

@ -0,0 +1,54 @@
'use strict';
import _ from 'lodash'
export default {
groups(state) {
return state.groupsOrdered;
},
seats(state) {
return state.seatsOrdered;
},
numbers(state) {
return _.get(state, 'numbers', []);
},
primaryNumbers(state, getters) {
let numbers = getters.numbers;
let primaryNumbers = [];
if(_.isArray(numbers)) {
numbers.forEach((number)=>{
if(number.is_primary) {
primaryNumbers.push(number);
}
});
}
return primaryNumbers;
},
aliasNumbers(state, getters) {
let numbers = getters.numbers;
let aliasNumbers = [];
if(_.isArray(numbers) && numbers.length) {
numbers.forEach((number)=>{
if(!number.is_primary) {
aliasNumbers.push(number);
}
});
}
return aliasNumbers;
},
listItemUpdating(state) {
return state.listItemUpdating;
},
listItemUpdateState(state) {
return state.listItemUpdateState;
},
listItemUpdateError(state) {
return state.listItemUpdateError;
},
listLoadingSilently(state) {
return (state.listLoadingSilently === true);
},
pilotId(state) {
return state.pilot.id;
}
}

@ -0,0 +1,13 @@
import state from './state'
import getters from './getters'
import mutations from './mutations'
import actions from './actions'
export default {
namespaced: true,
state: state,
getters: getters,
mutations: mutations,
actions: actions
};

@ -0,0 +1,121 @@
'use strict';
import _ from 'lodash'
import { ListState, AddState, RemoveState } from '../common'
export default {
listAllRequesting(state, silent) {
state.listAllState = ListState.requesting;
state.listLoadingSilently = silent;
},
listAllSucceeded(state, all) {
state.listAllState = ListState.succeeded;
state.listAllError = null;
state.pilot = all.pilot;
state.groups = {};
state.groupsOrdered = [];
state.seats = {};
state.seatsOrdered = [];
state.numbersMap = {};
all.groups.forEach((group)=>{
state.groups[group.id] = group;
state.groupsOrdered.push(group);
});
all.seats.forEach((seat)=>{
seat.pbx_group_ids.forEach((groupId)=>{
let group = state.groups[groupId];
let seats = _.get(group, 'seats', []);
seats.push(seat);
_.set(group, 'seats', seats);
let groups = _.get(seat, 'groups', []);
groups.push(group);
_.set(seat, 'groups', groups);
});
state.seats[seat.id] = seat;
state.seatsOrdered.push(seat);
});
if(_.isArray(all.numbers) && all.numbers.length > 0) {
all.numbers.forEach((number)=>{
if(_.has(state.groups, number.subscriber_id)) {
number.subscriber = state.groups[number.subscriber_id];
}
else if (_.has(state.seats, number.subscriber_id)) {
number.subscriber = state.seats[number.subscriber_id];
}
else if (state.pilot.id === number.subscriber_id) {
number.subscriber = state.pilot;
}
else {
number.subscriber = null;
}
state.numbersMap[number.id] = number;
});
state.numbers = all.numbers;
}
_.reverse(state.groupsOrdered);
_.reverse(state.seatsOrdered);
},
listAllFailed(state, error) {
state.listAllState = ListState.failed;
state.listAllError = error;
},
addGroupRequesting(state){
state.addGroupState = AddState.requesting;
state.addGroupError = null;
},
addGroupSucceeded(state){
state.addGroupState = AddState.succeeded;
state.addGroupError = null;
},
addGroupFailed(state, error) {
state.addGroupState = AddState.failed;
state.addGroupError = error;
},
removeGroup(state, group) {
delete state.groups[group.id];
state.groupsOrdered.forEach(($group, index)=>{
if(group.id === $group.id) {
delete state.groupsOrdered[index];
}
});
},
addSeatRequesting(state){
state.addSeatState = AddState.requesting;
state.addSeatError = null;
},
addSeatSucceeded(state){
state.addSeatState = AddState.succeeded;
state.addSeatError = null;
},
addSeatFailed(state, error) {
state.addSeatState = AddState.failed;
state.addSeatError = error;
},
removeSeatRequesting(state, seat) {
state.removeSeatState = RemoveState.requesting;
state.removeSeatError = null;
state.removeSeatItem = seat;
},
removeSeatSucceeded(state) {
state.removeSeatState = RemoveState.succeeded;
state.removeSeatError = null;
},
removeSeatFailed(state, message) {
state.removeSeatState = RemoveState.failed;
state.removeSeatError = message;
state.removeSeatItem = null;
},
updateListItemStarted(state, item) {
state.listItemUpdateState = 'requesting';
state.listItemUpdating = item;
},
updateListItemSucceeded(state) {
state.listItemUpdateState = 'succeeded';
state.listItemUpdating = null;
},
updateListItemFailed(state, error) {
state.listItemUpdateState = 'failed';
state.listItemUpdating = null;
state.listItemUpdateError = error;
}
}

@ -0,0 +1,26 @@
'use strict';
import { ListState, AddState, RemoveState } from '../common'
export default {
pilot: null,
groups: {},
groupsOrdered: [],
seats: {},
seatsOrdered: [],
numbers: [],
numbersMap : {},
listAllState: ListState.initiated,
listAllError: null,
listLoadingSilently: false,
addGroupState: AddState.button,
addGroupError: null,
addSeatState: AddState.button,
addSeatError: null,
removeSeatState: RemoveState.initiated,
removeSeatError: null,
removeSeatItem: null,
listItemUpdating: null,
listItemUpdateState: null,
listItemUpdateError: null
}
Loading…
Cancel
Save