global components, baseui lib

This commit is contained in:
Sebastian Frank 2017-09-25 11:48:53 +02:00
parent 3746ca0fa7
commit 606847d2db
8 changed files with 194 additions and 209 deletions

180
src/baseui.js Normal file
View File

@ -0,0 +1,180 @@
import Vue from 'vue';
import Vuex from 'vuex';
import VueRouter from 'vue-router';
import Axios from 'axios';
import JwtDecode from 'jwt-decode';
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 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 = {
username: payload.username,
password: payload.password
};
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) => {
Axios({
method: payload.method ? payload.method : 'get',
baseURL: context.state.ui.api.baseURL,
url: payload.endpoint,
params: payload.params,
data: payload.data,
headers: {
'X-Auth-Token': context.state.persist.authToken
}
})
.then(response => {
console.log(response);
resolve(response.data);
})
.catch(error => {
console.dir(error);
reject(error);
})
});
};
if (payload.endpoint != 'login') {
// no jwt check for login call
// empty username = not logged in
if (!context.state.persist.credentials.username) {
return new Promise((resolve, reject) => {
// show login page
Router.push('/login');
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('/login');
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('login', 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: 'login',
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) {
try {
const serialized = JSON.stringify(obj);
localStorage.setItem(key ? key : 'persistant', serialized);
} catch (error) {
console.error(error);
}
}
function persistToObject(key) {
try {
const serialized = localStorage.getItem(key ? key : 'persistant');
if (serialized === null) {
return undefined;
}
return JSON.parse(serialized);
} catch (error) {
console.log(error);
return undefined;
}
}
// get store persist part from localStorage
let persist = persistToObject('persistantStore');
if (persist) {
Store.state.persist = persist;
}
export default {
Vue,
Router,
Store,
Axios
};

View File

@ -23,7 +23,6 @@
<script>
export default {
name: "MyForm",
components: {},
props: {
elements: {
type: Object,

View File

@ -14,9 +14,6 @@
</template>
<script>
import MyTable from 'components/my-table';
import MyInput from 'components/my-input';
import { ObserveVisibility } from 'vue-observe-visibility/dist/vue-observe-visibility';
import { debounce } from 'lib/util';
@ -25,10 +22,6 @@ export default {
directives: {
ObserveVisibility
},
components: {
MyTable,
MyInput
},
props: {
actions: {
type: Array,

View File

@ -1,173 +1,12 @@
import Vue from 'vue';
import Vuex from 'vuex';
import VueRouter from 'vue-router';
import Axios from 'axios';
import JwtDecode from 'jwt-decode';
import BaseUI from './baseui.js';
import App from './app.vue';
// import Views from './views/views.js';
Vue.use(VueRouter);
Vue.use(Vuex);
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 = {
username: payload.username,
password: payload.password
};
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) => {
Axios({
method: payload.method ? payload.method : 'get',
baseURL: context.state.ui.api.baseURL,
url: payload.endpoint,
params: payload.params,
data: payload.data,
headers: {
'X-Auth-Token': context.state.persist.authToken
}
})
.then(response => {
console.log(response);
resolve(response.data);
})
.catch(error => {
console.dir(error);
reject(error);
})
});
};
if (payload.endpoint != 'login') {
// no jwt check for login call
// empty username = not logged in
if (!context.state.persist.credentials.username) {
return new Promise((resolve, reject) => {
// show login page
router.push('/login');
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('/login');
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('login', 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: 'login',
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) {
try {
const serialized = JSON.stringify(obj);
localStorage.setItem(key ? key : 'persistant', serialized);
} catch (error) {
console.error(error);
}
}
function persistToObject(key) {
try {
const serialized = localStorage.getItem(key ? key : 'persistant');
if (serialized === null) {
return undefined;
}
return JSON.parse(serialized);
} catch (error) {
console.log(error);
return undefined;
}
}
// get store persist part from localStorage
let persist = persistToObject('persistantStore');
if (persist) {
store.state.persist = persist;
}
// load views
import(/* webpackChunkName: "views" */ './views/views.js').then(Views => {
// load init
Axios.get('conf/init.json')
BaseUI.Axios.get('conf/init.json')
.then(results => {
// set navigation
if (!Array.isArray(results.data.routes)) {
@ -176,7 +15,7 @@ import(/* webpackChunkName: "views" */ './views/views.js').then(Views => {
}
// set ui config in store
store.commit("setUI", results.data.ui);
BaseUI.Store.commit("setUI", results.data.ui);
// add routes
let routes = [];
@ -198,18 +37,18 @@ import(/* webpackChunkName: "views" */ './views/views.js').then(Views => {
}(data)
}
}));
router.addRoutes(routes);
router.beforeEach((to, from, next) => {
BaseUI.Router.addRoutes(routes);
BaseUI.Router.beforeEach((to, from, next) => {
document.title = (to.meta && to.meta.title) ? results.data.ui.title + ': ' + to.meta.title : results.data.title;
next();
});
// load app, when init finishs
new Vue({
new BaseUI.Vue({
el: '#vue-app',
render: h => h(App),
router,
store
router: BaseUI.Router,
store: BaseUI.Store
});
})
.catch(error => {

View File

@ -17,22 +17,15 @@
</template>
<script>
import MyForm from "components/my-form";
import MyInput from "components/my-input";
export default {
name: "LoginForm",
components: {
MyForm,
MyInput
},
data() {
return {
username: "",
password: "",
elements: {
username: {
element: MyInput,
element: "my-input",
icon: "icon-user",
required: true,
requiredMessage: "Der Benutzername wird benötigt!",
@ -42,7 +35,7 @@ export default {
}
},
password: {
element: MyInput,
element: "my-input",
icon: "icon-key",
required: true,
requiredMessage: "Das Passwort wird benötigt!",

View File

@ -105,17 +105,8 @@
</template>
<script>
import MyForm from "components/my-form";
import MyInput from "components/my-input";
import TextareaInput from "components/textarea-input";
export default {
name: "FormDemo",
components: {
MyForm,
MyInput,
TextareaInput
},
data() {
return {
username: "",
@ -124,7 +115,7 @@ export default {
title: {
label: "Titel",
required: true,
element: MyInput,
element: "my-input",
props: {
type: "text",
placeholder: "Titel hier eintragen"
@ -134,7 +125,7 @@ export default {
label: "Permalink",
description: "Hier steht ein Beschreibungstext für etwas begriffsstutzige Menschen, die eine Beschreibung zum Befüllen des Feldes brauchen.",
required: true,
element: MyInput,
element: "my-input",
props: {
type: "text",
placeholder: "Permalink"
@ -144,7 +135,7 @@ export default {
label: "Inhalt",
description: "Hier steht ein Beschreibungstext für etwas begriffsstutzige Menschen, die eine Beschreibung zum Befüllen des Feldes brauchen.",
required: true,
element: TextareaInput,
element: "textarea-input",
props: {
placeholder: "Inhalt"
}
@ -152,7 +143,7 @@ export default {
public: {
label: "Is Public",
required: true,
element: MyInput,
element: "my-input",
props: {
type: "checkbox"
}

View File

@ -6,13 +6,8 @@
</template>
<script>
import ScrollTable from 'components/scroll-table.vue';
export default {
name: "Domainlist",
components: {
ScrollTable
},
data() {
return {
actions: [{

View File

@ -6,13 +6,8 @@
</template>
<script>
import ScrollTable from 'components/scroll-table.vue';
export default {
name: "Userlist",
components: {
ScrollTable
},
data() {
return {
actions: [{