diff --git a/src/api/pbx-config.js b/src/api/pbx-config.js index 54ec2c66..1ebb4066 100644 --- a/src/api/pbx-config.js +++ b/src/api/pbx-config.js @@ -51,8 +51,7 @@ export function getAllGroupsAndSeats(options) { options = options || {}; options = _.merge(options, { params: { - all: true, - is_pbx_pilot: 0 + all: true } }); getSubscribers(options).then((res)=>{ @@ -188,25 +187,27 @@ export function getSeatList(page) { }); } -export function getDeviceList(page) { - return getDevices({ - params: { - page: page, +export function getDeviceList(options) { + return new Promise((resolve, reject)=>{ + let params = { + page: options.page, + profile_id: options.profile_id, order_by: PBX_CONFIG_ORDER_BY, order_by_direction: PBX_CONFIG_ORDER_DIRECTION + }; + if(params.profile_id === null) { + delete params['profile_id']; } + return getDevices({ + params: params + }).then((devices)=>{ + resolve(devices); + }).catch((err)=>{ + reject(err); + }); }); } -export function filterDeviceList(params) { - let defaultParams = { - order_by: PBX_CONFIG_ORDER_BY, - order_by_direction: PBX_CONFIG_ORDER_DIRECTION - }; - let mergedParams = _.merge(defaultParams, params); - return getDevices({ params: mergedParams }); -} - export function addGroup(group) { return new Promise((resolve, reject)=>{ Promise.resolve().then(()=>{ @@ -352,18 +353,15 @@ export function getProfile(id, join) { }).then(($profile)=> { profile = $profile; if(join === true) { - return Promise.all([ - getModel(profile.device_id), - getModelFrontImage(profile.device_id) - ]); + return getModelFull(profile.device_id); } else { resolve(profile); } - }).then((res)=>{ - profile.model = res[0]; - profile.modelFrontImage = res[1]; - profile.modelFrontImageUrl = URL.createObjectURL(profile.modelFrontImage); + }).then((model)=>{ + profile.model = model; + profile.modelFrontImage = model.frontImageBlob; + profile.modelFrontImageUrl = model.frontImageUrl; resolve(profile); }).catch((err)=>{ reject(err); @@ -393,13 +391,48 @@ export function getModelFrontImage(id) { type: 'front' } }).then((res)=>{ - resolve(res.body); + resolve({ + id: id, + url: URL.createObjectURL(res.body), + blob: res.body + }); }).catch((err)=>{ reject(err); }); }); } +export function getModelFull(id) { + return new Promise((resolve, reject)=>{ + Promise.all([ + getModel(id), + getModelFrontImage(id) + ]).then((res)=>{ + let model = res[0]; + model.frontImageBlob = res[1].blob; + model.frontImageUrl = res[1].url; + resolve(model); + }).catch((err)=>{ + reject(err); + }); + }); +} + +export function createDevice(device) { + return new Promise((resolve, reject)=>{ + Vue.http.post('api/pbxdevices/', device).then((res)=>{ + resolve(res); + }).catch((err)=>{ + if(err.status >= 400) { + reject(new Error(err.body.message)); + } + else { + reject(err); + } + }); + }); +} + export function removeDevice(id) { return new Promise((resolve, reject)=>{ Vue.http.delete('api/pbxdevices/' + id).then(()=>{ diff --git a/src/components/pages/Conversations/CscVoicemailPlayer.vue b/src/components/pages/Conversations/CscVoicemailPlayer.vue index 474f565a..5e7463bf 100644 --- a/src/components/pages/Conversations/CscVoicemailPlayer.vue +++ b/src/components/pages/Conversations/CscVoicemailPlayer.vue @@ -58,7 +58,6 @@ }, isLoading() { let getter = this.playVoiceMailState; - //console.log(getter(this.id)); return getter(this.id) === 'requesting'; }, ...mapGetters('conversations', [ diff --git a/src/components/pages/PbxConfiguration/CscPbxDeviceAddForm.vue b/src/components/pages/PbxConfiguration/CscPbxDeviceAddForm.vue new file mode 100644 index 00000000..295c3afe --- /dev/null +++ b/src/components/pages/PbxConfiguration/CscPbxDeviceAddForm.vue @@ -0,0 +1,95 @@ + + + + + diff --git a/src/components/pages/PbxConfiguration/CscPbxDeviceConfig.vue b/src/components/pages/PbxConfiguration/CscPbxDeviceConfig.vue index 8f8fc4f2..dfca7ecb 100644 --- a/src/components/pages/PbxConfiguration/CscPbxDeviceConfig.vue +++ b/src/components/pages/PbxConfiguration/CscPbxDeviceConfig.vue @@ -71,7 +71,10 @@ selectedKeyIcon() { if(this.selectedLine !== null) { let subscriber = this.subscribers(this.selectedLine.subscriber_id); - if(subscriber !== null && subscriber.is_pbx_group === true) { + if(subscriber !== null && subscriber.is_pbx_pilot === true) { + return 'person_outlined'; + } + else if(subscriber !== null && subscriber.is_pbx_group === true) { return 'group'; } else if (subscriber !== null){ @@ -86,7 +89,10 @@ selectedKeyLabel() { if(this.selectedLine !== null) { let subscriber = this.subscribers(this.selectedLine.subscriber_id); - if(subscriber !== null && subscriber.is_pbx_group === true) { + if(subscriber !== null && subscriber.is_pbx_pilot === true) { + return this.$t('pbxConfig.keyPilotLabel'); + } + else if(subscriber !== null && subscriber.is_pbx_group === true) { return this.$t('pbxConfig.keyGroupLabel'); } else if (subscriber !== null){ @@ -328,7 +334,7 @@ type: line.type }); }); - if(changed === true && newLines.length > 0) { + if(changed === true) { this.$emit('keysChanged', newLines); } }, diff --git a/src/components/pages/PbxConfiguration/CscPbxDevices.vue b/src/components/pages/PbxConfiguration/CscPbxDevices.vue index ddedcc7d..0fc85fd5 100644 --- a/src/components/pages/PbxConfiguration/CscPbxDevices.vue +++ b/src/components/pages/PbxConfiguration/CscPbxDevices.vue @@ -3,51 +3,60 @@ :title="$t('pbxConfig.devicesTitle')" class="csc-list-page" > - -
- -
-
- -
- - + + + +
+ +
+
+ +
+
+ +
+
+
+ + + + + + + + + + + {{ profile.name }} + + + + +
+
+ +
+
+ + + + + diff --git a/src/helpers/store-helper.js b/src/helpers/store-helper.js new file mode 100644 index 00000000..4296d7b6 --- /dev/null +++ b/src/helpers/store-helper.js @@ -0,0 +1,11 @@ + +import Vue from 'vue' + +export function reactiveSet(object, name, value) { + Vue.delete(object, name); + Vue.set(object, name, value); +} + +export function reactiveDelete(object, name) { + Vue.delete(object, name); +} diff --git a/src/locales/en.json b/src/locales/en.json index 63bc5705..7b10dd21 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -294,7 +294,8 @@ "addedSeatToast": "Added seat {seat}", "removedSeatToast": "Removed seat {seat}", "removedDeviceToast": "Removed device {name}", - "updatedDeviceKeys": "Updated keys of device {name}" + "updatedDeviceKeys": "Updated keys of device {name}", + "createdDevice": "Created device {name} successfully" }, "removeDevice": "Remove device", "removeDeviceTitle": "Remove device", @@ -302,7 +303,8 @@ "keyEmptyLabel": "Unassigned", "keyGroupLabel": "Group", "keySeatLabel": "Seat", - "keyBothLabel": "Group/Seat", + "keyPilotLabel": "Pilot", + "keyBothLabel": "Group/Seat/Pilot", "keyTypeShared": "Shared", "keyTypeBLF": "Busy Lamp Field", "keyTypePrivate": "Private", diff --git a/src/store/pbx-config/actions.js b/src/store/pbx-config/actions.js index 5d2e30fb..2aafb752 100644 --- a/src/store/pbx-config/actions.js +++ b/src/store/pbx-config/actions.js @@ -3,10 +3,25 @@ import _ from 'lodash'; import { assignNumbers } from '../../api/user'; import { addGroup, removeGroup, addSeat, removeSeat, setGroupName, - setGroupExtension, setGroupHuntPolicy, setGroupHuntTimeout, updateDeviceKeys, - updateGroupSeats, setSeatName, setSeatExtension, removeDevice, getAllGroupsAndSeats, - updateSeatGroups, getGroupList, getSeatList, getDeviceList, filterDeviceList, - getProfiles, getDevice } from '../../api/pbx-config' + + setGroupExtension, + setGroupHuntPolicy, + setGroupHuntTimeout, + createDevice, + removeDevice, + updateGroupSeats, + setSeatName, + setSeatExtension, + getProfiles, + getModelFrontImage, + updateDeviceKeys, + updateSeatGroups, + getGroupList, + getSeatList, + getDeviceList, + getDevice, + getAllGroupsAndSeats +} from '../../api/pbx-config' export default { listGroups(context, options) { @@ -187,11 +202,15 @@ export default { return new Promise((resolve, reject)=>{ let silent = _.get(options, 'silent', false); let page = _.get(options, 'page', 1); + let profile_id = _.get(options, 'profile_id', null); context.commit('deviceListRequesting', { silent: silent, page: page }); - getDeviceList(page).then((devices)=>{ + getDeviceList({ + page: page, + profile_id: profile_id + }).then((devices)=>{ context.commit('deviceListSucceeded', devices); devices.items.forEach((device)=>{ context.dispatch('loadDevice', device.id); @@ -214,6 +233,35 @@ export default { context.commit('deviceFailed', deviceId, err.message); }); }, + loadProfiles(context) { + if(!context.getters.hasProfiles) { + getProfiles({ all: true }).then((profiles)=>{ + context.commit('profilesSucceeded', profiles); + profiles.items.forEach((profile)=>{ + context.dispatch('loadModelImage', profile.device_id); + }); + }).catch((err)=>{ + context.commit('profilesFailed', err.message); + }); + } + }, + loadModelImage(context, modelId) { + context.commit('modelImageRequesting', modelId); + getModelFrontImage(modelId).then((modelImage)=>{ + context.commit('modelImageSucceeded', modelImage); + }).catch((err)=>{ + context.commit('modelImageFailed', modelId, err.message); + }); + }, + createDevice(context, device) { + context.commit('createDeviceRequesting', device); + createDevice(device).then(()=>{ + context.commit('createDeviceSucceeded'); + context.dispatch('listDevices'); + }).catch((err)=>{ + context.commit('createDeviceFailed', err.message); + }); + }, removeDevice(context, device) { context.commit('deviceRequesting', device.id); removeDevice(device.id).then(()=>{ @@ -239,26 +287,18 @@ export default { }).catch((err)=>{ context.commit('updateDeviceKeyFailed', data.device.id, err); }); - }, - filterDevices(context, params) { - context.commit('deviceListRequesting', { - silent: false - }); - filterDeviceList(params).then((devices)=>{ - context.commit('deviceListSucceeded', devices); - devices.items.forEach((device)=>{ - context.dispatch('loadDevice', device.id); - }); - }).catch((err)=>{ - context.commit('deviceListFailed', err.message); - }); - }, - listProfiles(context) { - context.commit('listProfilesRequesting'); - getProfiles({ all: true }).then((profiles)=>{ - context.commit('listProfilesSucceeded', profiles); - }).catch((err)=>{ - context.commit('listProfilesFailed', err.message); - }); } + // filterDevices(context, params) { + // context.commit('deviceListRequesting', { + // silent: false + // }); + // filterDeviceList(params).then((devices)=>{ + // context.commit('deviceListSucceeded', devices); + // devices.items.forEach((device)=>{ + // context.dispatch('loadDevice', device.id); + // }); + // }).catch((err)=>{ + // context.commit('deviceListFailed', err.message); + // }); + // } } diff --git a/src/store/pbx-config/getters.js b/src/store/pbx-config/getters.js index 1fde149d..8bd41ea0 100644 --- a/src/store/pbx-config/getters.js +++ b/src/store/pbx-config/getters.js @@ -134,16 +134,6 @@ export default { devices(state) { return state.devicesOrdered; }, - modelOptions(state) { - let modelOptions = []; - state.modelsOrdered.forEach((model)=>{ - modelOptions.push({ - label: model.vendor + " " + model.model, - value: model.id - }); - }); - return modelOptions; - }, listCurrentPage(state) { return state.listCurrentPage; }, @@ -176,6 +166,15 @@ export default { lastRemovedSeat(state) { return state.lastRemovedSeat; }, + profiles(state) { + return state.profilesOrdered; + }, + models(state) { + return state.models; + }, + hasProfiles(state) { + return state.profilesOrdered.length > 0; + }, deviceRemoved(state) { return state.deviceRemoved; }, @@ -191,8 +190,15 @@ export default { } ]; state.groupsAndSeats.forEach((item)=>{ + let icon = 'person'; + if(item.is_pbx_pilot) { + icon = 'person_outlined'; + } + else if (item.is_pbx_group){ + icon = 'group'; + } options.push({ - icon: (item.is_pbx_group === true)? 'group' : 'person', + icon: icon, label: item.display_name, value: item.id }); @@ -213,6 +219,21 @@ export default { updatedDeviceKey(state) { return state.updatedDeviceKey; }, + createDeviceRequesting(state) { + return state.createDeviceState === RequestState.requesting; + }, + createDeviceSucceeded(state) { + return state.createDeviceState === RequestState.succeeded; + }, + createDeviceFailed(state) { + return state.createDeviceState === RequestState.failed; + }, + createDeviceError(state) { + return state.createDeviceError; + }, + createDeviceItem(state) { + return state.createDeviceItem; + }, profileOptions(state) { let profileOptions = []; state.profilesOrdered.forEach((profile) => { @@ -228,5 +249,8 @@ export default { }, listProfilesError(state) { return state.listError; + }, + modelImages(state) { + return state.modelImages; } } diff --git a/src/store/pbx-config/mutations.js b/src/store/pbx-config/mutations.js index 84321a3a..13b63c8a 100644 --- a/src/store/pbx-config/mutations.js +++ b/src/store/pbx-config/mutations.js @@ -3,6 +3,7 @@ import Vue from 'vue' import _ from 'lodash' import { RequestState } from '../common' +import { reactiveSet } from '../../helpers/store-helper' export default { listRequesting(state, options) { @@ -148,8 +149,6 @@ export default { state.listLoadingSilently = _.get(options, 'silent', false); state.listState = RequestState.requesting; state.listError = null; - state.devices = {}; - state.devicesOrdered = []; }, deviceListSucceeded(state, data) { state.listState = RequestState.succeeded; @@ -166,12 +165,13 @@ export default { state.listError = error; }, deviceRequesting(state, deviceId) { - Vue.set(state.deviceStates, deviceId + "", RequestState.requesting); + reactiveSet(state.deviceStates, deviceId + "", RequestState.requesting); }, deviceSucceeded(state, device) { - Vue.set(state.deviceStates, device.id + "", RequestState.succeeded); - Vue.set(state.deviceErrors, device.id + "", null); - Vue.set(state.devices, device.id + "", device); + let deviceId = device.id + ""; + reactiveSet(state.deviceStates, deviceId, RequestState.succeeded); + reactiveSet(state.deviceErrors, deviceId, null); + reactiveSet(state.devices, deviceId, device); for(let i = 0; i <= state.devicesOrdered.length; i++) { if(state.devicesOrdered[i].id === device.id) { state.devicesOrdered[i] = device; @@ -179,12 +179,14 @@ export default { } }, deviceFailed(state, deviceId, error) { - Vue.set(state.deviceStates, deviceId + "", RequestState.failed); - Vue.set(state.deviceErrors, deviceId + "", error); + deviceId = deviceId + ""; + reactiveSet(state.deviceStates, deviceId, RequestState.failed); + reactiveSet(state.deviceErrors, deviceId, error); }, deviceRemoved(state, device) { - Vue.set(state.deviceStates, device.id + "", 'deleted'); - Vue.set(state.deviceErrors, device.id + "", null); + let deviceId = device.id + ""; + reactiveSet(state.deviceStates, deviceId, 'deleted'); + reactiveSet(state.deviceErrors, deviceId, null); state.deviceRemoved = device; }, lastAddedGroup(state, group) { @@ -202,6 +204,34 @@ export default { lastUpdatedField(state, group) { state.lastUpdatedField = group; }, + profilesRequesting(state) { + state.profilesRequesting = true; + state.profilesRequestError = null; + }, + profilesSucceeded(state, profiles) { + state.profilesOrdered = profiles.items; + state.profilesOrdered.forEach((profile)=>{ + state.profiles[profile.id + ""] = profile; + }); + state.profilesRequesting = false; + state.profilesRequestError = null; + }, + profilesFailed(state, error) { + state.profilesRequesting = false; + state.profilesRequestError = error; + }, + modelImageRequesting(state, modelId) { + reactiveSet(state.modelImageStates, modelId, RequestState.requesting); + }, + modelImageSucceeded(state, modelImage) { + reactiveSet(state.modelImageStates, modelImage.id, RequestState.succeeded); + reactiveSet(state.modelImageErrors, modelImage.id, null); + reactiveSet(state.modelImages, modelImage.id, modelImage); + }, + modelImageFailed(state, modelId, error) { + reactiveSet(state.modelImageStates, modelId, RequestState.succeeded); + reactiveSet(state.modelImageErrors, modelId, error); + }, groupsAndSeatsRequesting(state) { state.groupsAndSeatsState = RequestState.requesting; state.groupsAndSeats = []; @@ -227,6 +257,18 @@ export default { Vue.set(state.deviceErrors, deviceId + "", error); state.updatedDeviceKey = null; }, + createDeviceRequesting(state, device) { + state.createDeviceState = RequestState.requesting; + state.createDeviceItem = device; + state.createDeviceError = null; + }, + createDeviceSucceeded(state) { + state.createDeviceState = RequestState.succeeded; + }, + createDeviceFailed(state, error) { + state.createDeviceState = RequestState.failed; + state.createDeviceError = error; + }, listProfilesRequesting(state) { state.listProfilesState = RequestState.requesting; state.listProfilesError = null; diff --git a/src/store/pbx-config/state.js b/src/store/pbx-config/state.js index ac583d34..993f0e63 100644 --- a/src/store/pbx-config/state.js +++ b/src/store/pbx-config/state.js @@ -14,8 +14,8 @@ export default { devices: {}, profilesOrdered: [], profiles: {}, - modelsOrdered: [], models: {}, + modelsOrdered: [], listState: RequestState.initiated, listError: null, listLoadingSilently: false, @@ -46,6 +46,12 @@ export default { groupsAndSeatsState: RequestState.initiated, groupsAndSeatsError: null, updatedDeviceKey: null, + createDeviceState: RequestState.initiated, + createDeviceItem: null, + createDeviceError: null, listProfilesState: RequestState.initiated, - listProfilesError: null + listProfilesError: null, + modelImageStates: {}, + modelImageErrors: {}, + modelImages: {}, }