TT#47986 Jump from a Seat/Group to CallQueue item

What has been done:
- TT#47986, Implement UI button for jumping from Seat/Group item to
  CallQueueConfiguration item
- TT#47987, Implement router link which passes parameter to
  CallQueueConfiguration component
- TT#47988, Implement highlighting of CallQueueConfiguration item upon
  route change
- TT#47989, Implement "scroll to item" capability in
  CallQueueConfiguration component
- TT#48594, Extend Seats/Groups list logic to also fetch call queue
  preferences

Change-Id: I31797e12889d1c5bd32b330550cec04e67edee93
changes/05/25405/13
raxelsen 6 years ago committed by Hans-Peter Herzog
parent cdbb7cabba
commit bf661f4fa9

@ -598,3 +598,7 @@ export function setQueueLengthConfig(id, queueLength) {
export function setWrapUpTimeConfig(id, wrapUpTime) { export function setWrapUpTimeConfig(id, wrapUpTime) {
return setWrapUpTime(id, wrapUpTime); return setWrapUpTime(id, wrapUpTime);
} }
export function getPrefs(id) {
return getPreferences(id);
}

@ -109,7 +109,7 @@
<q-btn <q-btn
:icon="titleIcon" :icon="titleIcon"
:big="isMobile" :big="isMobile"
color="primary" :color="caretColor"
flat flat
@click="toggleMain()" @click="toggleMain()"
/> />
@ -148,12 +148,14 @@
name: 'csc-pbx-call-queue', name: 'csc-pbx-call-queue',
props: [ props: [
'subscriber', 'subscriber',
'loading' 'loading',
'highlight'
], ],
data () { data () {
return { return {
expanded: false, expanded: this.highlight,
changes: this.getConfig() changes: this.getConfig(),
highlightCollapsed: false
} }
}, },
components: { components: {
@ -221,9 +223,16 @@
}); });
} }
}, },
highlighted() {
return this.expanded && this.highlight && !this.highlightCollapsed;
},
itemClasses() { itemClasses() {
let classes = ['csc-list-item', 'csc-pbx-call-queue']; let classes = ['csc-list-item', 'csc-pbx-call-queue'];
if (this.expanded) { if (this.highlighted) {
classes.push('csc-item-expanded');
classes.push('csc-item-highlight');
}
else if (this.expanded) {
classes.push('csc-item-expanded'); classes.push('csc-item-expanded');
} }
else { else {
@ -331,10 +340,14 @@
max_queue_length: this.changes.max_queue_length, max_queue_length: this.changes.max_queue_length,
queue_wrap_up_time: this.changes.queue_wrap_up_time queue_wrap_up_time: this.changes.queue_wrap_up_time
} }
},
caretColor() {
return this.highlighted ? 'white' : 'primary';
} }
}, },
methods: { methods: {
toggleMain() { toggleMain() {
this.highlightCollapsed = true;
this.expanded = !this.expanded; this.expanded = !this.expanded;
}, },
getConfig() { getConfig() {

@ -47,11 +47,13 @@
> >
<csc-pbx-call-queue <csc-pbx-call-queue
v-for="(subscriber, index) in callQueueGroupsAndSeats" v-for="(subscriber, index) in callQueueGroupsAndSeats"
:id="`queue-${subscriber.id}`"
:key="index" :key="index"
:subscriber="subscriber" :subscriber="subscriber"
:loading="isItemLoading(subscriber.id)" :loading="isItemLoading(subscriber.id)"
@save-queue-length="setQueueLength" @save-queue-length="setQueueLength"
@save-wrap-up-time="setWrapUpTime" @save-wrap-up-time="setWrapUpTime"
:highlight="highlight(subscriber)"
@remove="removeConfigDialog" @remove="removeConfigDialog"
/> />
</q-list> </q-list>
@ -92,6 +94,8 @@
QSpinnerDots, QSpinnerDots,
QBtn QBtn
} from 'quasar-framework' } from 'quasar-framework'
import { scroll } from 'quasar-framework'
const { getScrollTarget, setScrollPosition } = scroll
export default { export default {
components: { components: {
CscPage, CscPage,
@ -137,6 +141,18 @@
isMobile() { isMobile() {
return Platform.is.mobile; return Platform.is.mobile;
}, },
callQueueItem() {
return this.$route.query.item;
},
handleScroll () {
const el = document.getElementById(`queue-${this.callQueueItem}`)
const target = el ? getScrollTarget(el) : null;
const offset = el ? el.offsetTop - el.scrollHeight : null;
const duration = 200
if (this.callQueueItem && target) {
setScrollPosition(target, offset, duration)
}
},
removeDialogMessage() { removeDialogMessage() {
if (this.currentRemovingSubscriber !== null) { if (this.currentRemovingSubscriber !== null) {
return this.$t('pbxConfig.removeConfigText', { return this.$t('pbxConfig.removeConfigText', {
@ -177,6 +193,9 @@
return (this.isUpdating && this.updateItemId + "" === subscriberId + "") || return (this.isUpdating && this.updateItemId + "" === subscriberId + "") ||
(this.isRemoving && this.currentRemovingSubscriber.id + "" === subscriberId + ""); (this.isRemoving && this.currentRemovingSubscriber.id + "" === subscriberId + "");
}, },
highlight(subscriber) {
return subscriber.id == this.$route.query.item;
},
removeConfigDialog(subscriber) { removeConfigDialog(subscriber) {
this.currentRemovingSubscriber = subscriber; this.currentRemovingSubscriber = subscriber;
this.$refs.removeDialog.open(); this.$refs.removeDialog.open();
@ -190,6 +209,13 @@
if (state === 'succeeded') { if (state === 'succeeded') {
this.disableAddForm(); this.disableAddForm();
} }
},
callQueueGroupsAndSeats(state) {
if (state.length > 0) {
setTimeout(() => {
this.handleScroll;
}, 500);
}
} }
} }
} }

@ -135,12 +135,47 @@
<q-item-tile> <q-item-tile>
<q-btn <q-btn
v-if="expanded" v-if="expanded"
icon="delete" icon="more_vert"
:big="isMobile" color="primary"
color="negative"
flat flat
@click="remove()" >
/> <q-popover
ref="morePopover"
anchor="bottom right"
self="top right"
>
<q-list
class="csc-item-buttons-menu"
no-border
>
<q-item
v-if="group.cloud_pbx_callqueue"
link
@click="$router.push(callQueueRouteWithId)"
>
<q-item-side
icon="queue"
color="primary"
/>
<q-item-main
:label="$t('pbxConfig.callQueue')"
/>
</q-item>
<q-item
link
@click="remove"
>
<q-item-side
icon="delete"
color="negative"
/>
<q-item-main
:label="$t('buttons.remove')"
/>
</q-item>
</q-list>
</q-popover>
</q-btn>
<q-btn <q-btn
:icon="titleIcon" :icon="titleIcon"
:big="isMobile" :big="isMobile"
@ -181,7 +216,9 @@
QItemSide, QItemSide,
QItemMain, QItemMain,
QItemTile, QItemTile,
QAlert QAlert,
QList,
QPopover
} from 'quasar-framework' } from 'quasar-framework'
export default { export default {
name: 'csc-pbx-group', name: 'csc-pbx-group',
@ -216,9 +253,17 @@
QItemSide, QItemSide,
QItemMain, QItemMain,
QItemTile, QItemTile,
QAlert QAlert,
QList,
QPopover
}, },
computed: { computed: {
callQueueRouteWithId() {
return {
path: '/user/pbx-configuration/call-queues',
query: { item: this.id }
};
},
itemClasses() { itemClasses() {
let classes = ['csc-list-item', 'csc-pbx-group']; let classes = ['csc-list-item', 'csc-pbx-group'];
if (this.expanded) { if (this.expanded) {

@ -114,12 +114,47 @@
<q-item-tile> <q-item-tile>
<q-btn <q-btn
v-if="expanded" v-if="expanded"
icon="delete" icon="more_vert"
:big="isMobile" color="primary"
color="negative"
flat flat
@click="remove()" >
/> <q-popover
ref="morePopover"
anchor="bottom right"
self="top right"
>
<q-list
class="csc-item-buttons-menu"
no-border
>
<q-item
v-if="seat.cloud_pbx_callqueue"
link
@click="$router.push(callQueueRouteWithId)"
>
<q-item-side
icon="queue"
color="primary"
/>
<q-item-main
:label="$t('pbxConfig.callQueue')"
/>
</q-item>
<q-item
link
@click="remove"
>
<q-item-side
icon="delete"
color="negative"
/>
<q-item-main
:label="$t('buttons.remove')"
/>
</q-item>
</q-list>
</q-popover>
</q-btn>
<q-btn <q-btn
:icon="titleIcon" :icon="titleIcon"
:big="isMobile" :big="isMobile"
@ -155,7 +190,9 @@
QItemSide, QItemSide,
QItemMain, QItemMain,
QItemTile, QItemTile,
QAlert QAlert,
QList,
QPopover
} from 'quasar-framework' } from 'quasar-framework'
export default { export default {
name: 'csc-pbx-seat', name: 'csc-pbx-seat',
@ -184,9 +221,17 @@
QItemSide, QItemSide,
QItemMain, QItemMain,
QItemTile, QItemTile,
QAlert QAlert,
QList,
QPopover
}, },
computed: { computed: {
callQueueRouteWithId() {
return {
path: '/user/pbx-configuration/call-queues',
query: { item: this.id }
};
},
itemClasses() { itemClasses() {
let classes = ['csc-list-item', 'csc-pbx-seat']; let classes = ['csc-list-item', 'csc-pbx-seat'];
if (this.expanded) { if (this.expanded) {

@ -395,6 +395,7 @@
"wrapUpTime": "Wrap Up Time", "wrapUpTime": "Wrap Up Time",
"queueExtensionName": "Group/Seat/Pilot", "queueExtensionName": "Group/Seat/Pilot",
"addConfig": "Add Call Queue", "addConfig": "Add Call Queue",
"callQueue": "Call Queue",
"createConfig": "Create Call Queue", "createConfig": "Create Call Queue",
"removeConfigTitle": "Remove call queue", "removeConfigTitle": "Remove call queue",
"removeConfigText": "You are about to remove call queue for {subscriber}" "removeConfigText": "You are about to remove call queue for {subscriber}"

@ -36,6 +36,7 @@ import {
setQueueLengthConfig, setQueueLengthConfig,
setWrapUpTimeConfig, setWrapUpTimeConfig,
getConfig, getConfig,
getPrefs,
removeCallQueue removeCallQueue
} from '../../api/pbx-config' } from '../../api/pbx-config'
@ -47,8 +48,13 @@ export default {
silent: silent, silent: silent,
page: page page: page
}); });
getGroupList(page).then((groups)=>{ getGroupList(page).then((data)=>{
context.commit('listSucceeded', groups); context.commit('listSucceeded', data);
return data;
}).then((groups) => {
groups.groups.items.forEach((group)=>{
context.dispatch('loadCallQueueForGroup', group.id);
});
}).catch((err)=>{ }).catch((err)=>{
context.commit('listFailed', err.message); context.commit('listFailed', err.message);
}); });
@ -182,8 +188,13 @@ export default {
silent: silent, silent: silent,
page: page page: page
}); });
getSeatList(page).then((seats)=>{ getSeatList(page).then((data)=>{
context.commit('listSucceeded', seats); context.commit('listSucceeded', data);
return data;
}).then((seats) => {
seats.seats.items.forEach((seat)=>{
context.dispatch('loadCallQueueForSeat', seat.id);
});
}).catch((err)=>{ }).catch((err)=>{
context.commit('listFailed', err.message); context.commit('listFailed', err.message);
}); });
@ -498,6 +509,32 @@ export default {
context.commit('updateItemFailed', err.message); context.commit('updateItemFailed', err.message);
}); });
}, },
loadCallQueueForGroup(context, subscriberId) {
context.commit('preferenceRequesting', 'group', subscriberId);
getPrefs(subscriberId).then(($preferences) => {
let preferences = $preferences;
delete preferences._link;
context.commit('preferenceSucceeded', {
type: 'group',
preferences: preferences
});
}).catch((err) => {
context.commit('preferenceFailed', 'group', subscriberId, err.message);
})
},
loadCallQueueForSeat(context, subscriberId) {
context.commit('preferenceRequesting', 'seat', subscriberId);
getPrefs(subscriberId).then(($preferences) => {
let preferences = $preferences;
delete preferences._link;
context.commit('preferenceSucceeded', {
type: 'seat',
preferences: preferences
});
}).catch((err) => {
context.commit('preferenceFailed', 'seat', subscriberId, err.message);
})
},
removeCallQueue(context, config) { removeCallQueue(context, config) {
context.commit('removeItemRequesting', config); context.commit('removeItemRequesting', config);
removeCallQueue(config.id).then(()=>{ removeCallQueue(config.id).then(()=>{

@ -192,7 +192,7 @@ export default {
state.groupsAndSeats.forEach((item)=>{ state.groupsAndSeats.forEach((item)=>{
let icon = 'person'; let icon = 'person';
if(item.is_pbx_pilot) { if(item.is_pbx_pilot) {
icon = 'person_outlined'; icon = 'person_outline';
} }
else if (item.is_pbx_group){ else if (item.is_pbx_group){
icon = 'group'; icon = 'group';
@ -312,7 +312,10 @@ export default {
.filter((item) => { .filter((item) => {
return ids.indexOf(item.value) === -1; return ids.indexOf(item.value) === -1;
} }
); ).map((item)=>{
item.leftColor = 'primary';
return item;
});
return options; return options;
}, },
configItemById(state) { configItemById(state) {

@ -448,5 +448,24 @@ export default {
configReloadingFailed(state, err) { configReloadingFailed(state, err) {
state.configReloadingState = RequestState.failed; state.configReloadingState = RequestState.failed;
state.configReloadingError = err; state.configReloadingError = err;
},
preferenceRequesting(state, type, id) {
reactiveSet(state[type + 'States'], id + "", RequestState.requesting);
},
preferenceSucceeded(state, data) {
let id = data.preferences.id + "";
reactiveSet(state[data.type + 'States'], id, RequestState.succeeded);
reactiveSet(state[data.type + 'Errors'], id, null);
Vue.set(state[data.type + 's'], id, Object.assign(state[data.type + 's'][id], data.preferences));
for(let i = 0; i <= state[data.type + 'sOrdered'].length; i++) {
if(state[data.type + 'sOrdered'][i].id === data.preferences.id) {
state[data.type + 'sOrdered'][i] = Object.assign(state[data.type + 'sOrdered'][i], data.preferences);
}
}
},
preferenceFailed(state, type, id, error) {
id = id + "";
reactiveSet(state[type + 'States'], id, RequestState.failed);
reactiveSet(state[type + 'Errors'], id, error);
} }
} }

@ -74,5 +74,9 @@ export default {
callQueueGroupsAndSeatsOrdered: [], callQueueGroupsAndSeatsOrdered: [],
configReloading: null, configReloading: null,
configReloadingState: RequestState.initiated, configReloadingState: RequestState.initiated,
configReloadingError: null configReloadingError: null,
groupStates: {},
groupErrors: {},
seatStates: {},
seatErrors: {}
} }

@ -185,7 +185,6 @@
.q-chip-side .q-chip-side
color $dark color $dark
.csc-item-highlight,
.q-popover .csc-item-highlight:hover
.q-icon background alpha($primary, 0.3) !important
color: $primary

Loading…
Cancel
Save