TT#37656 PBXConfig: As a Customer, I want to filter PBXDevices by station_name

Change-Id: I9842a710fc07b3c349f3f1ab9609db8a5b5b2e52
changes/73/22773/8
Hans-Peter Herzog 7 years ago
parent 9b97844cd8
commit c3963b1f35

@ -201,6 +201,7 @@ export function getDeviceList(options) {
page: options.page,
profile_id: options.profile_id,
identifier: options.identifier,
station_name: options.station_name,
order_by: PBX_CONFIG_ORDER_BY,
order_by_direction: PBX_CONFIG_ORDER_DIRECTION
};
@ -210,6 +211,9 @@ export function getDeviceList(options) {
if(params.identifier === null) {
delete params['identifier'];
}
if(params.station_name === null) {
delete params['station_name'];
}
return getDevices({
params: params
}).then((devices)=>{

@ -7,6 +7,7 @@
</q-item-side>
<q-item-main :style="{zIndex: 10}">
<q-item-tile
class="csc-device-title"
v-if="!expanded"
label
>
@ -350,4 +351,11 @@
.csc-pbx-device-buttons
margin-top 32px
.csc-device-title
text-overflow ellipsis
white-space: nowrap;
width 100%
overflow hidden
padding-right 80px
</style>

@ -1,6 +1,5 @@
<template>
<div class="col">
<div class="col">
<div>
<q-field>
<q-input
v-model="data.station_name"
@ -46,7 +45,6 @@
@click="save()"
>{{ $t('buttons.save') }}</q-btn>
</div>
</div>
<q-inner-loading
v-show="loading"
:visible="loading"

@ -2,20 +2,121 @@
<csc-page
class="csc-list-page"
>
<csc-pbx-devices-toolbar
@showForm="showForm"
@toggleFilterOptions="toggleFilterOptions"
@resetAll="resetAllFilters"
<div
class="row justify-center">
<q-btn
v-if="!formEnabled"
flat
icon="add"
color="primary"
@click="showForm()"
>{{ addButtonLabel }}</q-btn>
<q-btn
v-if="!filterEnabled"
flat
icon="fa-filter"
color="primary"
@click="toggleFilter()"
>{{ filterButtonLabel }}</q-btn>
</div>
<div v-if="filterEnabled" class="csc-form margin-sm">
<div :class="filterClasses">
<q-field
class="col-xs-12 col-md-4 col-lg-2">
<q-input
v-if="listStationNameFilter == null"
v-model="filterStationNameInput"
:float-label="$t('pbxConfig.filterStationName')"
@keyup.enter="filterByStationName()"
:after="searchButtonStationName"
/>
<q-list
no-border
separator
sparse
multiline
<q-chip
class="full-width"
v-if="listStationNameFilter != null"
color="primary"
>{{ listStationNameFilter }}
<q-icon
size="26px"
class="csc-chip-remove absolute-right cursor-pointer"
name="fa-times-circle"
@click="resetStationNameFilter()"
/>
</q-chip>
</q-field>
<q-field
class="col-xs-12 col-md-4 col-lg-2">
<q-input
v-if="listMacAddressFilter == null"
v-model="filterMacAddressInput"
:float-label="$t('pbxConfig.filterMacAddress')"
@keyup.enter="filterByMacAddress()"
:after="searchButtonMacAddress"
/>
<q-chip
class="full-width"
v-if="listMacAddressFilter != null"
color="primary"
>{{ listMacAddressFilter }}
<q-icon
size="26px"
class="csc-chip-remove absolute-right cursor-pointer"
name="fa-times-circle"
@click="resetMacAddressFilter()"
/>
</q-chip>
</q-field>
<q-field
class="col-xs-12 col-md-4 col-lg-2">
<csc-pbx-model-select
v-if="listProfileFilter == null"
:preview="false"
:erasable="false"
:profiles="profiles"
:modelImages="modelImages"
:label="$t('pbxConfig.filterPhoneModel')"
@opened="modelSelectOpened()"
@select="filterByProfile"
/>
<q-chip
class="full-width"
v-if="listProfileFilter != null"
:avatar="profileUrl"
color="primary"
>{{ profileName }}
<q-icon
size="26px"
class="csc-chip-remove absolute-right cursor-pointer"
name="fa-times-circle"
@click="resetProfileFilter()"
/>
</q-chip>
</q-field>
</div>
<div
class="row justify-center form-actions"
>
<q-item>
<q-item-main>
<div class="row justify-center">
<q-btn
v-if="filterEnabled"
flat
icon="clear"
color="default"
@click="closeFilter()"
>{{ $t('pbxConfig.closeFilters') }}</q-btn>
<q-btn
v-if="filterEnabled"
flat
icon="fa-filter"
color="negative"
@click="resetFilter()"
:disabled="!hasFilters"
>{{ $t('pbxConfig.resetFilters') }}</q-btn>
</div>
</div>
<div
v-if="formEnabled"
class="row justify-center margin-sm csc-form">
<csc-pbx-device-add-form
class="col col-md-6 col-sm-12"
v-if="formEnabled"
@ -28,11 +129,8 @@
@save="saveDevice"
@cancelForm="cancelForm"
/>
<csc-pbx-devices-filter
class="col col-md-6 col-sm-12"
v-if="filterOptionsPanelOpened"
/>
</div>
<div
v-if="devices.length > 0 && !isListRequesting && listLastPage > 1"
class="row justify-center"
@ -43,6 +141,7 @@
@change="changePage"
/>
</div>
<div
v-if="isListLoadingVisible"
class="row justify-center"
@ -52,8 +151,13 @@
:size="40"
/>
</div>
</q-item-main>
</q-item>
<q-list
no-border
separator
sparse
multiline
>
<csc-pbx-device
v-for="device in devices"
:key="device.id"
@ -81,13 +185,12 @@
</template>
<script>
import _ from 'lodash'
import { mapGetters } from 'vuex'
import CscPage from '../../CscPage'
import CscPbxDevice from './CscPbxDevice'
import CscPbxDeviceAddForm from './CscPbxDeviceAddForm'
import CscPbxDevicesFilter from './CscPbxDevicesFilter'
import CscPbxModelSelect from './CscPbxModelSelect'
import CscPbxDevicesToolbar from './CscPbxDevicesToolbar'
import { showToast, showGlobalError } from '../../../helpers/ui'
import {
QSpinnerDots,
@ -97,15 +200,21 @@
QItem,
QItemMain,
QBtn,
QSelect
QSelect,
QField,
QInput,
QChip,
QIcon,
Platform
} from 'quasar-framework'
export default {
data () {
return {
formEnabled: false,
filterOptionsPanelOpened: false,
platform: this.$q.platform.is
filterEnabled: false,
filterStationNameInput: '',
filterMacAddressInput: ''
}
},
mounted() {
@ -116,16 +225,18 @@
CscPage,
CscPbxDevice,
CscPbxDeviceAddForm,
CscPbxDevicesFilter,
CscPbxModelSelect,
CscPbxDevicesToolbar,
QSpinnerDots,
QPagination,
QList,
QItem,
QBtn,
QSelect,
QItemMain
QItemMain,
QField,
QInput,
QChip,
QIcon
},
computed: {
...mapGetters('pbxConfig', [
@ -155,36 +266,104 @@
'updatedDeviceError',
'updatedDeviceProperty',
'listProfileFilter',
'listMacAddressFilter'
'listProfileFilterObject',
'listMacAddressFilter',
'listStationNameFilter'
]),
isMobile() {
return Platform.is.mobile;
},
noDeviceMessage() {
if (this.listProfileFilter && !this.listMacAddressFilter) {
if (this.listProfileFilter && !this.listMacAddressFilter && !this.listStationNameFilter) {
return this.$t('pbxConfig.noModel');
}
else if (this.listMacAddressFilter && !this.listProfileFilter) {
else if (this.listMacAddressFilter && !this.listProfileFilter && !this.listStationNameFilter) {
return this.$t('pbxConfig.noMacAddress')
}
if (this.listMacAddressFilter && this.listProfileFilter) {
else if (this.listStationNameFilter && !this.listProfileFilter && !this.listMacAddressFilter) {
return this.$t('pbxConfig.noStationName');
}
if (this.listMacAddressFilter && this.listProfileFilter && this.listStationNameFilter ||
this.listMacAddressFilter && this.listProfileFilter && !this.listStationNameFilter ||
this.listMacAddressFilter && !this.listProfileFilter && this.listStationNameFilter ||
!this.listMacAddressFilter && this.listProfileFilter && this.listStationNameFilter
) {
return this.$t('pbxConfig.noDevicesFound');
}
else if (this.devices.length === 0) {
return this.$t('pbxConfig.noDevicesCreated');
}
},
profileUrl() {
return _.get(this.listProfileFilterObject, 'modelImage.url', null);
},
profileName() {
return this.listProfileFilterObject.name;
},
hasFilters() {
return this.listProfileFilterObject !== null ||
this.listMacAddressFilter !== null ||
this.listStationNameFilter !== null;
},
filterResetButtonLabel() {
if(this.hasFilters) {
return this.$t('pbxConfig.resetFilters');
}
else {
return this.$t('pbxConfig.closeFilters');
}
},
methods: {
resetAllFilters() {
this.filterOptionsPanelOpened = false;
this.$emit('resetAllFilters');
this.resetProfileFilter();
this.resetMacAddressFilter();
filterClasses() {
let classes = ['row', 'justify-center'];
if(!this.isMobile) {
classes.push('sm-gutter');
}
return classes;
},
resetProfileFilter() {
this.$store.dispatch('pbxConfig/resetProfileFilter');
addButtonLabel() {
if(this.isMobile) {
return this.$t('pbxConfig.addDeviceShort');
}
else {
return this.$t('pbxConfig.addDevice');
}
},
resetMacAddressFilter() {
this.$store.dispatch('pbxConfig/resetMacAddressFilter');
filterButtonLabel() {
if(this.isMobile) {
return this.$t('pbxConfig.filterDevicesShort');
}
else {
return this.$t('pbxConfig.filterDevices');
}
},
searchButtonStationName() {
let self = this;
return [
{
icon: 'search',
error: false,
handler (event) {
event.stopPropagation();
self.filterByStationName();
}
}
];
},
searchButtonMacAddress() {
let self = this;
return [
{
icon: 'search',
error: false,
handler (event) {
event.stopPropagation();
self.filterByMacAddress();
}
}
];
}
},
methods: {
changePage(page) {
this.$store.dispatch('pbxConfig/goToPage', page);
},
@ -236,19 +415,55 @@
this.$store.dispatch('pbxConfig/setProfile', data);
},
showForm() {
if(this.filterOptionsPanelOpened) {
this.toggleFilterOptions();
if(this.filterEnabled) {
this.closeFilter();
}
this.formEnabled = true;
},
cancelForm() {
this.formEnabled = false;
},
toggleFilterOptions() {
if(this.formEnabled) {
toggleFilter() {
if(this.formEnabled && !this.filterEnabled) {
this.cancelForm();
}
this.filterOptionsPanelOpened = !this.filterOptionsPanelOpened;
this.filterEnabled = !this.filterEnabled;
},
resetFilter() {
this.filterStationNameInput = '';
this.filterMacAddressInput = '';
if(this.hasFilters) {
this.resetFilters();
}
},
closeFilter() {
this.filterEnabled = false;
this.resetFilter();
},
filterByStationName() {
this.$store.dispatch('pbxConfig/filterByStationName', this.filterStationNameInput);
this.filterStationNameInput = '';
},
resetStationNameFilter() {
this.filterStationNameInput = this.listStationNameFilter;
this.$store.dispatch('pbxConfig/resetStationNameFilter');
},
filterByMacAddress() {
this.$store.dispatch('pbxConfig/filterByMacAddress', this.filterMacAddressInput);
this.filterMacAddressInput = '';
},
resetMacAddressFilter() {
this.filterMacAddressInput = this.listMacAddressFilter;
this.$store.dispatch('pbxConfig/resetMacAddressFilter');
},
filterByProfile(profile) {
this.$store.dispatch('pbxConfig/filterByProfile', profile);
},
resetProfileFilter() {
this.$store.dispatch('pbxConfig/resetProfileFilter');
},
resetFilters() {
this.$store.dispatch('pbxConfig/resetDeviceFilters');
}
},
watch: {
@ -317,4 +532,32 @@
<style lang="stylus" rel="stylesheet/stylus">
.filter-model-select
margin 16px 16px 8px 16px
.q-chip
position relative
.q-chip-main
text-overflow ellipsis
white-space: nowrap;
width 100%
overflow hidden
padding-right 18px
.csc-chip-remove
right 6px
.q-chip-side
background-color white
position relative
img
position absolute
display block
top 0
.form-actions
margin-top 16px
margin-bottom 8px
.csc-form
.q-field
margin-bottom 0
</style>

@ -1,66 +0,0 @@
<template>
<div class="col">
<div class="filterOptionsPanel">
<csc-pbx-mac-input
@filter="filterByMacAddress"
@reset="resetMacAddressFilter"
/>
<csc-pbx-model-select
:erasable="true"
:profiles="profiles"
:modelImages="modelImages"
:label="$t('pbxConfig.filterPhoneModel')"
@opened="modelSelectOpened()"
@select="filterByProfile"
@reseted="resetProfileFilter"
/>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import CscPbxModelSelect from './CscPbxModelSelect'
import CscPbxMacInput from './CscPbxMacInput'
export default {
name: 'csc-pbx-devices-filter',
components: {
CscPbxModelSelect,
CscPbxMacInput
},
computed: {
...mapGetters('pbxConfig', [
'profiles',
'modelImages'
])
},
methods: {
filterByProfile(profile) {
this.$store.dispatch('pbxConfig/filterByProfile', profile);
},
filterByMacAddress(identifier) {
this.$store.dispatch('pbxConfig/filterByMacAddress', identifier);
},
resetProfileFilter() {
this.$store.dispatch('pbxConfig/resetProfileFilter');
},
resetMacAddressFilter() {
this.$store.dispatch('pbxConfig/resetMacAddressFilter');
},
modelSelectOpened() {
this.$store.dispatch('pbxConfig/loadProfiles');
}
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
.filter-model-select
margin 16px 16px 8px 16px
.filter-icon
padding 10px
</style>

@ -1,163 +0,0 @@
<template>
<div>
<q-toolbar
color="primary"
inverted
class="row justify-center"
>
<div>
<q-btn
color="primary"
icon="add"
flat
@click="enableForm()"
:class="{ cscLabelMobile: isSmallLabelBreakpoint }"
>
{{ $t('pbxConfig.addDevice') }}
</q-btn>
</div>
<q-btn
v-if="isMobile"
:disabled="checkDevicesCreated"
color="primary"
icon="fa-filter"
flat
@click="toggleFilterOptions()"
:class="{ cscIconMobile: isSmallIconBreakpoint }"
>
{{ showFilterLabel }}
</q-btn>
<div
v-if="!isMobile"
@click="toggleFilterOptions()"
>
<q-btn
:disabled="checkDevicesCreated"
icon="fa-filter"
flat
:class="{ cscIconMobile: isSmallIconBreakpoint }"
>
{{ $t('pbxConfig.filterDevices') }}
</q-btn>
<q-chip
small
tag
square
color="primary"
v-if="chipMacAddressFilter"
>
{{ chipMacAddressFilter | removeTrailingWildcard }}
</q-chip>
<q-chip
small
tag
square
color="primary"
v-if="chipModelFilter"
>
{{ chipModelFilter }}
</q-chip>
</div>
<div class="resetAllBtn">
<q-btn
color="primary"
icon="highlight_off"
flat
:disabled="checkFiltersApplied"
@click="resetAllFilters"
:class="{ cscIconMobile: isSmallIconBreakpoint }"
>
{{ $t('pbxConfig.resetFilters') }}
</q-btn>
</div>
</q-toolbar>
</div>
</template>
<script>
import {
QChip,
QIcon,
QBtn,
QToolbar,
Platform,
dom
} from 'quasar-framework'
import { mapGetters } from 'vuex'
const { viewport } = dom
let { width } = viewport()
export default {
name: 'csc-pbx-devices-toolbar',
data () {
return {
formEnabled: false
}
},
components: {
QChip,
QIcon,
QBtn,
QToolbar,
Platform
},
computed: {
...mapGetters('pbxConfig', [
'devices',
'chipModelFilter',
'chipMacAddressFilter'
]),
isSmallLabelBreakpoint() {
return (width <= 390 && width > 352);
},
isSmallIconBreakpoint() {
return (width <= 500);
},
isMobile() {
return (Platform.is.mobile || width < 1270);
},
filtersApplied() {
return (this.chipModelFilter || this.chipMacAddressFilter);
},
showFilterLabel() {
return this.filtersApplied ? this.$t('pbxConfig.showFilters') : this.$t('pbxConfig.filterDevices');
},
checkFiltersApplied() {
return !(this.chipModelFilter || this.chipMacAddressFilter);
},
checkDevicesCreated() {
return (this.devices.length === 0 && !this.chipModelFilter && !this.chipMacAddressFilter);
}
},
methods: {
enableForm() {
if(this.chipModelFilter || this.chipMacAddressFilter) {
this.resetAllFilters();
}
this.$emit('showForm');
},
toggleFilterOptions() {
if(this.devices.length !== 0 || this.chipModelFilter || this.chipMacAddressFilter) {
this.$emit('toggleFilterOptions');
}
},
resetAllFilters() {
this.$emit('resetAll');
}
},
filters: {
removeTrailingWildcard: function(value) {
return value.slice(0, -1);
}
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
.cscIconMobile
.on-left
margin-right 0
.cscLabelMobile
padding-bottom 20px
</style>

@ -1,93 +0,0 @@
<template>
<div class="col">
<q-field class="row">
<q-input
v-model="macAddress"
:float-label="$t('pbxConfig.filterMacAddress')"
:after="clearButton"
@keyup="filterByMacAddress"
/>
</q-field>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import {
QInnerLoading,
QSpinnerMat,
QField,
QInput,
debounce } from 'quasar-framework'
export default {
name: 'csc-pbx-mac-input',
data () {
return {
macAddress: ''
}
},
components: {
QInnerLoading,
QSpinnerMat,
QField,
QInput
},
created() {
if (this.listMacAddressFilter) {
this.macAddress = this.listMacAddressFilter.slice(0, -1);
}
},
computed: {
...mapGetters('pbxConfig', [
'listMacAddressFilter'
]),
clearButton() {
let self = this;
let buttons = [];
if (this.macAddress) {
buttons = [{
icon: 'clear',
error: false,
handler (event) {
event.stopPropagation();
self.reset();
}
}];
}
return buttons;
}
},
mounted() {
this.debouncedFilterByMacAddress = debounce(() => {
if(this.macAddress === '') {
this.reset();
}
else {
this.$emit('filter', this.macAddress + '*');
}
}, 500)
},
methods: {
reset() {
this.macAddress = '';
this.$emit('reset');
},
filterByMacAddress() {
this.debouncedFilterByMacAddress();
}
},
watch: {
listMacAddressFilter() {
if (this.listMacAddressFilter === null) {
this.macAddress = '';
}
}
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
@import '../../../themes/quasar.variables.styl';
</style>

@ -304,13 +304,14 @@
"devicesTitle": "Devices",
"deviceStationName": "Station name",
"deviceIdentifier": "MAC address",
"deviceModel": "Model",
"deviceModel": "Phone model",
"groupsTitle": "Groups",
"seatsTitle": "Seats",
"noDevicesCreated": "No devices created yet",
"noDevicesFound": "Could not find any device matching any of the filter criteria",
"noModel": "Could not find any device with model matching the filter criteria",
"noMacAddress": "Could not find any device with MAC address matching the filter criteria",
"noStationName": "Could not find any device with station name matching the filter criteria",
"noGroups": "No groups created yet",
"noSeats": "No seats created yet",
"toasts": {
@ -330,6 +331,7 @@
"createdDevice": "Created device {name} successfully"
},
"addDevice": "Add device",
"addDeviceShort": "Add",
"removeDevice": "Remove device",
"removeDeviceTitle": "Remove device",
"removeDeviceText": "You are about to remove device {device}",
@ -341,11 +343,14 @@
"keyTypeShared": "Shared",
"keyTypeBLF": "Busy Lamp Field",
"keyTypePrivate": "Private",
"filterPhoneModel": "Filter by phone model",
"filterMacAddress": "Filter by MAC address",
"filterPhoneModel": "Phone model",
"filterMacAddress": "MAC address",
"filterStationName": "Station name",
"showFilters": "Show filters",
"filterDevices": "Filter devices",
"resetFilters": "Reset filters"
"filterDevicesShort": "Filter",
"resetFilters": "Reset filters",
"closeFilters": "Close filters"
},
"callBlocking": {
"privacyEnabledToast": "Your number is hidden to the callee",

@ -262,7 +262,8 @@ export default {
getDeviceList({
page: _.get(context, 'getters.listCurrentPage', 1),
profile_id: _.get(context, 'getters.listProfileFilter', null),
identifier: _.get(context, 'getters.listMacAddressFilter', null)
identifier: _.get(context, 'getters.listMacAddressFilter', null),
station_name: _.get(context, 'getters.listStationNameFilter', null)
}).then((devices)=>{
context.commit('deviceListSucceeded', devices);
devices.items.forEach((device)=>{
@ -390,6 +391,10 @@ export default {
context.commit('filterByMacAddress', macAddress);
context.dispatch('listDevices');
},
filterByStationName(context, stationName) {
context.commit('filterByStationName', stationName);
context.dispatch('listDevices');
},
resetProfileFilter(context) {
context.commit('resetProfileFilter');
context.dispatch('listDevices');
@ -398,8 +403,18 @@ export default {
context.commit('resetMacAddressFilter');
context.dispatch('listDevices');
},
resetStationNameFilter(context) {
context.commit('resetStationNameFilter');
context.dispatch('listDevices');
},
goToPage(context, page) {
context.commit('goToPage', page);
context.dispatch('listDevices');
},
resetDeviceFilters(context) {
context.commit('resetProfileFilter');
context.commit('resetStationNameFilter');
context.commit('resetMacAddressFilter');
context.dispatch('listDevices');
}
}

@ -271,13 +271,29 @@ export default {
listProfileFilter(state) {
return state.listProfileFilter;
},
listProfileFilterObject(state) {
if(state.listProfileFilter !== null) {
let profile = state.profiles[state.listProfileFilter];
profile.modelImage = state.modelImages[profile.device_id];
return profile;
}
else {
return null;
}
},
listMacAddressFilter(state) {
return state.listMacAddressFilter;
},
listStationNameFilter(state) {
return state.listStationNameFilter;
},
chipModelFilter(state) {
return state.chipModelFilter;
},
chipMacAddressFilter(state) {
return state.chipMacAddressFilter;
},
chipStationNameFilter(state) {
return state.chipStationNameFilter;
}
}

@ -336,20 +336,23 @@ export default {
filterByProfile(state, profile) {
state.listProfileFilter = profile.id;
state.listCurrentPage = 1;
state.chipModelFilter = profile.name;
},
filterByMacAddress(state, macAddress) {
state.listMacAddressFilter = macAddress;
state.listCurrentPage = 1;
state.chipMacAddressFilter = macAddress;
},
filterByStationName(state, stationName) {
state.listStationNameFilter = stationName;
state.listCurrentPage = 1;
},
resetProfileFilter(state) {
state.listProfileFilter = null;
state.chipModelFilter = null;
},
resetMacAddressFilter(state) {
state.listMacAddressFilter = null;
state.chipMacAddressFilter = null;
},
resetStationNameFilter(state) {
state.listStationNameFilter = null;
},
goToPage(state, page) {
state.listCurrentPage = page;

@ -23,6 +23,7 @@ export default {
listLastPage: null,
listProfileFilter: null,
listMacAddressFilter: null,
listStationNameFilter: null,
addState: RequestState.initiated,
addError: null,
addItem: null,
@ -67,5 +68,6 @@ export default {
seatReloadingState: RequestState.initiated,
seatReloadingError: null,
chipModelFilter: null,
chipMacAddressFilter: null
chipMacAddressFilter: null,
chipStationNameFilter: null
}

@ -1,6 +1,12 @@
@import 'quasar.variables'
.margin-xs
margin 8px
.margin-sm
margin 16px
@media (max-width: $breakpoint-sm)
.page.csc-list-page
padding 0

Loading…
Cancel
Save