TT#80753 Use a smaller preview version of each PBX device image in order to save bandwidth and improve render performance
Change-Id: I84b03ad7146af767ae9c6bb0e336fca2ce8f5874mr9.1.1
parent
b038c533d8
commit
075452c698
@ -0,0 +1,65 @@
|
|||||||
|
<template>
|
||||||
|
<csc-page
|
||||||
|
:style="pageStyle"
|
||||||
|
>
|
||||||
|
<q-page-sticky
|
||||||
|
ref="pageSticky"
|
||||||
|
class="bg-secondary q-pt-md"
|
||||||
|
style="z-index: 10"
|
||||||
|
expand
|
||||||
|
position="top"
|
||||||
|
>
|
||||||
|
<slot
|
||||||
|
name="header"
|
||||||
|
/>
|
||||||
|
<q-separator />
|
||||||
|
<div
|
||||||
|
class="col-12"
|
||||||
|
>
|
||||||
|
<slot
|
||||||
|
name="toolbar"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<q-resize-observer
|
||||||
|
@resize="computeTopMargin"
|
||||||
|
/>
|
||||||
|
</q-page-sticky>
|
||||||
|
<slot />
|
||||||
|
</csc-page>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import CscPage from 'components/CscPage'
|
||||||
|
export default {
|
||||||
|
name: 'CscPageSticky',
|
||||||
|
components: {
|
||||||
|
CscPage
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
topMargin: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
pageStyle () {
|
||||||
|
return {
|
||||||
|
paddingTop: this.topMargin + 'px'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
this.computeTopMargin()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
input ($event) {
|
||||||
|
this.$emit('input', $event)
|
||||||
|
this.computeTopMargin()
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.computeTopMargin()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
computeTopMargin () {
|
||||||
|
this.topMargin = this.$refs.pageSticky.$el.offsetHeight + 36
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -0,0 +1,94 @@
|
|||||||
|
<template>
|
||||||
|
<csc-input
|
||||||
|
ref="input"
|
||||||
|
v-bind="$attrs"
|
||||||
|
:type="inputType"
|
||||||
|
:value="value"
|
||||||
|
@input="$emit('input', $event)"
|
||||||
|
v-on="$listeners"
|
||||||
|
>
|
||||||
|
<template
|
||||||
|
slot="prepend"
|
||||||
|
>
|
||||||
|
<q-icon
|
||||||
|
name="lock"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template
|
||||||
|
v-slot:append
|
||||||
|
>
|
||||||
|
<q-btn
|
||||||
|
v-if="value !== ''"
|
||||||
|
:icon="icon"
|
||||||
|
:disable="$attrs.disable"
|
||||||
|
tabindex="-1"
|
||||||
|
color="primary"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
@click.stop="visible=!visible"
|
||||||
|
/>
|
||||||
|
<q-btn
|
||||||
|
v-if="generate"
|
||||||
|
icon="casino"
|
||||||
|
:disable="$attrs.disable"
|
||||||
|
tabindex="-1"
|
||||||
|
color="primary"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
@click.stop="generatePassword"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</csc-input>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import CscInput from 'components/form/CscInput'
|
||||||
|
import PasswordGenerator from 'generate-password'
|
||||||
|
export default {
|
||||||
|
name: 'CscInputPassword',
|
||||||
|
components: { CscInput },
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
type: String,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
generate: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
inputType () {
|
||||||
|
if (this.visible) {
|
||||||
|
return 'text'
|
||||||
|
} else {
|
||||||
|
return 'password'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
icon () {
|
||||||
|
if (!this.visible) {
|
||||||
|
return 'visibility_off'
|
||||||
|
} else {
|
||||||
|
return 'visibility'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
generatePassword () {
|
||||||
|
const pass = PasswordGenerator.generate({
|
||||||
|
length: 10,
|
||||||
|
numbers: true
|
||||||
|
})
|
||||||
|
this.$emit('input', pass)
|
||||||
|
this.$emit('generated', pass)
|
||||||
|
},
|
||||||
|
clear () {
|
||||||
|
this.$refs.input.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -0,0 +1,144 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="csc-input-password-retype"
|
||||||
|
>
|
||||||
|
<csc-input-password
|
||||||
|
v-model="password"
|
||||||
|
v-bind="$attrs"
|
||||||
|
generate
|
||||||
|
clearable
|
||||||
|
:label="$t('pbxConfig.typePassword')"
|
||||||
|
@input="inputPassword"
|
||||||
|
@generated="passwordGenerated"
|
||||||
|
@clear="$refs.passwordRetype.clear()"
|
||||||
|
/>
|
||||||
|
<password-strength-meter
|
||||||
|
v-show="false"
|
||||||
|
v-model="password"
|
||||||
|
:strength-meter-only="true"
|
||||||
|
@score="strengthMeterScoreUpdate"
|
||||||
|
/>
|
||||||
|
<q-linear-progress
|
||||||
|
v-model="passwordScoreMappedValue"
|
||||||
|
:color="passwordScoreColor"
|
||||||
|
size="8px"
|
||||||
|
/>
|
||||||
|
<csc-input-password
|
||||||
|
ref="passwordRetype"
|
||||||
|
v-model="passwordRetype"
|
||||||
|
v-bind="$attrs"
|
||||||
|
:label="$t('pbxConfig.retypePassword')"
|
||||||
|
:error="$v.passwordRetype.$error"
|
||||||
|
:error-message="errorMessagePasswordRetype"
|
||||||
|
clearable
|
||||||
|
:disable="passwordScore < 2 || $attrs.disable"
|
||||||
|
@clear="$v.passwordRetype.$reset"
|
||||||
|
@blur="blur"
|
||||||
|
@input="inputRetypePassword"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
sameAs,
|
||||||
|
required
|
||||||
|
} from 'vuelidate/lib/validators'
|
||||||
|
import CscInputPassword from 'components/form/CscInputPassword'
|
||||||
|
import PasswordStrengthMeter from 'vue-password-strength-meter'
|
||||||
|
export default {
|
||||||
|
name: 'CscInputPasswordRetype',
|
||||||
|
components: {
|
||||||
|
CscInputPassword,
|
||||||
|
PasswordStrengthMeter
|
||||||
|
},
|
||||||
|
validations: {
|
||||||
|
password: {
|
||||||
|
required
|
||||||
|
},
|
||||||
|
passwordRetype: {
|
||||||
|
sameAsPassword: sameAs('password')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
type: Object,
|
||||||
|
default () {
|
||||||
|
return {
|
||||||
|
password: '',
|
||||||
|
passwordRetype: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
password: this.value.password,
|
||||||
|
passwordRetype: this.value.passwordRetype,
|
||||||
|
passwordScore: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
errorMessagePasswordRetype () {
|
||||||
|
if (!this.$v.passwordRetype.sameAsPassword) {
|
||||||
|
return this.$t('pbxConfig.errorPasswordNotEqual')
|
||||||
|
} else {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
passwordScoreMappedValue () {
|
||||||
|
if (this.passwordScore === null || this.passwordScore === undefined) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return (this.passwordScore + 1) / 5
|
||||||
|
},
|
||||||
|
passwordScoreColor () {
|
||||||
|
if (this.passwordScore < 2) {
|
||||||
|
return 'negative'
|
||||||
|
} else if (this.passwordScore === 2) {
|
||||||
|
return 'warning'
|
||||||
|
} else {
|
||||||
|
return 'primary'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
value (value) {
|
||||||
|
this.password = value.password
|
||||||
|
this.passwordRetype = value.passwordRetype
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
strengthMeterScoreUpdate (score) {
|
||||||
|
this.passwordScore = score
|
||||||
|
this.$emit('score', score)
|
||||||
|
},
|
||||||
|
inputPassword () {
|
||||||
|
this.$emit('input', {
|
||||||
|
password: this.password,
|
||||||
|
passwordRetype: this.passwordRetype
|
||||||
|
})
|
||||||
|
},
|
||||||
|
inputRetypePassword () {
|
||||||
|
this.$v.passwordRetype.$reset()
|
||||||
|
this.inputPassword()
|
||||||
|
},
|
||||||
|
passwordGenerated (password) {
|
||||||
|
this.$emit('input', {
|
||||||
|
password: password,
|
||||||
|
passwordRetype: password
|
||||||
|
})
|
||||||
|
},
|
||||||
|
blur () {
|
||||||
|
this.$v.passwordRetype.$touch()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" rel="stylesheet/stylus">
|
||||||
|
.csc-input-password-retype
|
||||||
|
.Password__strength-meter
|
||||||
|
margin 0
|
||||||
|
margin-top 16px !important
|
||||||
|
margin-bottom 16px !important
|
||||||
|
</style>
|
@ -0,0 +1,135 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
class="row justify-center full-width q-gutter-x-sm q-pt-sm"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="col-md-2"
|
||||||
|
>
|
||||||
|
<q-select
|
||||||
|
v-model="filterType"
|
||||||
|
emit-value
|
||||||
|
map-options
|
||||||
|
dense
|
||||||
|
:options="filterTypeOptions"
|
||||||
|
:label="$t('pbxConfig.seatsFiltersFilterByLabel')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="col-md-2"
|
||||||
|
>
|
||||||
|
<q-input
|
||||||
|
v-model="typedFilter"
|
||||||
|
type="text"
|
||||||
|
dense
|
||||||
|
:disable="filterType === null"
|
||||||
|
:label="$t('pbxConfig.seatsFilterInputLabel')"
|
||||||
|
@keypress.enter="triggerFilter"
|
||||||
|
>
|
||||||
|
<template
|
||||||
|
v-slot:append
|
||||||
|
>
|
||||||
|
<q-btn
|
||||||
|
icon="search"
|
||||||
|
color="primary"
|
||||||
|
dense
|
||||||
|
flat
|
||||||
|
@click="triggerFilter"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</q-input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="row justify-center full-width q-gutter-x-sm q-pt-sm"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="col-md-4"
|
||||||
|
>
|
||||||
|
<q-chip
|
||||||
|
v-for="(filterItem, index) in filters"
|
||||||
|
:key="index"
|
||||||
|
:label="$t('pbxConfig.seatsFiltersTypes.' + filterItem.name) + ': ' + filterItem.value"
|
||||||
|
:disable="false"
|
||||||
|
icon="filter_alt"
|
||||||
|
removable
|
||||||
|
dense
|
||||||
|
color="primary"
|
||||||
|
text-color="dark"
|
||||||
|
@remove="removeFilter(filterItem.name)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import _ from 'lodash'
|
||||||
|
export default {
|
||||||
|
name: 'CscPbxSeatFilters',
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
filterType: null,
|
||||||
|
typedFilter: '',
|
||||||
|
filters: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
filterTypeOptions () {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: this.$t('pbxConfig.seatsFiltersTypes.display_name'),
|
||||||
|
value: 'display_name'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('pbxConfig.seatsFiltersTypes.pbx_extension'),
|
||||||
|
value: 'pbx_extension'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('pbxConfig.seatsFiltersTypes.primary_number'),
|
||||||
|
value: 'primary_number'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('pbxConfig.seatsFiltersTypes.alias_number'),
|
||||||
|
value: 'alias_number'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
triggerFilter () {
|
||||||
|
this.addFilter(this.filterType, this.typedFilter)
|
||||||
|
},
|
||||||
|
removeFilter (name) {
|
||||||
|
this.filters = this.filters.filter(item => item.name !== name)
|
||||||
|
this.filter()
|
||||||
|
},
|
||||||
|
removeFilters () {
|
||||||
|
if (this.filters.length > 0) {
|
||||||
|
this.filters = []
|
||||||
|
this.filter()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
addFilter (name, value) {
|
||||||
|
const valueTrimmed = _.trim(value)
|
||||||
|
if (valueTrimmed) {
|
||||||
|
this.typedFilter = ''
|
||||||
|
this.filters = this.filters.filter(item => item.name !== name)
|
||||||
|
const filter = {
|
||||||
|
name: name,
|
||||||
|
value: valueTrimmed
|
||||||
|
}
|
||||||
|
this.filters.push(filter)
|
||||||
|
this.filter()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
filter () {
|
||||||
|
const params = {}
|
||||||
|
this.filters.forEach(filter => {
|
||||||
|
params[filter.name] = filter.value
|
||||||
|
})
|
||||||
|
this.$emit('filter', params)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
Loading…
Reference in new issue