diff --git a/src/components/CscDialogBase.vue b/src/components/CscDialogBase.vue new file mode 100644 index 00000000..e982dbee --- /dev/null +++ b/src/components/CscDialogBase.vue @@ -0,0 +1,91 @@ +<template> + <q-dialog + ref="dialog" + v-bind="$attrs" + v-on="$listeners" + @hide="$emit('hide', $event)" + > + <q-card + class="bg-main-menu q-dialog-plugin" + > + <q-card-section + class="text-h6" + > + <q-icon + v-if="icon !== undefined" + :name="icon" + size="24px" + class="self-center" + /> + {{ title }} + </q-card-section> + <q-card-section> + <slot /> + </q-card-section> + <q-card-actions + align="right" + > + <q-btn + icon="clear" + :label="$t('buttons.cancel')" + flat + @click="hide" + /> + <q-btn + icon="check" + :label="$t('buttons.confirm')" + unelevated + text-color="dark" + color="primary" + :disable="!ready" + @click="okEvent" + /> + </q-card-actions> + </q-card> + </q-dialog> +</template> + +<script> +export default { + name: 'CscDialogBase', + components: { + }, + props: { + icon: { + type: String, + default: undefined + }, + title: { + type: String, + default: undefined + }, + ready: { + type: Boolean, + default: true + } + }, + data () { + return { + passwordRetype: { + password: '', + passwordRetype: '' + } + } + }, + methods: { + show () { + this.$refs.dialog.show() + }, + hide () { + this.$refs.dialog.hide() + }, + okEvent ($event) { + this.$emit('ok', $event) + this.hide() + }, + cancelEvent ($event) { + this.hide() + } + } +} +</script> diff --git a/src/components/CscDialogChangePassword.vue b/src/components/CscDialogChangePassword.vue new file mode 100644 index 00000000..c8cb2a4f --- /dev/null +++ b/src/components/CscDialogChangePassword.vue @@ -0,0 +1,58 @@ +<template> + <csc-dialog-base + ref="dialog" + icon="vpn_key" + title="Change Password" + :ready="ready" + v-bind="$attrs" + v-on="$listeners" + @hide="$emit('hide', $event)" + @ok="ok" + > + <template + v-slot:title + > + Change Password + </template> + <csc-input-password-retype + v-model="passwordRetype" + dense + @validation-failed="ready=false" + @validation-succeeded="ready=true" + /> + </csc-dialog-base> +</template> + +<script> +import CscInputPasswordRetype from 'components/form/CscInputPasswordRetype' +import CscDialogBase from 'components/CscDialogBase' +export default { + name: 'CscDialogChangePassword', + components: { + CscDialogBase, + CscInputPasswordRetype + }, + data () { + return { + ready: false, + passwordRetype: { + password: '', + passwordRetype: '' + } + } + }, + methods: { + show () { + this.$refs.dialog.show() + }, + hide () { + this.$refs.dialog.hide() + }, + ok () { + if (this.ready) { + this.$emit('confirmed', this.passwordRetype.password) + } + } + } +} +</script> diff --git a/src/components/CscPageSticky.vue b/src/components/CscPageSticky.vue index 62982ce4..26f8b7ee 100644 --- a/src/components/CscPageSticky.vue +++ b/src/components/CscPageSticky.vue @@ -58,7 +58,7 @@ export default { }) }, computeTopMargin () { - this.topMargin = this.$refs.pageSticky.$el.offsetHeight + 36 + this.topMargin = this.$refs.pageSticky.$el.offsetHeight } } } diff --git a/src/components/CscPopupMenu.vue b/src/components/CscPopupMenu.vue index bc141cf3..834c0116 100644 --- a/src/components/CscPopupMenu.vue +++ b/src/components/CscPopupMenu.vue @@ -2,6 +2,7 @@ <q-popup-proxy> <q-list v-bind="$attrs" + class="bg-main-menu" v-on="$listeners" > <slot /> diff --git a/src/components/form/CscInputPasswordRetype.vue b/src/components/form/CscInputPasswordRetype.vue index 6fc08bd7..a3cb8e59 100644 --- a/src/components/form/CscInputPasswordRetype.vue +++ b/src/components/form/CscInputPasswordRetype.vue @@ -3,6 +3,7 @@ class="csc-input-password-retype" > <csc-input-password + ref="password" v-model="password" v-bind="$attrs" generate @@ -10,7 +11,7 @@ :label="$t('pbxConfig.typePassword')" @input="inputPassword" @generated="passwordGenerated" - @clear="$refs.passwordRetype.clear()" + @clear="passwordClear" /> <password-strength-meter v-show="false" @@ -33,7 +34,7 @@ clearable :disable="passwordScore < 2 || $attrs.disable" @clear="$v.passwordRetype.$reset" - @blur="blur" + @blur="passwordRetypeBlur" @input="inputRetypePassword" /> </div> @@ -56,6 +57,7 @@ export default { required }, passwordRetype: { + required, sameAsPassword: sameAs('password') } }, @@ -105,8 +107,19 @@ export default { value (value) { this.password = value.password this.passwordRetype = value.passwordRetype + }, + passwordScore (score) { + if (score < 2) { + this.$refs.passwordRetype.clear() + this.$v.$reset() + } } }, + mounted () { + this.$v.$reset() + this.$refs.passwordRetype.clear() + this.$refs.password.clear() + }, methods: { strengthMeterScoreUpdate (score) { this.passwordScore = score @@ -119,7 +132,7 @@ export default { }) }, inputRetypePassword () { - this.$v.passwordRetype.$reset() + this.validate() this.inputPassword() }, passwordGenerated (password) { @@ -127,9 +140,25 @@ export default { password: password, passwordRetype: password }) + this.$nextTick(() => { + this.validate() + }) }, - blur () { - this.$v.passwordRetype.$touch() + passwordClear () { + this.$refs.passwordRetype.clear() + this.validate() + this.$v.$reset() + }, + passwordRetypeBlur () { + this.validate() + }, + validate () { + this.$v.$touch() + if (!this.$v.$invalid) { + this.$emit('validation-succeeded') + } else { + this.$emit('validation-failed') + } } } } diff --git a/src/components/pages/PbxConfiguration/CscPbxSeat.vue b/src/components/pages/PbxConfiguration/CscPbxSeat.vue index 23a635bb..61a68620 100644 --- a/src/components/pages/PbxConfiguration/CscPbxSeat.vue +++ b/src/components/pages/PbxConfiguration/CscPbxSeat.vue @@ -1,8 +1,9 @@ <template> <q-expansion-item group="seats" - header-class="q-pa-md" + header-class="q-pa-sm" active-class="csc-item-odd" + dense-toggle > <template slot="header" @@ -57,9 +58,8 @@ > <q-icon class="self-center" - name="info" - color="info" - size="24px" + name="group" + size="16px" /> {{ $t('pbxConfig.noGroupAssigned') }} </span> @@ -67,6 +67,7 @@ </q-item-section> <q-item-section side + top > <csc-more-menu> <csc-popup-menu-item @@ -232,6 +233,10 @@ @click="jumpToCallQueue" /> </div> + <csc-dialog-change-password + ref="dialogChangePassword" + @confirmed="changeWebPassword" + /> </q-expansion-item> </template> @@ -244,9 +249,11 @@ import CscInputButtonReset from 'components/form/CscInputButtonReset' import CscMoreMenu from 'components/CscMoreMenu' import CscPopupMenuItemDelete from 'components/CscPopupMenuItemDelete' import CscPopupMenuItem from 'components/CscPopupMenuItem' +import CscDialogChangePassword from 'components/CscDialogChangePassword' export default { name: 'CscPbxSeat', components: { + CscDialogChangePassword, CscPopupMenuItem, CscPopupMenuItemDelete, CscMoreMenu, @@ -439,14 +446,14 @@ export default { } }, showPasswordDialog () { - this.$refs.changePasswordDialog.open() + this.$refs.dialogChangePassword.show() }, - async changeWebPassword (data) { + async changeWebPassword (password) { await this.$store.dispatch('pbxSeats/setSeatWebPassword', { seatId: this.seat.id, - seatWebPassword: data.password + seatWebPassword: password }) - this.$refs.changePasswordDialog.close() + this.$refs.dialogChangePassword.hide() }, changeIntraPbx () { this.$emit('save-intra-pbx', { diff --git a/src/components/pages/PbxConfiguration/CscPbxSeatAddForm.vue b/src/components/pages/PbxConfiguration/CscPbxSeatAddForm.vue index a059a268..0907ca14 100644 --- a/src/components/pages/PbxConfiguration/CscPbxSeatAddForm.vue +++ b/src/components/pages/PbxConfiguration/CscPbxSeatAddForm.vue @@ -1,10 +1,10 @@ <template> <div> <div - class="row justify-center q-gutter-x-sm q-pt-sm" + class="row justify-center q-gutter-x-sm" > <div - class="col col-3" + class="col-xs-12 col-lg-3" > <csc-input v-model="data.name" @@ -54,7 +54,7 @@ /> </div> <div - class="col col-3" + class="col-xs-12 col-lg-3" > <q-select v-model="data.aliasNumbers" diff --git a/src/components/pages/PbxConfiguration/CscPbxSeatFilters.vue b/src/components/pages/PbxConfiguration/CscPbxSeatFilters.vue index ecc0a313..57054161 100644 --- a/src/components/pages/PbxConfiguration/CscPbxSeatFilters.vue +++ b/src/components/pages/PbxConfiguration/CscPbxSeatFilters.vue @@ -1,10 +1,10 @@ <template> <div> <div - class="row justify-center full-width q-gutter-x-sm q-pt-sm" + class="row justify-center full-width q-gutter-x-sm" > <div - class="col-md-2" + class="col-xs-12 col-md-2" > <q-select v-model="filterType" @@ -16,7 +16,7 @@ /> </div> <div - class="col-md-2" + class="col-xs-12 col-md-2" > <q-input v-model="typedFilter" @@ -41,10 +41,10 @@ </div> </div> <div - class="row justify-center full-width q-gutter-x-sm q-pt-sm" + class="row justify-center full-width q-gutter-x-sm" > <div - class="col-md-4" + class="col-xs-12 col-md-4" > <q-chip v-for="(filterItem, index) in filters" diff --git a/src/components/pages/PbxConfiguration/CscPbxSeats.vue b/src/components/pages/PbxConfiguration/CscPbxSeats.vue index 36965c12..96de5ca1 100644 --- a/src/components/pages/PbxConfiguration/CscPbxSeats.vue +++ b/src/components/pages/PbxConfiguration/CscPbxSeats.vue @@ -34,12 +34,13 @@ <csc-pbx-seat-filters v-if="showFilters" ref="filters" + class="q-mb-md q-pa-md" @filter="filterEvent" /> <csc-pbx-seat-add-form v-if="!isSeatAddFormDisabled" ref="addForm" - class="q-mb-lg" + class="q-mb-md q-pa-md" :loading="isSeatCreating" :group-options="getGroupOptions" :alias-number-options="getNumberOptions" @@ -64,14 +65,14 @@ > <csc-spinner /> </div> - <csc-list + <q-list v-if="!isSeatListEmpty && seatListVisibility === 'visible'" - class="row justify-center" + class="row justify-start" > <csc-pbx-seat v-for="(seat, index) in seatListItems" :key="seat.id" - :class="'col-xs-12 col-md-10 col-lg-8 csc-item-' + ((index % 2 === 0)?'odd':'even')" + :class="'col-xs-12 col-md-6 col-lg-4 csc-item-' + ((index % 2 === 0)?'odd':'even')" :seat="seat" :intra-pbx="getIntraPbx(seat.id)" :groups="groupMapById" @@ -94,7 +95,7 @@ @save-intra-pbx="setIntraPbx" @jump-to-call-queue="jumpToCallQueue" /> - </csc-list> + </q-list> <div v-if="!isSeatListRequesting && isSeatListEmpty" class="row justify-center csc-no-entities" @@ -132,7 +133,7 @@ import { RequestState } from 'src/store/common' import platform from '../../../mixins/platform' -import CscList from '../../CscList' +// import CscList from '../../CscList' import CscPageSticky from 'components/CscPageSticky' import CscPbxSeatFilters from 'components/pages/PbxConfiguration/CscPbxSeatFilters' @@ -143,8 +144,8 @@ export default { CscSpinner, CscPbxSeat, CscPbxSeatAddForm, - CscRemoveDialog, - CscList + CscRemoveDialog + // CscList // CscListActions, // CscListActionButton }, diff --git a/src/css/app.styl b/src/css/app.styl index 856a4bf5..863273d9 100644 --- a/src/css/app.styl +++ b/src/css/app.styl @@ -13,6 +13,8 @@ body.body--dark background-color $secondary .csc-item-odd background-color $item-stripe-color + .csc-item-even + background-color alpha($main-menu-background, 0.2) .q-drawer background-color transparent