You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
373 lines
12 KiB
373 lines
12 KiB
<template>
|
|
<csc-page
|
|
id="csc-page-pbx-devices"
|
|
class="q-pa-lg"
|
|
>
|
|
<csc-list-actions class="row justify-center q-mb-xs">
|
|
<template
|
|
v-if="isDeviceAddFormDisabled"
|
|
#slot1
|
|
>
|
|
<csc-list-action-button
|
|
icon="add"
|
|
color="primary"
|
|
:label="$t('Add device')"
|
|
:disable="isDeviceListRequesting || isDeviceRemoving || isDeviceUpdating"
|
|
@click="enableAddForm"
|
|
/>
|
|
</template>
|
|
<template #slot2>
|
|
<csc-list-action-button
|
|
v-if="!filtersEnabled"
|
|
icon="filter_alt"
|
|
color="primary"
|
|
:label="$t('Filter devices')"
|
|
:disable="isDeviceListRequesting || isDeviceCreating || isDeviceRemoving || isDeviceUpdating"
|
|
@click="enableFilters"
|
|
/>
|
|
<csc-list-action-button
|
|
v-if="filtersEnabled"
|
|
icon="clear"
|
|
color="negative"
|
|
:label="$t('Close filters')"
|
|
:disable="isDeviceListRequesting || isDeviceCreating || isDeviceRemoving || isDeviceUpdating"
|
|
@click="closeFilters"
|
|
/>
|
|
</template>
|
|
</csc-list-actions>
|
|
<q-separator class="q-mb-xs" />
|
|
<q-slide-transition>
|
|
<div
|
|
v-if="!isDeviceAddFormDisabled"
|
|
class="row justify-center q-mb-lg"
|
|
>
|
|
<csc-pbx-device-add-form
|
|
class="csc-list-form col-xs-12 col-md-6"
|
|
:loading="isDeviceCreating"
|
|
:profiles="deviceProfileList"
|
|
:profile-map="deviceProfileMap"
|
|
:model-image-map="deviceModelImageMap"
|
|
@cancel="disableDeviceAddForm"
|
|
@submit="createDevice"
|
|
@model-select-opened="loadProfileThumbnails()"
|
|
/>
|
|
</div>
|
|
</q-slide-transition>
|
|
<q-slide-transition>
|
|
<csc-pbx-device-filters
|
|
v-if="hasFilters || filtersEnabled"
|
|
:loading="isDeviceListRequesting"
|
|
class="q-pb-md"
|
|
@filter="applyFilter"
|
|
@model-select-opened="loadProfileThumbnails()"
|
|
/>
|
|
</q-slide-transition>
|
|
<div
|
|
v-if="isDeviceListPaginationActive"
|
|
class="row justify-center"
|
|
>
|
|
<q-pagination
|
|
:model-value="deviceListCurrentPage"
|
|
:max="deviceListLastPage"
|
|
@update:model-value="loadDeviceListFiltered"
|
|
/>
|
|
</div>
|
|
<csc-list-spinner v-if="showSpinner" />
|
|
<q-list
|
|
v-if="!showSpinner && !isDeviceListEmpty && deviceListVisibility === 'visible'"
|
|
class="row justify-start items-start"
|
|
>
|
|
<csc-fade
|
|
v-for="(device, index) in deviceList"
|
|
:key="'csc-fade-' + device.id"
|
|
>
|
|
<csc-pbx-device
|
|
:key="device.id"
|
|
:loading="isItemLoading(device.id)"
|
|
:device="device"
|
|
:class="'col-xs-12 col-md-6 col-lg-4 csc-item-' + ((index % 2 === 0)?'odd':'even')"
|
|
:profile="getDeviceProfile(device.profile_id)"
|
|
:model="getDeviceModel(device.profile_id)"
|
|
:model-image="getDeviceModelImage(device.profile_id)"
|
|
@load-model="loadDeviceModel({
|
|
type: 'all',
|
|
deviceId: device.profile_id ? getDeviceProfile(device.profile_id).device_id : null
|
|
})"
|
|
@remove="openDeviceRemovalDialog(device.id)"
|
|
/>
|
|
</csc-fade>
|
|
</q-list>
|
|
<div
|
|
v-if="isDeviceListEmpty && !isDeviceListRequesting && hasFilters"
|
|
class="row justify-center csc-no-entities"
|
|
>
|
|
{{ $t('Could not find any device matching any of the filter criteria') }}
|
|
</div>
|
|
<div
|
|
v-else-if="isDeviceListEmpty && !isDeviceListRequesting"
|
|
class="row justify-center csc-no-entities"
|
|
>
|
|
{{ $t('No devices created yet') }}
|
|
</div>
|
|
<csc-remove-dialog
|
|
ref="removeDialog"
|
|
:title="$t('Remove device')"
|
|
:message="getDeviceRemoveDialogMessage"
|
|
@remove="removeDevice(deviceRemoving.id)"
|
|
@cancel="closeDeviceRemovalDialog"
|
|
/>
|
|
</csc-page>
|
|
</template>
|
|
|
|
<script>
|
|
import CscListActionButton from 'components/CscListActionButton'
|
|
import CscListActions from 'components/CscListActions'
|
|
import CscListSpinner from 'components/CscListSpinner'
|
|
import CscPage from 'components/CscPage'
|
|
import CscRemoveDialog from 'components/CscRemoveDialog'
|
|
import CscPbxDevice from 'components/pages/PbxConfiguration/CscPbxDevice'
|
|
import CscPbxDeviceAddForm from 'components/pages/PbxConfiguration/CscPbxDeviceAddForm'
|
|
import CscPbxDeviceFilters from 'components/pages/PbxConfiguration/CscPbxDeviceFilters'
|
|
import CscFade from 'components/transitions/CscFade'
|
|
import { showGlobalError, showToast } from 'src/helpers/ui'
|
|
import { CreationState, RequestState } from 'src/store/common'
|
|
import {
|
|
mapActions,
|
|
mapGetters,
|
|
mapMutations,
|
|
mapState
|
|
} from 'vuex'
|
|
export default {
|
|
name: 'CscPagePbxDevices',
|
|
components: {
|
|
CscRemoveDialog,
|
|
CscPbxDeviceAddForm,
|
|
CscPbxDeviceFilters,
|
|
CscListActions,
|
|
CscListActionButton,
|
|
CscFade,
|
|
CscPage,
|
|
CscPbxDevice,
|
|
CscListSpinner
|
|
},
|
|
data () {
|
|
return {
|
|
filters: {},
|
|
filtersEnabled: false
|
|
}
|
|
},
|
|
computed: {
|
|
...mapState('pbx', [
|
|
'deviceProfileMap',
|
|
'deviceProfileList',
|
|
'deviceModelList',
|
|
'deviceModelMap',
|
|
'deviceModelImageMap',
|
|
'deviceModelListState',
|
|
'isDeviceModelListStateRequesting',
|
|
'deviceModelError',
|
|
'deviceProfileListState',
|
|
'deviceProfileListError'
|
|
]),
|
|
...mapState('pbxDevices', [
|
|
'deviceRemoving',
|
|
'deviceList',
|
|
'deviceListCurrentPage',
|
|
'deviceListLastPage',
|
|
'deviceListVisibility',
|
|
'deviceCreationState',
|
|
'deviceRemovalState',
|
|
'deviceListState',
|
|
'deviceListError',
|
|
'deviceCreationError'
|
|
]),
|
|
...mapGetters('pbxDevices', [
|
|
'isDeviceListEmpty',
|
|
'isDeviceListRequesting',
|
|
'isDeviceListPaginationActive',
|
|
'isDeviceAddFormDisabled',
|
|
'isDeviceCreating',
|
|
'isDeviceUpdating',
|
|
'isDeviceRemoving',
|
|
'isDeviceLoading',
|
|
'getDeviceRemoveDialogMessage',
|
|
'getDeviceCreationToastMessage',
|
|
'getDeviceUpdateToastMessage',
|
|
'getDeviceRemovalToastMessage'
|
|
]),
|
|
hasFilters () {
|
|
return Object.keys(this.filters).length > 0
|
|
},
|
|
getDeviceIdFromProfile () {
|
|
return (profileId) => {
|
|
const profile = this.getDeviceProfile(profileId)
|
|
return profile && profile.device_id ? profile.device_id : null
|
|
}
|
|
},
|
|
getDeviceProfile () {
|
|
return (profileId) => {
|
|
if (!profileId) {
|
|
return {}
|
|
}
|
|
return this.deviceProfileMap[profileId] || {}
|
|
}
|
|
},
|
|
getDeviceModel () {
|
|
return (profileId) => {
|
|
if (!profileId) {
|
|
return {}
|
|
}
|
|
|
|
const deviceProfile = this.deviceProfileMap[profileId]
|
|
if (!deviceProfile) {
|
|
return {}
|
|
}
|
|
|
|
if (!deviceProfile.device_id) {
|
|
return {}
|
|
}
|
|
|
|
const deviceModel = this.deviceModelMap[deviceProfile.device_id]
|
|
if (!deviceModel) {
|
|
return {}
|
|
}
|
|
|
|
return deviceModel
|
|
}
|
|
},
|
|
getDeviceModelImage () {
|
|
return (profileId) => {
|
|
if (!profileId) {
|
|
return null
|
|
}
|
|
|
|
const deviceProfile = this.deviceProfileMap[profileId]
|
|
if (!deviceProfile) {
|
|
return null
|
|
}
|
|
|
|
if (!deviceProfile.device_id) {
|
|
return null
|
|
}
|
|
|
|
const deviceModelImage = this.deviceModelImageMap[deviceProfile.device_id]
|
|
if (!deviceModelImage) {
|
|
return null
|
|
}
|
|
|
|
return deviceModelImage
|
|
}
|
|
},
|
|
isItemLoading () {
|
|
return (deviceId) => this.isDeviceLoading(deviceId) ||
|
|
this.isDeviceListRequesting ||
|
|
this.isDeviceModelListStateRequesting
|
|
},
|
|
showSpinner () {
|
|
const deviceListDataIsNotReady = this.isDeviceListRequesting && !(this.isDeviceCreating || this.isDeviceRemoving || this.isDeviceUpdating)
|
|
return this.deviceProfileListState === RequestState.requesting || deviceListDataIsNotReady
|
|
}
|
|
},
|
|
watch: {
|
|
deviceCreationState (state) {
|
|
if (state === CreationState.created) {
|
|
this.$scrollTo(this.$parent.$el)
|
|
showToast(this.getDeviceCreationToastMessage)
|
|
} else if (state === CreationState.error) {
|
|
showGlobalError(this.deviceCreationError)
|
|
}
|
|
},
|
|
deviceRemovalState (state) {
|
|
if (state === RequestState.succeeded) {
|
|
this.$scrollTo(this.$parent.$el)
|
|
showToast(this.getDeviceRemovalToastMessage)
|
|
} else if (state === RequestState.failed) {
|
|
showGlobalError(this.deviceRemovalError)
|
|
}
|
|
},
|
|
deviceListState (state) {
|
|
if (state === RequestState.failed) {
|
|
showGlobalError(this.deviceListError)
|
|
}
|
|
},
|
|
deviceModelListState (state) {
|
|
if (state === RequestState.failed) {
|
|
showGlobalError(this.deviceModelError)
|
|
}
|
|
},
|
|
deviceProfileListState (state) {
|
|
if (state === RequestState.failed) {
|
|
showGlobalError(this.deviceProfileListError)
|
|
}
|
|
}
|
|
},
|
|
async created () {
|
|
if (this.deviceProfileList.length === 0) {
|
|
await this.loadProfiles()
|
|
}
|
|
},
|
|
mounted () {
|
|
this.$scrollTo(this.$parent.$el)
|
|
this.loadDeviceListFiltered(this.deviceListCurrentPage || 1)
|
|
},
|
|
methods: {
|
|
...mapActions('pbx', [
|
|
'loadDeviceModel',
|
|
'loadProfileThumbnails',
|
|
'loadProfiles'
|
|
]),
|
|
...mapMutations('pbxDevices', [
|
|
'enableDeviceAddForm',
|
|
'disableDeviceAddForm',
|
|
'deviceRemovalRequesting',
|
|
'deviceRemovalCanceled'
|
|
]),
|
|
...mapActions('pbxDevices', [
|
|
'loadDeviceList',
|
|
'createDevice',
|
|
'removeDevice'
|
|
]),
|
|
loadDeviceListFiltered (page) {
|
|
this.loadDeviceList({
|
|
page: page || 1,
|
|
filters: this.filters
|
|
})
|
|
},
|
|
enableAddForm () {
|
|
this.enableDeviceAddForm()
|
|
this.closeFilters()
|
|
},
|
|
enableFilters () {
|
|
this.filtersEnabled = true
|
|
this.disableDeviceAddForm()
|
|
},
|
|
applyFilter (filterData) {
|
|
this.filters = filterData
|
|
this.loadDeviceListFiltered()
|
|
},
|
|
closeFilters () {
|
|
this.filtersEnabled = false
|
|
this.resetFilters()
|
|
},
|
|
resetFilters () {
|
|
if (this.hasFilters) {
|
|
this.filters = {}
|
|
this.loadDeviceListFiltered()
|
|
}
|
|
},
|
|
openDeviceRemovalDialog (deviceId) {
|
|
if (this.$refs.removeDialog) {
|
|
this.deviceRemovalRequesting(deviceId)
|
|
this.$refs.removeDialog.show()
|
|
}
|
|
},
|
|
closeDeviceRemovalDialog () {
|
|
this.deviceRemovalCanceled()
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="sass" rel="stylesheet/sass">
|
|
</style>
|