From cd7a727f0fc51445d7273786db18a4b166d3bdb9 Mon Sep 17 00:00:00 2001 From: Sebastian Frank Date: Fri, 25 Aug 2017 12:25:19 +0200 Subject: [PATCH] logout handling --- conf/init.json | 5 ++ package.json | 2 +- src/components/logout.vue | 17 ++++ src/components/my-table.vue | 38 ++++++--- src/components/scroll-table.vue | 32 ++++++- src/components/userlist.vue | 4 +- src/main.js | 147 ++++++++++++++++++++------------ 7 files changed, 173 insertions(+), 72 deletions(-) create mode 100644 src/components/logout.vue diff --git a/conf/init.json b/conf/init.json index 1a4892d..3c7c558 100644 --- a/conf/init.json +++ b/conf/init.json @@ -17,6 +17,11 @@ "name": "Userlist", "to": "/userlist", "icon": "fa-news" + }, + { + "name": "Logout", + "to": "/logout", + "icon": "fa-lock" } ] } \ No newline at end of file diff --git a/package.json b/package.json index b3b0a56..8d45c00 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "description": "JS UI for Basispanel Server Management", "main": "index.js", "scripts": { - "serve": "WEBPACK_ENV=dev webpack-dev-server --inline --hot --open", + "serve": "WEBPACK_ENV=dev webpack-dev-server --inline --hot --host 0.0.0.0", "dev": "WEBPACK_ENV=dev webpack --progress --colors --watch", "build": "WEBPACK_ENV=production webpack --colors" }, diff --git a/src/components/logout.vue b/src/components/logout.vue new file mode 100644 index 0000000..a1c3a8d --- /dev/null +++ b/src/components/logout.vue @@ -0,0 +1,17 @@ + + + diff --git a/src/components/my-table.vue b/src/components/my-table.vue index 2a892fb..4ca4555 100644 --- a/src/components/my-table.vue +++ b/src/components/my-table.vue @@ -2,15 +2,19 @@
- - - - - - + + + + + + + + + +
{{ c.heading }}
- {{ r[c.prop] }} - {{ c.render(r) }} -
{{ c.heading }}
+ {{ r[c.prop] }} + {{ c.render(r) }} +
@@ -38,4 +42,18 @@ export default { } } } - \ No newline at end of file + + + diff --git a/src/components/scroll-table.vue b/src/components/scroll-table.vue index 471aad4..b70a4a5 100644 --- a/src/components/scroll-table.vue +++ b/src/components/scroll-table.vue @@ -1,8 +1,10 @@ @@ -56,15 +58,28 @@ export default { watch: { newRows(rows) { rows.forEach(row => { - this.rows.push(row) + this.rowsToPush.push(row); }); this.currentOffset += rows.length; + this.pushRows(); // for transition + }, + loading(l) { + if (!l) { + // delay after loading for visibility observer + setTimeout(() => { + this.loadingDelayed = false; + }, 200); + } else { + this.loadingDelayed = true; + } } }, data() { return { rows: [ ], - currentOffset: this.offset + rowsToPush: [ ], + currentOffset: this.offset, + loadingDelayed: false } }, methods: { @@ -73,6 +88,15 @@ export default { // infinite scrolling this.handler(this.currentOffset, this.limit); } + }, + pushRows() { + let row = this.rowsToPush.shift(); + if (row) { + this.rows.push(row); + setTimeout(() => { + this.pushRows(); + }, 50); + } } } } diff --git a/src/components/userlist.vue b/src/components/userlist.vue index e83572e..cb9fc61 100644 --- a/src/components/userlist.vue +++ b/src/components/userlist.vue @@ -49,9 +49,7 @@ export default { .then(rows => { this.hasMore = (rows.length >= limit); this.newRows = rows; - setTimeout(() => { - this.loading = false; - }, 200); // for oberserver + this.loading = false; }) .catch(error => { this.loading = false; diff --git a/src/main.js b/src/main.js index 44a4132..b77a688 100644 --- a/src/main.js +++ b/src/main.js @@ -7,6 +7,7 @@ import JwtDecode from 'jwt-decode'; import App from './app.vue'; import Dashboard from './components/dashboard.vue'; import LoginForm from './components/forms/login.vue'; +import Logout from './components/logout.vue'; import Userlist from './components/userlist.vue'; Vue.use(VueRouter); @@ -25,6 +26,10 @@ const routes = [ { path: '/userlist', component: Userlist + }, + { + path: '/logout', + component: Logout } ]; @@ -36,35 +41,41 @@ const store = new Vuex.Store({ state: { api: {}, navigation: [], - login: {}, - authToken: '', - jwt: {}, - credentials: {} + persist: { + login: {}, + authToken: '', + jwt: {}, + credentials: {} + } }, mutations: { setAPI(state, payload) { state.api = payload; }, setNavigation(state, payload) { - for (var i=0; i { - console.log(response); - resolve(response.data); + console.log(response); + resolve(response.data); }) .catch(error => { - console.dir(error); - reject(error); + console.dir(error); + reject(error); }) }); }; if (payload.endpoint != 'login') { // no jwt check for login call - + // empty username = not logged in - if (!context.state.credentials.username) { + if (!context.state.persist.credentials.username) { return new Promise((resolve, reject) => { // show login page router.push('/login'); @@ -105,7 +116,7 @@ const store = new Vuex.Store({ } let now = Math.round(Date.now() / 1000); - if ( context.state.jwt.exp < (now + 300) ) { + if (context.state.persist.jwt.exp < (now + 300)) { // too old jwt, logout return new Promise((resolve, reject) => { context.commit('clearLogin'); @@ -114,11 +125,11 @@ const store = new Vuex.Store({ }); } - if ( (context.state.jwt.exp - 60) < now ) { + 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.credentials) + return context.dispatch('login', context.state.persist.credentials) .then(() => { console.log("LOOOGIIIINNN"); return doRequest(); @@ -144,43 +155,71 @@ const store = new Vuex.Store({ resolve(data.User); }) .catch(error => { - if (error.response && error.response.data && error.response.data.error) { - reject(error.response.data.error); - } else { - reject([]); - } + 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 init Axios.get('conf/init.json') - .then(results => { - // set navigation - if ( !Array.isArray(results.data.navigation) ) { - alert('invalid data in: ' + this.src); - return; - } - store.commit("setNavigation", results.data.navigation); + .then(results => { + // set navigation + if (!Array.isArray(results.data.navigation)) { + alert('invalid data in init.json'); + return; + } + store.commit("setNavigation", results.data.navigation); - // set api config in store - store.commit("setAPI", results.data.api); + // set api config in store + store.commit("setAPI", results.data.api); - // load app, when init finishs - new Vue({ - el: '#vue-app', - components: { - App - }, - data: { - navItems: store.state.navigation - }, - router, - store - }); - }) - .catch(error => { - alert('error loading: ' + error.message); - }); \ No newline at end of file + // load app, when init finishs + new Vue({ + el: '#vue-app', + components: { + App + }, + data: { + navItems: store.state.navigation + }, + router, + store + }); + }) + .catch(error => { + alert('error loading: ' + error.message); + }); \ No newline at end of file