TT#23291 Setup: Created page component

Change-Id: Iad155520d956d01476416125ade8786425304f90
changes/80/16080/1
Hans-Peter Herzog 8 years ago
parent 99bd2371fb
commit f01543c323

@ -3,6 +3,7 @@ var path = require('path')
module.exports = { module.exports = {
// Webpack aliases // Webpack aliases
aliases: { aliases: {
'quasar-frameworks': path.resolve(__dirname, '../node_modules/quasar-framework/'),
quasar: path.resolve(__dirname, '../node_modules/quasar-framework/'), quasar: path.resolve(__dirname, '../node_modules/quasar-framework/'),
src: path.resolve(__dirname, '../src'), src: path.resolve(__dirname, '../src'),
assets: path.resolve(__dirname, '../src/assets'), assets: path.resolve(__dirname, '../src/assets'),

@ -5,7 +5,7 @@
</template> </template>
<script> <script>
import { QTransition } from 'quasar' import { QTransition } from 'quasar-framework'
export default { export default {
components: { components: {
QTransition QTransition

@ -3,19 +3,21 @@ import Vue from 'vue';
export function getGroups(options) { export function getGroups(options) {
return new Promise((resolve, reject)=>{ return new Promise((resolve, reject)=>{
Promise.props({ Vue.http.get('/api/subscribers', {
numbers: Vue.http.get('/api/numbers'), params: {
subscribers: Vue.http.get('/api/subscribers', { is_pbx_group: true
params: { }
is_pbx_group: true
}
})
}).then((result)=>{ }).then((result)=>{
var groups = [];
}).then(()=>{ var body = JSON.parse(result.body);
resolve(); if(_.isArray(body["_embedded"]["ngcp:subscribers"])) {
body['_embedded']['ngcp:subscribers'].forEach((group)=>{
groups.push(group);
});
}
resolve(groups);
}).catch((err)=>{ }).catch((err)=>{
reject(err) reject(err);
}); });
}); });
} }

@ -26,13 +26,11 @@ export function getUserData(id) {
return new Promise((resolve, reject)=>{ return new Promise((resolve, reject)=>{
return Promise.all([ return Promise.all([
getSubscriberById(id), getSubscriberById(id),
getCapabilities(), getCapabilities()
getNumbers()
]).then((results)=>{ ]).then((results)=>{
resolve({ resolve({
subscriber: results[0], subscriber: results[0],
capabilities: results[1], capabilities: results[1]
numbers: results[2]
}); });
}).catch((err)=>{ }).catch((err)=>{
reject(err); reject(err);

@ -1,5 +1,11 @@
<template> <template>
<div>404 NotFound</div> <q-layout>
<div id="csc-login" class="row">
<div class="column col-lg-4 col-xl-4 col-md-3 gt-sm"></div>
<div class="column col-12 col-md-6 col-lg-4 col-xl-4">404 NotFound</div>
<div class="column col-lg-4 col-xl-4 col-md-3 gt-sm"></div>
</div>
</q-layout>
</template> </template>
<script> <script>

@ -10,10 +10,20 @@
</q-card-title> </q-card-title>
<q-card-main> <q-card-main>
<q-field icon="fa-user-circle" :helper="$t('username_helper')" :count="128"> <q-field icon="fa-user-circle" :helper="$t('username_helper')" :count="128">
<q-input type="text" max-length="128" :float-label="$t('username')" clearable v-model="username"/> <q-input type="text"
max-length="128"
:float-label="$t('username')"
clearable
v-model="username"
@keyup.enter="login()"/>
</q-field> </q-field>
<q-field icon="fa-lock" :helper="$t('password_helper')" :count="32"> <q-field icon="fa-lock" :helper="$t('password_helper')" :count="32">
<q-input type="password" max-length="32" :float-label="$t('password')" clearable v-model="password"/> <q-input type="password"
max-length="32"
:float-label="$t('password')"
clearable
v-model="password"
@keyup.enter="login()"/>
</q-field> </q-field>
</q-card-main> </q-card-main>
<q-card-actions class="pull-right"> <q-card-actions class="pull-right">
@ -28,19 +38,8 @@
<script> <script>
import { startLoading, stopLoading, showGlobalError } from '../helpers/ui' import { startLoading, stopLoading, showGlobalError } from '../helpers/ui'
import { import { QLayout, QCard, QCardTitle, QCardSeparator, QCardMain, QField, QInput,
QLayout, QCardActions, QBtn, QIcon, Loading, Alert } from 'quasar-framework'
QCard,
QCardTitle,
QCardSeparator,
QCardMain,
QField,
QInput,
QCardActions,
QBtn,
QIcon,
Loading,
Alert } from 'quasar'
export default { export default {
name: 'login', name: 'login',
components: { components: {
@ -57,14 +56,17 @@
}, },
data () { data () {
return { return {
user: '', username: '',
pass: '' password: ''
} }
}, },
methods: { methods: {
login() { login() {
startLoading(); startLoading();
this.$store.dispatch('user/login').then(()=>{ this.$store.dispatch('user/login', {
username: this.username,
password: this.password
}).then(()=>{
stopLoading(); stopLoading();
this.$router.push({path : '/'}); this.$router.push({path : '/'});
}).catch((err)=>{ }).catch((err)=>{
@ -72,24 +74,6 @@
showGlobalError(this.$i18n.t('login_error')); showGlobalError(this.$i18n.t('login_error'));
}); });
} }
},
computed: {
username: {
get () {
return this.$store.state.user.username;
},
set (value) {
this.$store.commit('user/updateUsername', value)
}
},
password: {
get () {
return this.$store.state.user.password;
},
set (value) {
this.$store.commit('user/updatePassword', value)
}
}
} }
} }
</script> </script>

@ -0,0 +1,55 @@
<template>
<div class="page">
<q-fixed-position corner="top-left" :offset="[0,0]" class="page-title transition-generic">
<h2>{{ title }}</h2>
</q-fixed-position>
<div class="page-content">
<slot></slot>
</div>
</div>
</template>
<script>
import { QIcon, QFixedPosition } from 'quasar-framework'
export default {
name: 'page',
props: [
'title'
],
data () {
return {}
},
components: {
QIcon,
QFixedPosition
}
}
</script>
<style lang="stylus">
@import '../../src/themes/app.variables.styl';
.page {
padding: 60px;
padding-top: 100px;
}
.page h2 {
margin: 0px;
font-size: 26px;
line-height: 26px;
color: #68A44E;
}
.page .page-title {
right: 0;
padding: 30px;
padding-left: 60px;
background-color: white;
z-index: 1000;
}
.page-title-icon {
margin-right: 10px;
font-size: 24px !important;
}
</style>

@ -9,7 +9,8 @@
<span slot="subtitle"></span> <span slot="subtitle"></span>
</q-toolbar-title> </q-toolbar-title>
<q-btn flat @click="" icon-right="fa-user-circle"> <q-btn flat @click="" icon-right="fa-user-circle">
<span id="user-login-as">{{ $t('loggedInAs') }}</span><span id="user-name">{{ getUsername }}</span> <span id="user-login-as" class="gt-sm">{{ $t('loggedInAs') }}</span>
<span id="user-name" class="gt-xs">{{ getUsername }}</span>
<q-popover ref="popover"> <q-popover ref="popover">
<q-list item-separator link> <q-list item-separator link>
<q-item @click="logout()"> <q-item @click="logout()">
@ -81,7 +82,7 @@
</q-side-link> </q-side-link>
</q-collapsible> </q-collapsible>
</q-list> </q-list>
<q-fixed-position corner="top-right" :offset="[20, 20]"> <q-fixed-position corner="top-right" :offset="[60, 16]" class="page-action-button">
<q-fab color="primary" icon="question answer" active-icon="clear" direction="left" flat> <q-fab color="primary" icon="question answer" active-icon="clear" direction="left" flat>
<q-fab-action color="primary" @click="" icon="fa-fax" flat> <q-fab-action color="primary" @click="" icon="fa-fax" flat>
<q-tooltip anchor="bottom middle" self="top middle" :offset="[0, 15]">{{ $t('sendFax') }}</q-tooltip> <q-tooltip anchor="bottom middle" self="top middle" :offset="[0, 15]">{{ $t('sendFax') }}</q-tooltip>
@ -126,10 +127,14 @@
name: 'default', name: 'default',
mounted: function() { mounted: function() {
this.$refs.layout.showLeft(); this.$refs.layout.showLeft();
// this.$store.dispatch('connectRtcEngine'); if(!this.$store.getters['user/hasUser']) {
}, startLoading();
created: function() { this.$store.dispatch('user/initUser').then(()=>{
this.$store.dispatch('user/initUser'); stopLoading();
}).catch(()=>{
this.logout();
});
}
}, },
components: { components: {
QLayout, QLayout,
@ -172,9 +177,6 @@
if(!this.$store.state.rtcEngineConnected) { if(!this.$store.state.rtcEngineConnected) {
showGlobalError(this.$t('rtcEngineDisconnected')); showGlobalError(this.$t('rtcEngineDisconnected'));
} }
},
navigate(path) {
this.$router.push({path: path});
} }
} }
} }
@ -227,4 +229,20 @@
#user-name { #user-name {
font-weight: bold; font-weight: bold;
} }
.q-card {
margin: 0;
}
.q-card.page {
padding: 15px;
}
.q-card.pbx-group {
margin-bottom: 15px;
}
.page-action-button {
z-index: 1001;
}
</style> </style>

@ -1,11 +1,15 @@
<template> <template>
<div>CallBlocking Incoming</div> <page title="Incoming"></page>
</template> </template>
<script> <script>
import Page from '../../Page'
export default { export default {
data () { data () {
return {} return {}
},
components: {
Page
} }
} }
</script> </script>

@ -1,11 +1,15 @@
<template> <template>
<div>CallBlocking Outgoing</div> <page title="Outgoing"></page>
</template> </template>
<script> <script>
import Page from '../../Page'
export default { export default {
data () { data () {
return {} return {}
},
components: {
Page
} }
} }
</script> </script>

@ -1,11 +1,15 @@
<template> <template>
<div>CallBlocking Privacy</div> <page title="Privacy"></page>
</template> </template>
<script> <script>
import Page from '../../Page'
export default { export default {
data () { data () {
return {} return {}
},
components: {
Page
} }
} }
</script> </script>

@ -1,11 +1,15 @@
<template> <template>
<div>CallForward AfterHours</div> <page title="After Hours"></page>
</template> </template>
<script> <script>
import Page from '../../Page'
export default { export default {
data () { data () {
return {} return {}
},
components: {
Page
} }
} }
</script> </script>

@ -1,11 +1,15 @@
<template> <template>
<div>CallForward Always</div> <page title="Always"></page>
</template> </template>
<script> <script>
import Page from '../../Page'
export default { export default {
data () { data () {
return {} return {}
},
components: {
Page
} }
} }
</script> </script>

@ -1,11 +1,15 @@
<template> <template>
<div>CallForward CompanyHours</div> <page title="Company Hours"></page>
</template> </template>
<script> <script>
import Page from '../../Page'
export default { export default {
data () { data () {
return {} return {}
},
components: {
Page
} }
} }
</script> </script>

@ -1,11 +1,15 @@
<template> <template>
<div>Conversations</div> <page title="Conversations"></page>
</template> </template>
<script> <script>
import Page from '../Page'
export default { export default {
data () { data () {
return {} return {}
},
components: {
Page
} }
} }
</script> </script>

@ -1,11 +1,15 @@
<template> <template>
<div>PBX Devices</div> <page title="Devices"></page>
</template> </template>
<script> <script>
import Page from '../../Page'
export default { export default {
data () { data () {
return {} return {}
},
components: {
Page
} }
} }
</script> </script>

@ -1,14 +1,49 @@
<template> <template>
<div>PBX Groups</div> <page title="PBX Groups"></page>
</template> </template>
<script> <script>
import Page from '../../Page'
import { QChip, QCard, QCardSeparator, QCardTitle, QCardMain,
QIcon, QPopover, QList, QItem, QItemMain } from 'quasar-framework'
import { mapState } from 'vuex'
export default { export default {
components: {
Page,
QChip,
QCard,
QCardSeparator,
QCardTitle,
QCardMain,
QIcon,
QPopover,
QList,
QItem,
QItemMain
},
mounted() {
this.$store.dispatch('pbxGroups/load').then(()=>{
}).catch((err)=>{
});
},
data () { data () {
return {} return {}
} },
computed: {
...mapState({
groups: state => state.pbxGroups.groups,
})
},
} }
</script> </script>
<style> <style lang="stylus">
@import '../../../../src/themes/app.variables.styl';
.number {
color: $primary;
}
</style> </style>

@ -1,11 +1,15 @@
<template> <template>
<div>PBX Seats</div> <page title="Seats"></page>
</template> </template>
<script> <script>
import Page from '../../Page'
export default { export default {
data () { data () {
return {} return {}
},
components: {
Page
} }
} }
</script> </script>

@ -1,11 +1,15 @@
<template> <template>
<div>Reminder</div> <page title="Reminder"></page>
</template> </template>
<script> <script>
import Page from '../Page'
export default { export default {
data () { data () {
return {} return {}
},
components: {
Page
} }
} }
</script> </script>

@ -0,0 +1,5 @@
import Vue from 'vue';
import NumberFilter from './number'
Vue.filter('number', NumberFilter);

@ -0,0 +1,4 @@
export default function(number) {
return '+' + number.cc + number.ac + number.sn;
}

@ -1,5 +1,5 @@
import { Loading, Alert } from 'quasar' import { Loading, Alert } from 'quasar-framework'
export function startLoading() { export function startLoading() {
Loading.show({ delay: 0 }); Loading.show({ delay: 0 });

@ -13,11 +13,12 @@ require(`./themes/app.${__THEME}.styl`)
import _ from 'lodash' import _ from 'lodash'
import Vue from 'vue' import Vue from 'vue'
import VueResource from 'vue-resource' import VueResource from 'vue-resource'
import Quasar from 'quasar' import Quasar from 'quasar-framework'
import { store } from './store' import { store } from './store'
import { i18n, locales } from './i18n' import { i18n, locales } from './i18n'
import router from './router' import router from './router'
import { sync } from 'vuex-router-sync' import { sync } from 'vuex-router-sync'
import filters from './filters'
Vue.use(VueResource); Vue.use(VueResource);

@ -3,7 +3,9 @@
import _ from 'lodash' import _ from 'lodash'
import Vue from 'vue' import Vue from 'vue'
import Vuex from 'vuex' import Vuex from 'vuex'
// import cdk from 'cdk';
import UserModule from './user'
import PbxGroupsModule from './pbx-groups'
var rtcEngineClient = null; var rtcEngineClient = null;
var rtcEngineNetwork = null; var rtcEngineNetwork = null;
@ -12,7 +14,8 @@ Vue.use(Vuex);
export const store = new Vuex.Store({ export const store = new Vuex.Store({
modules: { modules: {
user: require('./user').UserModule user: UserModule,
pbxGroups: PbxGroupsModule
}, },
state: { state: {
rtcEngineConnected: false rtcEngineConnected: false

@ -1,7 +1,8 @@
import { getGroups } from '../../api/pbx-config' import { getGroups } from '../api/pbx-config'
export const PbxGroups = { export default {
namespaced: true,
state: { state: {
groups: [], groups: [],
page: 1 page: 1
@ -10,15 +11,15 @@ export const PbxGroups = {
}, },
mutations: { mutations: {
showGroups: function(state, options) { show: function(state, options) {
state.groups = options.groups; state.groups = options.groups;
} }
}, },
actions: { actions: {
loadGroups: function(context, options) { load: function(context, options) {
return new Promise((resolve, reject)=>{ return new Promise((resolve, reject)=>{
getGroups().then((groups)=>{ getGroups().then((groups)=>{
context.commit('showGroups', { context.commit('show', {
groups: groups groups: groups
}); });
}).catch((err)=>{ }).catch((err)=>{

@ -2,28 +2,22 @@
import _ from 'lodash'; import _ from 'lodash';
import { login, getCapabilities, getUserData} from '../api/user'; import { login, getCapabilities, getUserData} from '../api/user';
import Vue from 'vue';
// import cdk from 'cdk'; export default {
var rtcEngineClient = '';
export const UserModule = {
namespaced: true, namespaced: true,
state: { state: {
username: '',
password: '',
jwt: localStorage.getItem('jwt') || null, jwt: localStorage.getItem('jwt') || null,
subscriberId: localStorage.getItem('subscriberId') || null, subscriberId: localStorage.getItem('subscriberId') || null,
loggedUsername: '',
subscriber: null, subscriber: null,
capabilities: null, capabilities: null
numbers: null
}, },
getters: { getters: {
isLogged(state, getters) { isLogged(state, getters) {
return !_.isEmpty(state.jwt) && !_.isEmpty(state.subscriberId); return !_.isEmpty(state.jwt) && !_.isEmpty(state.subscriberId);
}, },
hasUser(state, getters) {
return state.subscriber !== null;
},
getUsername(state, getters) { getUsername(state, getters) {
if(state.subscriber !== null && !_.isEmpty(state.subscriber.display_name)) { if(state.subscriber !== null && !_.isEmpty(state.subscriber.display_name)) {
return state.subscriber.display_name; return state.subscriber.display_name;
@ -44,32 +38,34 @@ export const UserModule = {
login(state, options) { login(state, options) {
state.jwt = options.jwt; state.jwt = options.jwt;
state.subscriberId = options.subscriberId; state.subscriberId = options.subscriberId;
state.subscriber = options.subscriber;
state.capabilities = options.capabilities;
}, },
setUserData(state, options) { setUserData(state, options) {
state.subscriber = options.subscriber; state.subscriber = options.subscriber;
state.capabilities = options.capabilities; state.capabilities = options.capabilities;
state.numbers = options.numbers;
}, },
logout(state) { logout(state) {
state.jwt = null; state.jwt = null;
state.subscriberId = null; state.subscriberId = null;
}, state.subscriber = null;
updatePassword (state, password) { state.capabilities = null;
state.password = password;
},
updateUsername (state, username) {
state.username = username;
} }
}, },
actions: { actions: {
login(context) { login(context, options) {
return new Promise((resolve, reject)=>{ return new Promise((resolve, reject)=>{
login(context.state.username, context.state.password).then((result)=>{ login(options.username, options.password).then((result)=>{
localStorage.setItem('jwt', result.jwt); localStorage.setItem('jwt', result.jwt);
localStorage.setItem('subscriberId', result.subscriberId); localStorage.setItem('subscriberId', result.subscriberId);
}).then(()=>{
return getUserData(localStorage.getItem('subscriberId'));
}).then((result)=>{
context.commit('login', { context.commit('login', {
jwt: localStorage.getItem('jwt'), jwt: localStorage.getItem('jwt'),
subscriberId: localStorage.getItem('subscriberId') subscriberId: localStorage.getItem('subscriberId'),
subscriber: result.subscriber,
capabilities: result.capabilities
}); });
resolve(); resolve();
}).catch((err)=>{ }).catch((err)=>{
@ -93,8 +89,7 @@ export const UserModule = {
getUserData(localStorage.getItem('subscriberId')).then((result)=>{ getUserData(localStorage.getItem('subscriberId')).then((result)=>{
context.commit('setUserData', { context.commit('setUserData', {
subscriber: result.subscriber, subscriber: result.subscriber,
capabilities: result.capabilities, capabilities: result.capabilities
numbers: result.numbers
}); });
resolve(); resolve();
}).catch((err)=>{ }).catch((err)=>{

@ -0,0 +1,13 @@
import Vue from 'vue'
import Login from '../../src/components/Login.vue'
import { assert } from 'chai';
describe('Login', function() {
it('should initialize with default data', function(){
var defaultData = Login.data();
assert.equal(defaultData.username, '');
assert.equal(defaultData.password, '');
});
});

@ -1,6 +1,6 @@
'use strict'; 'use strict';
import { UserModule } from '../../src/store/user'; import UserModule from '../../src/store/user';
import { assert } from 'chai'; import { assert } from 'chai';
describe('UserModule', ()=>{ describe('UserModule', ()=>{

Loading…
Cancel
Save