vue in main

This commit is contained in:
Sebastian Frank 2017-09-29 15:17:10 +02:00
parent 48291a08e5
commit 0002a899e4
4 changed files with 174 additions and 161 deletions

View File

@ -0,0 +1,13 @@
import MyForm from 'components/my-form.vue';
import MyInput from 'components/my-input.vue';
import TextareaInput from 'components/textarea-input.vue';
import MyTable from 'components/my-table.vue';
import ScrollTable from 'components/scroll-table.vue';
export default {
MyForm,
MyInput,
TextareaInput,
MyTable,
ScrollTable
}

View File

@ -7,7 +7,7 @@
<div class="user_profile" ref="user_profile"> <div class="user_profile" ref="user_profile">
<a class="trigger" @click.prevent="toggleMenu"> <a class="trigger" @click.prevent="toggleMenu">
<div class="image"><i class="icon icon-user" aria-hidden="true"></i></div> <div class="image"><i class="icon icon-user" aria-hidden="true"></i></div>
<div class="text"> {{ loginDisplay }} <div class="role"> {{ loginType }}</div></div> <!-- <div class="text"> {{ loginDisplay }} <div class="role"> {{ loginType }}</div></div> -->
<div class="trigger_btn"><i class="icon icon-arrow-down" aria-hidden="true"></i></div> <div class="trigger_btn"><i class="icon icon-arrow-down" aria-hidden="true"></i></div>
</a> </a>
<nav class="user_menu"> <nav class="user_menu">

View File

@ -1,156 +1,13 @@
import Vue from 'vue';
import Vuex from 'vuex'; import Vuex from 'vuex';
import VueRouter from 'vue-router'; import VueRouter from 'vue-router';
import Axios from 'axios'; import Axios from 'axios';
import JwtDecode from 'jwt-decode'; import JwtDecode from 'jwt-decode';
import App from 'app.vue'; import App from 'app.vue';
import GlobalComponents from 'components/components.js';
import MyForm from 'components/my-form.vue';
import MyInput from 'components/my-input.vue';
import TextareaInput from 'components/textarea-input.vue';
import MyTable from 'components/my-table.vue';
import ScrollTable from 'components/scroll-table.vue';
Vue.use(VueRouter);
Vue.use(Vuex);
Vue.component('my-form', MyForm);
Vue.component('my-input', MyInput);
Vue.component('textarea-input', TextareaInput);
Vue.component('my-table', MyTable);
Vue.component('scroll-table', ScrollTable);
const globalConf = {
loginEndpoint: 'login',
loginRoute: '/login',
authHeader: 'X-Auth-Token',
responseType: 'json',
initUrl: 'conf/init.json',
el: '#my-app'
}
const Router = new VueRouter();
const Store = new Vuex.Store({
state: {
ui: {},
persist: {
login: {},
authToken: '',
jwt: {},
credentials: {}
}
},
mutations: {
setUI(state, payload) {
state.ui = payload;
},
setCredentials(state, payload) {
state.persist.credentials = payload;
objectToPersist(state.persist, 'persistantStore');
},
setLogin(state, payload) {
state.persist.login = payload.User;
state.persist.authToken = payload.AuthToken;
state.persist.jwt = JwtDecode(payload.AuthToken);
objectToPersist(state.persist, 'persistantStore');
},
clearLogin(state) {
state.persist.login = {};
state.persist.authToken = '';
state.persist.jwt = {};
state.persist.credentials = {};
objectToPersist(state.persist, 'persistantStore');
}
},
actions: {
apiRequest(context, payload) {
let doRequest = () => {
return new Promise((resolve, reject) => {
const addHeader = {};
addHeader[globalConf.authHeader] = context.state.persist.authToken;
Axios({
method: payload.method ? payload.method : 'get',
baseURL: context.state.ui.api.baseURL,
url: payload.endpoint,
params: payload.params,
data: payload.data,
headers: addHeader,
responseType: globalConf.responseType
})
.then(response => {
console.log(response);
resolve(response.data);
})
.catch(error => {
console.dir(error);
reject(error);
})
});
};
if (payload.endpoint != globalConf.loginEndpoint) {
// no jwt check for login call
if (!context.state.persist.jwt.exp) {
return new Promise((resolve, reject) => {
// show login page
Router.push(globalConf.loginRoute);
reject(['not logged in']);
});
}
let now = Math.round(Date.now() / 1000);
if (context.state.persist.jwt.exp < (now + 300)) {
// too old jwt, logout
return new Promise((resolve, reject) => {
context.commit('clearLogin');
Router.push(globalConf.loginRoute);
reject(['jwt too old, logout']);
});
}
if ((context.state.persist.jwt.exp - 60) < now) {
// jwt near expire, get new one
console.log("getting new jwt");
return context.dispatch(globalConf.loginEndpoint, context.state.persist.credentials)
.then(() => {
console.log("LOOOGIIIINNN");
return doRequest();
})
.catch(error => {
throw error;
})
}
}
return doRequest();
},
login(context, payload) {
return new Promise((resolve, reject) => {
context.dispatch('apiRequest', {
method: 'post',
endpoint: globalConf.loginEndpoint,
data: payload
})
.then(data => {
context.commit('setCredentials', payload);
context.commit('setLogin', data);
resolve(data.User);
})
.catch(error => {
if (error.response && error.response.data && error.response.data.error) {
reject(error.response.data.error);
} else {
reject([]);
}
});
});
}
}
});
function objectToPersist(obj, key) { function objectToPersist(obj, key) {
try { try {
@ -174,20 +31,22 @@ function persistToObject(key) {
} }
} }
// get store persist part from localStorage
let persist = persistToObject('persistantStore');
if (persist) {
Store.state.persist = persist;
}
export default { export default {
Vue, config: {
Router, loginEndpoint: 'login',
Store, loginRoute: '/login',
Axios, authHeader: 'X-Auth-Token',
InitApp(config) { // config: {initUrl, views, el} tokenClaim: 'AuthToken',
Object.assign(globalConf, config); responseType: 'json',
Axios.get(globalConf.initUrl) initUrl: 'conf/init.json',
el: '#vue-app'
},
InitApp(vue, config) { // config: {initUrl, views, el}
Object.assign(this.config, config);
var $this = this;
Axios.get($this.config.initUrl)
.then(results => { .then(results => {
// set navigation // set navigation
if (!Array.isArray(results.data.routes)) { if (!Array.isArray(results.data.routes)) {
@ -195,6 +54,145 @@ export default {
return; return;
} }
// register global components
for (var prop in GlobalComponents) {
vue.component(prop, GlobalComponents[prop]);
}
vue.use(VueRouter);
const Router = new VueRouter();
vue.use(Vuex);
const Store = new Vuex.Store({
state: {
ui: {},
persist: {
login: {},
authToken: '',
jwt: {},
credentials: {}
}
},
mutations: {
setUI(state, payload) {
state.ui = payload;
},
setCredentials(state, payload) {
state.persist.credentials = payload;
objectToPersist(state.persist, 'persistantStore');
},
setLogin(state, payload) {
state.persist.login = payload.User;
state.persist.authToken = payload[$this.config.tokenClaim];
state.persist.jwt = JwtDecode(payload[$this.config.tokenClaim]);
objectToPersist(state.persist, 'persistantStore');
},
clearLogin(state) {
state.persist.login = {};
state.persist.authToken = '';
state.persist.jwt = {};
state.persist.credentials = {};
objectToPersist(state.persist, 'persistantStore');
}
},
actions: {
apiRequest(context, payload) {
let doRequest = () => {
return new Promise((resolve, reject) => {
const addHeader = {};
addHeader[$this.config.authHeader] = context.state.persist.authToken;
Axios({
method: payload.method ? payload.method : 'get',
baseURL: context.state.ui.api.baseURL,
url: payload.endpoint,
params: payload.params,
data: payload.data,
headers: addHeader,
responseType: $this.config.responseType
})
.then(response => {
console.log(response);
resolve(response.data);
})
.catch(error => {
console.dir(error);
reject(error);
})
});
};
if (payload.endpoint != $this.config.loginEndpoint) {
// no jwt check for login call
if (!context.state.persist.jwt.exp) {
return new Promise((resolve, reject) => {
// show login page
Router.push($this.config.loginRoute);
reject(['not logged in']);
});
}
let now = Math.round(Date.now() / 1000);
if (context.state.persist.jwt.exp < (now + 300)) {
// too old jwt, logout
return new Promise((resolve, reject) => {
context.commit('clearLogin');
Router.push($this.config.loginRoute);
reject(['jwt too old, logout']);
});
}
if ((context.state.persist.jwt.exp - 60) < now) {
// jwt near expire, get new one
console.log("getting new jwt");
return context.dispatch($this.config.loginEndpoint, context.state.persist.credentials)
.then(() => {
console.log("LOOOGIIIINNN");
return doRequest();
})
.catch(error => {
throw error;
})
}
}
return doRequest();
},
login(context, payload) {
return new Promise((resolve, reject) => {
context.dispatch('apiRequest', {
method: 'post',
endpoint: $this.config.loginEndpoint,
data: payload
})
.then(data => {
context.commit('setCredentials', payload);
context.commit('setLogin', data);
resolve(data.User);
})
.catch(error => {
if (error.response && error.response.data && error.response.data.error) {
reject(error.response.data.error);
} else {
reject([]);
}
});
});
}
}
});
// get store persist part from localStorage
let persist = persistToObject('persistantStore');
if (persist) {
Store.state.persist = persist;
}
// set ui config in store // set ui config in store
Store.commit("setUI", results.data.ui); Store.commit("setUI", results.data.ui);
@ -209,7 +207,7 @@ export default {
}, },
component: { component: {
template: '<div id="' + name + rIdx + '">' + content + '</div>', template: '<div id="' + name + rIdx + '">' + content + '</div>',
components: globalConf.views, components: this.config.views,
data: function (data) { data: function (data) {
if (typeof data != 'object') { if (typeof data != 'object') {
return () => { return {}; }; return () => { return {}; };
@ -225,12 +223,13 @@ export default {
}); });
// load app, when init finishs // load app, when init finishs
new Vue({ return new vue({
el: globalConf.el, el: this.config.el,
render: h => h(App), render: h => h(App),
router: Router, router: Router,
store: Store store: Store
}); });
}) })
.catch(error => { .catch(error => {
alert('error loading: ' + error.message); alert('error loading: ' + error.message);

View File

@ -1,9 +1,10 @@
import Vue from 'vue';
import BaseUI from './lib/baseui.js'; import BaseUI from './lib/baseui.js';
import Views from './views/views.js'; import Views from './views/views.js';
// load init // load init
BaseUI.InitApp({ BaseUI.InitApp(Vue, {
el: '#vue-app', el: '#vue-app',
initUrl: 'conf/init.json', initUrl: 'conf/init.json',
views: Views views: Views