What has been done: - TT#40522, Investigate and discover necessary API endpoints - TT#40523, Implement speed dial page, navigation menu entry and home page box - TT#40525, Implement UI display for list of speed dials - TT#40524, Implement API method for fetching speed dial slots 0-9 - TT#40526, Implement loading animation and error alert - TT#41016, Implement test API speed dial method Change-Id: I0b6fc4dab08913948bb8acf9c136bd56fe89da01changes/61/22561/8
parent
8e4fb6446b
commit
6117c5f6fe
@ -0,0 +1,36 @@
|
||||
|
||||
import _ from 'lodash'
|
||||
import { getFieldList } from './common'
|
||||
|
||||
export function getSpeedDials(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
getFieldList({
|
||||
path: 'api/speeddials/' + id,
|
||||
field: 'speeddials'
|
||||
}).then((result) => {
|
||||
let sortedResult = _.sortBy(result, ['slot']);
|
||||
resolve(sortedResult);
|
||||
}).catch((err) => {
|
||||
reject(err.body.message);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function getUnassignedSlots(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let slots = ["*0", "*1", "*2", "*3", "*4", "*5", "*6", "*7", "*8", "*9"];
|
||||
Promise.resolve().then(() => {
|
||||
return getSpeedDials(id);
|
||||
}).then((assignedSlots) => {
|
||||
// TODO: Split into own testable function that takes slots and
|
||||
// unassigned slots, and outputs slotOptions array ready to be
|
||||
// consumed by q-select
|
||||
let unassignedSlots = _.difference(slots, assignedSlots.map((slot) => {
|
||||
return slot.slot;
|
||||
}));
|
||||
resolve(unassignedSlots);
|
||||
}).catch((err) => {
|
||||
reject(err.body.message);
|
||||
});
|
||||
});
|
||||
}
|
@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<csc-page class="csc-list-page">
|
||||
<q-list
|
||||
no-border
|
||||
inset-separator
|
||||
sparse
|
||||
multiline
|
||||
>
|
||||
<q-item
|
||||
v-for="(assigned, index) in assignedSlots"
|
||||
:key="index"
|
||||
class="csc-entity"
|
||||
>
|
||||
<q-item-side
|
||||
icon="touch app"
|
||||
color="primary"
|
||||
/>
|
||||
<q-item-main>
|
||||
<q-item-tile label>
|
||||
<span class="csc-entity-title">
|
||||
{{ $t('speedDial.whenIDial', { slot: assigned.slot }) }}
|
||||
</span>
|
||||
</q-item-tile>
|
||||
<q-item-tile sublabel>
|
||||
{{ $t('speedDial.ring') }}
|
||||
{{ assigned.destination | destinationFormat }}
|
||||
</q-item-tile>
|
||||
</q-item-main>
|
||||
<q-item-side
|
||||
right
|
||||
class="csc-item-buttons"
|
||||
>
|
||||
<q-item-tile>
|
||||
<q-btn
|
||||
flat
|
||||
icon="delete"
|
||||
color="negative"
|
||||
slot="right"
|
||||
@click="deleteAssignment(index)"
|
||||
/>
|
||||
</q-item-tile>
|
||||
</q-item-side>
|
||||
</q-item>
|
||||
</q-list>
|
||||
<div
|
||||
v-if="assignedSlots.length === 0"
|
||||
class="row justify-center"
|
||||
>
|
||||
{{ $t('speedDial.noResultsMessage') }}
|
||||
</div>
|
||||
</csc-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import {
|
||||
startLoading,
|
||||
stopLoading,
|
||||
showGlobalError
|
||||
} from '../../helpers/ui'
|
||||
import CscPage from '../CscPage'
|
||||
import {
|
||||
QList,
|
||||
QItem,
|
||||
QItemMain,
|
||||
QItemTile,
|
||||
QItemSide,
|
||||
QChip,
|
||||
QBtn
|
||||
} from 'quasar-framework'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CscPage,
|
||||
QList,
|
||||
QItem,
|
||||
QItemMain,
|
||||
QItemTile,
|
||||
QItemSide,
|
||||
QChip,
|
||||
QBtn
|
||||
},
|
||||
created() {
|
||||
this.$store.dispatch('speedDial/loadSpeedDials');
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('speedDial', [
|
||||
'assignedSlots',
|
||||
'speedDialLoadingState',
|
||||
'speedDialLoadingError'
|
||||
])
|
||||
},
|
||||
methods: {
|
||||
deleteAssignment(index) {
|
||||
console.log('deleteAssignment(), index', index);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
speedDialLoadingState(state) {
|
||||
if (state === 'requesting') {
|
||||
startLoading();
|
||||
}
|
||||
else if (state === 'failed') {
|
||||
stopLoading();
|
||||
showGlobalError(this.speedDialLoadingError);
|
||||
}
|
||||
else if (state === 'succeeded') {
|
||||
stopLoading();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus" rel="stylesheet/stylus">
|
||||
</style>
|
@ -0,0 +1,62 @@
|
||||
'use strict';
|
||||
|
||||
import { i18n } from '../i18n';
|
||||
import { RequestState } from './common'
|
||||
import {
|
||||
getSpeedDials
|
||||
} from '../api/speed-dial';
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
assignedSlots: [],
|
||||
slotOptions: [],
|
||||
speedDialLoadingState: RequestState.initiated,
|
||||
speedDialError: null
|
||||
},
|
||||
getters: {
|
||||
reminderLoadingState(state) {
|
||||
return state.reminderLoadingState;
|
||||
},
|
||||
reminderError(state) {
|
||||
return state.reminderError;
|
||||
},
|
||||
subscriberId(state, getters, rootState, rootGetters) {
|
||||
return rootGetters['user/getSubscriberId'];
|
||||
},
|
||||
assignedSlots(state) {
|
||||
return state.assignedSlots;
|
||||
},
|
||||
speedDialLoadingState(state) {
|
||||
return state.speedDialLoadingState;
|
||||
},
|
||||
speedDialLoadingError(state) {
|
||||
return state.speedDialLoadingError || i18n.t('speedDial.loadSpeedDialErrorMessage');
|
||||
}
|
||||
},
|
||||
mutations: {
|
||||
speedDialRequesting(state) {
|
||||
state.speedDialLoadingState = RequestState.requesting;
|
||||
state.speedDialLoadingError = null;
|
||||
},
|
||||
speedDialSucceeded(state, slots) {
|
||||
state.speedDialLoadingState = RequestState.succeeded;
|
||||
state.assignedSlots = slots;
|
||||
state.speedDialLoadingError = null;
|
||||
},
|
||||
speedDialFailed(state, error) {
|
||||
state.speedDialLoadingState = RequestState.failed;
|
||||
state.speedDialLoadingError = error;
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
loadSpeedDials(context) {
|
||||
context.commit('speedDialRequesting');
|
||||
getSpeedDials(context.getters.subscriberId).then((slots) => {
|
||||
context.commit('speedDialSucceeded', slots);
|
||||
}).catch((error) => {
|
||||
context.commit('speedDialFailed', error);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
@ -0,0 +1,99 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import Vue from 'vue';
|
||||
import VueResource from 'vue-resource';
|
||||
import {
|
||||
getFieldList
|
||||
} from '../../src/api/common';
|
||||
import {
|
||||
getSpeedDials
|
||||
} from '../../src/api/speed-dial';
|
||||
import { assert } from 'chai';
|
||||
|
||||
Vue.use(VueResource);
|
||||
|
||||
describe('Speed Dials', function(){
|
||||
|
||||
const subscriberId = 123;
|
||||
|
||||
it('should get list of subscriber specific speed dials', function(done){
|
||||
|
||||
let data = {
|
||||
"_links" : {
|
||||
"collection" : {
|
||||
"href" : "/api/speeddials/"
|
||||
},
|
||||
"curies" : {
|
||||
"href" : "http://purl.org/sipwise/ngcp-api/#rel-{rel}",
|
||||
"name" : "ngcp",
|
||||
"templated" : true
|
||||
},
|
||||
"ngcp:journal" : [
|
||||
{
|
||||
"href" : "/api/speeddials/323/journal/"
|
||||
}
|
||||
],
|
||||
"ngcp:speeddials" : [
|
||||
{
|
||||
"href" : "/api/speeddials/323"
|
||||
}
|
||||
],
|
||||
"ngcp:subscribers" : [
|
||||
{
|
||||
"href" : "/api/subscribers/323"
|
||||
}
|
||||
],
|
||||
"profile" : {
|
||||
"href" : "http://purl.org/sipwise/ngcp-api/"
|
||||
},
|
||||
"self" : {
|
||||
"href" : "/api/speeddials/323"
|
||||
}
|
||||
},
|
||||
"speeddials" : [
|
||||
{
|
||||
"destination" : "sip:439965050@10.15.17.240",
|
||||
"slot" : "*9"
|
||||
},
|
||||
{
|
||||
"destination" : "sip:22222222@10.15.17.240",
|
||||
"slot" : "*0"
|
||||
},
|
||||
{
|
||||
"destination" : "sip:43665522@10.15.17.240",
|
||||
"slot" : "*3"
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
let fieldList = [
|
||||
{
|
||||
"destination" : "sip:22222222@10.15.17.240",
|
||||
"slot" : "*0"
|
||||
},
|
||||
{
|
||||
"destination" : "sip:43665522@10.15.17.240",
|
||||
"slot" : "*3"
|
||||
},
|
||||
{
|
||||
"destination" : "sip:439965050@10.15.17.240",
|
||||
"slot" : "*9"
|
||||
}
|
||||
];
|
||||
|
||||
Vue.http.interceptors = [];
|
||||
Vue.http.interceptors.unshift((request, next)=>{
|
||||
next(request.respondWith(JSON.stringify(data), {
|
||||
status: 200
|
||||
}));
|
||||
});
|
||||
getSpeedDials(subscriberId).then((result)=>{
|
||||
assert.deepEqual(result, fieldList);
|
||||
done();
|
||||
}).catch((err)=>{
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
Loading…
Reference in new issue