TT#20511 PBXConfig: As a Customer, I want to remove PBX Groups

Change-Id: Iaaab318c929ba8e1177a36b8e54e490ac34d292f
changes/53/18253/5
Hans-Peter Herzog 8 years ago
parent 508e8701e3
commit 3463789805

@ -2,7 +2,7 @@
import Vue from 'vue'; import Vue from 'vue';
import { getJsonBody } from './utils'; import { getJsonBody } from './utils';
import { getNumbers, assignNumber, assignNumbers } from './user'; import { getNumbers, assignNumber, assignNumbers } from './user';
import { createSubscriber } from './subscriber'; import { createSubscriber, deleteSubscriber } from './subscriber';
var assumedRows = 1000; var assumedRows = 1000;
@ -88,7 +88,7 @@ export function addGroup(group) {
pbx_groupmember_ids: group.seats pbx_groupmember_ids: group.seats
}); });
}).then((subscriberId)=>{ }).then((subscriberId)=>{
return assignNumbers(group.aliasNumbers, subscriberId); assignNumbers(group.aliasNumbers, subscriberId);
}).then(()=>{ }).then(()=>{
resolve(); resolve();
}).catch((err)=>{ }).catch((err)=>{
@ -97,8 +97,6 @@ export function addGroup(group) {
}); });
} }
export function deleteGroup(id) { export function removeGroup(id) {
return new Promise((resolve, reject)=>{ return deleteSubscriber(id);
});
} }

@ -198,17 +198,16 @@ export function createSubscriber(subscriber) {
}); });
} }
// export function deleteSubscriber(id) { export function deleteSubscriber(id) {
// return new Promise((resolve, reject)=>{ return new Promise((resolve, reject)=>{
// Vue.http.delete('/api/subscribers/', null, { Vue.http.delete('/api/subscribers/' + id).then((res)=>{
// }).then((res)=>{ resolve();
// resolve(_.last(_.split(res.headers.get('Location'), '/'))); }).catch((err)=>{
// }).catch((err)=>{ if(err.status === 422) {
// if(err.status === 422) { reject(new Error(err.body.message));
// reject(new Error(err.body.message)); } else {
// } else { reject(err);
// reject(err); }
// } });
// }); });
// }); }
// }

@ -101,7 +101,7 @@ export function assignNumbers(numberIds, subscriberId) {
reject(err); reject(err);
}); });
} else { } else {
reject(new Error('No numberIds given')); resolve();
} }
}); });
} }

@ -30,8 +30,13 @@
<q-select v-model="seats" :options="seatOptions" multiple chips readonly clearable /> <q-select v-model="seats" :options="seatOptions" multiple chips readonly clearable />
</q-field> </q-field>
</q-card-main> </q-card-main>
<q-card-actions> <q-card-actions align="center">
<q-btn :loader="isLoading" v-model="isLoading" flat round
color="negative" icon="delete" @click="remove()">Delete</q-btn>
</q-card-actions> </q-card-actions>
<q-inner-loading :visible="isLoading">
<q-spinner-mat size="60px" color="primary"></q-spinner-mat>
</q-inner-loading>
</q-card> </q-card>
</template> </template>
@ -47,7 +52,10 @@
QInput, QInput,
QIcon, QIcon,
QSelect, QSelect,
QChip QChip,
QBtn,
QInnerLoading,
QSpinnerMat
} from 'quasar-framework' } from 'quasar-framework'
export default { export default {
name: 'csc-pbx-group', name: 'csc-pbx-group',
@ -55,6 +63,7 @@
'huntPolicyOptions', 'huntPolicyOptions',
'aliasNumberOptions', 'aliasNumberOptions',
'seatOptions', 'seatOptions',
'loading'
], ],
data () { data () {
return {} return {}
@ -68,9 +77,15 @@
QInput, QInput,
QIcon, QIcon,
QSelect, QSelect,
QChip QChip,
QBtn,
QInnerLoading,
QSpinnerMat
}, },
computed: { computed: {
id() {
return this.group.id;
},
name() { name() {
return this.group.display_name; return this.group.display_name;
}, },
@ -103,12 +118,42 @@
}); });
} }
return seats; return seats;
},
groupModel() {
return {
id: this.id,
name: this.name,
extension: this.extension,
huntPolicy: this.huntPolicy,
huntTimeout: this.huntTimeout,
primaryNumber: this.primaryNumber,
aliasNumbers: this.aliasNumbers,
seats: this.seats
}
},
isLoading() {
return this.loading;
},
cardClasses() {
var cardClasses = ['csc-pbx-group'];
if(this.isLoading) {
cardClasses.push('light-dimmed');
}
return cardClasses;
}
},
methods: {
remove() {
this.$emit('remove', this.groupModel);
} }
} }
} }
</script> </script>
<style> <style>
.csc-pbx-group {
position: relative;
}
.csc-pbx-group .csc-pbx-group-title { .csc-pbx-group .csc-pbx-group-title {
padding-left: 8px; padding-left: 8px;
} }

@ -0,0 +1,131 @@
<template>
<q-card class="csc-pbx-group-add-form">
<q-card-title>
<q-icon name="add" color="primary" size="22px"/>
<span>Add Group</span>
</q-card-title>
<q-card-main>
<q-field>
<q-input :disabled="addGroupIsRequesting" ref="groupName" v-model="groupForm.name" autofocus
:float-label="$t('pbxConfig.groupName')" clearable />
</q-field>
<q-field>
<q-input :disabled="addGroupIsRequesting" type="number" v-model="groupForm.extension" clearable min="1" max="1000000"
:float-label="$t('pbxConfig.extension')" />
</q-field>
<q-field>
<q-select :disabled="addGroupIsRequesting" v-model="groupForm.huntPolicy" :float-label="$t('pbxConfig.huntPolicy')"
:options="huntPolicyOptions" radio />
</q-field>
<q-field >
<q-input :disabled="addGroupIsRequesting" type="number" v-model="groupForm.huntTimeout" :float-label="$t('pbxConfig.huntTimeout')"
suffix="seconds" min="1" max="3600" clearable />
</q-field>
<q-field>
<q-select :disabled="addGroupIsRequesting" v-model="groupForm.aliasNumbers" :float-label="$t('pbxConfig.aliasNumbers')"
:options="aliasNumberOptions" multiple chips readonly clearable />
</q-field>
<q-field>
<q-select :disabled="addGroupIsRequesting" v-model="groupForm.seats" :float-label="$t('pbxConfig.seats')"
:options="seatOptions" multiple chips readonly clearable />
</q-field>
</q-card-main>
<q-card-separator/>
<q-card-actions align="center">
<q-btn v-if="!addGroupIsRequesting" flat color="secondary" icon="clear" @click="disableGroupForm()">{{ $t('buttons.cancel') }}</q-btn>
<q-btn loader v-model="addGroupIsRequesting" flat color="primary" icon="done" @click="addGroup()">{{ $t('buttons.save') }}</q-btn>
</q-card-actions>
<q-inner-loading :visible="addGroupIsRequesting">
<q-spinner-mat size="60px" color="primary"></q-spinner-mat>
</q-inner-loading>
</q-card>
</template>
<script>
import { startLoading, stopLoading, showGlobalError, showToast } from '../../../helpers/ui'
import CscPage from '../../CscPage'
import CscPbxGroup from './CscPbxGroup'
import {
QChip,
QCard,
QCardSeparator,
QCardTitle,
QCardMain,
QCardActions,
QIcon,
QPopover,
QList,
QItem,
QItemMain,
QField,
QInput,
QBtn,
QSelect,
QInnerLoading,
QSpinnerDots,
QSpinnerMat,
Dialog
} from 'quasar-framework'
import { mapState } from 'vuex'
import numberFilter from '../../../filters/number'
export default {
components: {
CscPage,
QChip,
QCard,
QCardSeparator,
QCardTitle,
QCardMain,
QCardActions,
QIcon,
QPopover,
QList,
QItem,
QItemMain,
QField,
QInput,
CscPbxGroup,
QBtn,
QSelect,
QInnerLoading,
QSpinnerDots,
QSpinnerMat,
Dialog
},
data () {
return {
group: {
name: '',
extension: '',
huntPolicy: 'serial',
huntTimeout: 10,
aliasNumbers: [],
seats: []
},
}
},
computed: {
},
methods: {
save() {
},
cancel() {
}
}
}
</script>
<style lang="stylus">
@import '../../../../src/themes/app.variables.styl';
.add-form {
position: relative;
}
.add-form .q-field:last-child {
margin-bottom: 36px;
}
</style>

@ -36,21 +36,23 @@
<q-btn v-if="!addGroupIsRequesting" flat color="secondary" icon="clear" @click="disableGroupForm()">{{ $t('buttons.cancel') }}</q-btn> <q-btn v-if="!addGroupIsRequesting" flat color="secondary" icon="clear" @click="disableGroupForm()">{{ $t('buttons.cancel') }}</q-btn>
<q-btn loader v-model="addGroupIsRequesting" flat color="primary" icon="done" @click="addGroup()">{{ $t('buttons.save') }}</q-btn> <q-btn loader v-model="addGroupIsRequesting" flat color="primary" icon="done" @click="addGroup()">{{ $t('buttons.save') }}</q-btn>
</q-card-actions> </q-card-actions>
<q-inner-loading :visible="addGroupIsRequesting">
<q-spinner-mat size="60px" color="primary"></q-spinner-mat>
</q-inner-loading>
</q-card> </q-card>
<q-card v-else flat> <q-card v-else flat>
<q-card-actions align="center"> <q-card-actions align="center">
<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" flat> <q-card v-if="listIsRequesting && !removeGroupIsRequesting && !addGroupIsRequesting" 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" :all-seats="seats" <csc-pbx-group v-for="group in groups" :group="group" :alias-number-options="aliasNumberOptions"
:all-alias-numbers="aliasNumbers" :all-primary-numbers="primaryNumbers" :seat-options="seatOptions" :hunt-policy-options="huntPolicyOptions" @remove="removeGroup"
:alias-number-options="aliasNumberOptions" :seat-options="seatOptions" :loading="removeGroupIsRequesting && group.id == removeGroupId" />
:hunt-policy-options="huntPolicyOptions"/>
</csc-page> </csc-page>
</template> </template>
@ -76,8 +78,9 @@
QBtn, QBtn,
QSelect, QSelect,
QInnerLoading, QInnerLoading,
QSpinnerGears, QSpinnerDots,
QSpinnerDots QSpinnerMat,
Dialog
} from 'quasar-framework' } from 'quasar-framework'
import { mapState } from 'vuex' import { mapState } from 'vuex'
import numberFilter from '../../../filters/number' import numberFilter from '../../../filters/number'
@ -102,8 +105,9 @@
QBtn, QBtn,
QSelect, QSelect,
QInnerLoading, QInnerLoading,
QSpinnerGears, QSpinnerDots,
QSpinnerDots QSpinnerMat,
Dialog
}, },
mounted() { mounted() {
this.$store.dispatch('pbxConfig/listGroups'); this.$store.dispatch('pbxConfig/listGroups');
@ -203,6 +207,16 @@
}, },
addGroupError() { addGroupError() {
return this.$store.state.pbxConfig.addGroupError; return this.$store.state.pbxConfig.addGroupError;
},
removeGroupState() {
return this.$store.state.pbxConfig.removeGroupState;
},
removeGroupIsRequesting() {
return this.removeGroupState === 'requesting' ||
this.removeGroupState === 'succeeded';
},
removeGroupId() {
return this.$store.state.pbxConfig.removeGroupItem.id;
} }
}, },
watch: { watch: {
@ -213,6 +227,11 @@
if(state === 'succeeded') { if(state === 'succeeded') {
this.disableGroupForm(); this.disableGroupForm();
} }
},
removeGroupState(state) {
if(state === 'failed') {
showGlobalError(this.removeGroupError);
}
} }
}, },
methods: { methods: {
@ -236,6 +255,25 @@
}, },
addGroup() { addGroup() {
this.$store.dispatch('pbxConfig/addGroup', this.groupForm); this.$store.dispatch('pbxConfig/addGroup', this.groupForm);
},
removeGroup(group) {
var store = this.$store;
var state = this;
var i18n = this.$i18n;
Dialog.create({
title: i18n.t('pbxConfig.removeGroupTitle'),
message: i18n.t('pbxConfig.removeGroupText', { group: group.name }),
buttons: [
'Cancel',
{
label: i18n.t('pbxConfig.removeGroup'),
color: 'negative',
handler () {
store.dispatch('pbxConfig/removeGroup', group);
}
}
]
});
} }
} }
} }
@ -243,6 +281,9 @@
<style lang="stylus"> <style lang="stylus">
@import '../../../../src/themes/app.variables.styl'; @import '../../../../src/themes/app.variables.styl';
.add-form {
position: relative;
}
.add-form .q-field:last-child { .add-form .q-field:last-child {
margin-bottom: 36px; margin-bottom: 36px;
} }

@ -177,6 +177,9 @@
"circularRinging": "Circular Ringing", "circularRinging": "Circular Ringing",
"allocatedByNobody": "Free", "allocatedByNobody": "Free",
"allocatedBy": "Allocated by {type} {name}", "allocatedBy": "Allocated by {type} {name}",
"addGroup": "Add Group" "addGroup": "Add Group",
"removeGroup": "Remove",
"removeGroupTitle": "Remove group",
"removeGroupText": "You are about to remove group \"{group}\""
} }
} }

@ -1,6 +1,6 @@
import _ from 'lodash'; import _ from 'lodash';
import { getPbxConfiguration, addGroup } from '../api/pbx-config' import { getPbxConfiguration, addGroup, removeGroup } from '../api/pbx-config'
const ListState = { const ListState = {
initiated: 'initiated', initiated: 'initiated',
@ -17,6 +17,13 @@ const AddGroupState = {
failed: 'failed' failed: 'failed'
}; };
const RemoveGroupState = {
initiated: 'initiated',
requesting: 'requesting',
succeeded: 'succeeded',
failed: 'failed'
};
export default { export default {
namespaced: true, namespaced: true,
state: { state: {
@ -30,7 +37,10 @@ export default {
listAllState: ListState.initiated, listAllState: ListState.initiated,
listAllError: null, listAllError: null,
addGroupState: AddGroupState.button, addGroupState: AddGroupState.button,
addGroupError: null addGroupError: null,
removeGroupState: RemoveGroupState.initiated,
removeGroupError: null,
removeGroupItem: null
}, },
getters: { getters: {
groups(state, getters) { groups(state, getters) {
@ -72,6 +82,7 @@ export default {
state.listAllState = ListState.requesting; state.listAllState = ListState.requesting;
}, },
listAllSucceeded(state, all) { listAllSucceeded(state, all) {
state.removeGroupState = RemoveGroupState.initiated;
state.listAllState = ListState.succeeded; state.listAllState = ListState.succeeded;
state.listAllError = null; state.listAllError = null;
state.pilot = all.pilot; state.pilot = all.pilot;
@ -130,6 +141,19 @@ export default {
addGroupFailed(state, error) { addGroupFailed(state, error) {
state.addGroupState = AddGroupState.failed; state.addGroupState = AddGroupState.failed;
state.addGroupError = error; state.addGroupError = error;
},
removeGroupRequesting(state, group) {
state.removeGroupState = RemoveGroupState.requesting;
state.removeGroupError = null;
state.removeGroupItem = group;
},
removeGroupSucceeded(state) {
state.removeGroupState = RemoveGroupState.succeeded;
state.removeGroupError = null;
},
removeGroupFailed(state, message) {
state.removeGroupState = RemoveGroupState.failed;
state.removeGroupError = message;
} }
}, },
actions: { actions: {
@ -154,6 +178,15 @@ export default {
}).catch((err)=>{ }).catch((err)=>{
context.commit('addGroupFailed', err.message); 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);
});
} }
} }
}; };

Loading…
Cancel
Save