added recorder status component and other stuff

This commit is contained in:
2019-10-31 16:11:53 +01:00
parent 5505e823c4
commit 5792af21a5
10 changed files with 4096 additions and 3877 deletions

7002
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -31,10 +31,10 @@
<b-nav-item v-if="authenticated" to="/logout">Logout</b-nav-item> <b-nav-item v-if="authenticated" to="/logout">Logout</b-nav-item>
<b-nav-item v-else="authenticated" to="/login">Login</b-nav-item> <b-nav-item v-else="authenticated" to="/login">Login</b-nav-item>
<b-nav-item :to="{name: 'rooms'}">{{ $t('Rooms') }}</b-nav-item> <b-nav-item v-if="authenticated" :to="{name: 'rooms'}">{{ $t('Rooms') }}</b-nav-item>
<b-nav-item :to="{name: 'recorders'}">{{ $t('Recorders') }}</b-nav-item> <b-nav-item v-if="authenticated" :to="{name: 'recorders'}">{{ $t('Recorders') }}</b-nav-item>
<b-nav-item :to="{name: 'commands'}">{{ $t('Commands') }}</b-nav-item> <b-nav-item v-if="authenticated" :to="{name: 'commands'}">{{ $t('Commands') }}</b-nav-item>
<b-nav-item :to="{name: 'test'}">{{ $t('Test') }}</b-nav-item> <b-nav-item :to="{name: 'test'}">Test</b-nav-item>
</b-navbar-nav> </b-navbar-nav>
<!-- Right aligned nav items --> <!-- Right aligned nav items -->

View File

@@ -1,59 +1,81 @@
<template> <template>
<div class="hello"> <div>
<h1>{{ $t('welcomeMsg') }}</h1> <b-alert show dismissible>Default Alert</b-alert>
<p>
{{ $t('guide') }}<br> <!--<img alt="Vue logo" src="../assets/logo.png">-->
{{ $t('checkout') }} <div v-if="authenticated">
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>. <h2>Yeah, you are logged in!</h2>
</p> </div>
<h3>{{ $t('plugins') }}</h3> <div v-else class="hello">
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li> <h1>{{ $t('welcomeMsg') }}</h1>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-typescript" target="_blank" rel="noopener">typescript</a></li> <h3>{{msg}}</h3>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-unit-mocha" target="_blank" rel="noopener">unit-mocha</a></li> <p>Go to <router-link :to="{name: 'login'}">login page</router-link> to login!</p>
</ul> <p>
<h3>{{ $t('links') }}</h3> {{ $t('guide') }}<br>
<ul> {{ $t('checkout') }}
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li> <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li> </p>
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li> <h3>{{ $t('plugins') }}</h3>
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li> <ul>
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li> <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank"
</ul> rel="noopener">babel</a></li>
<h3>{{ $t('ecosystem') }}</h3> <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-typescript"
<ul> target="_blank" rel="noopener">typescript</a></li>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li> <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-unit-mocha"
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li> target="_blank" rel="noopener">unit-mocha</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li> </ul>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li> <h3>{{ $t('links') }}</h3>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li> <ul>
</ul> <li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
</div> <li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
</ul>
<h3>{{ $t('ecosystem') }}</h3>
<ul>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank"
rel="noopener">vue-devtools</a></li>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
</div>
</div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator'; import {Component, Prop, Vue} from 'vue-property-decorator';
@Component @Component
export default class HelloWorld extends Vue { export default class HelloWorld extends Vue {
@Prop() private msg!: string; @Prop() private msg!: string;
}
get authenticated() {
return this.$store.getters.isAuthenticated;
}
}
</script> </script>
<!-- Add "scoped" attribute to limit CSS to this component only --> <!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss"> <style scoped lang="scss">
h3 { h3 {
margin: 40px 0 0; margin: 40px 0 0;
} }
ul {
list-style-type: none; ul {
padding: 0; list-style-type: none;
} padding: 0;
li { }
display: inline-block;
margin: 0 10px; li {
} display: inline-block;
a { margin: 0 10px;
color: #42b983; }
}
a {
color: #42b983;
}
</style> </style>

View File

@@ -129,7 +129,6 @@
this.$nextTick(() => { this.$nextTick(() => {
window.setInterval(() => { window.setInterval(() => {
this.$log.debug(getRemainingJwtValiditySeconds(this.$store.state.access_token));
this.tokenValidity = getRemainingJwtValiditySeconds(this.$store.state.access_token); this.tokenValidity = getRemainingJwtValiditySeconds(this.$store.state.access_token);
this.refreshTokenValidity = getRemainingJwtValiditySeconds(this.$store.state.refresh_token); this.refreshTokenValidity = getRemainingJwtValiditySeconds(this.$store.state.refresh_token);
}, 1000); }, 1000);

View File

@@ -0,0 +1,75 @@
<template>
<b-card class="mb-2" style="max-width: 30rem; min-width:20rem;"
:header="recorder.name"
v-bind:key="recorder.id">
<b-card-text>
<h5 class="card-title">
<strong>{{ $t('name') }}:&nbsp;{{recorder.name}}</strong>&nbsp
<router-link :to="{ name: 'recorders'}"> ({{$t('recorders')}}&nbsp
<font-awesome-icon icon="external-link-alt"/>
)
</router-link>
</h5>
</b-card-text>
<div slot="footer">
<small class="text-muted">
<p>{{ $t('created')}}: {{recorder.created_at | moment("dddd, MMMM Do YYYY")}}<br/>
{{ $t('last_time_modified')}}: {{recorder.last_time_modified | moment("dddd, MMMM Do YYYY")}}<br/>
</p>
</small>
</div>
</b-card>
</template>
<script>
export default {
props: ['recorder'],
data() {
return {
connectedWebsocket: false
}
},
mounted() {
this.$socket.client.on('connect', function(msg) {
console.log("We are connected!");
console.log(msg);
this.$socket.client.emit('request_recorder_state_'+ this.recorder.id, msg);
this.$socket.client.on('request_recorder_state_' + this.recorder.id, function(msg) {
//TODO: refresh state!
console.log(msg);
});
});
this.$log.info("mounted called");
if (!this.$socket.connected) {
this.connectWebsocket();
this.connectedWebsocket = true;
};
},
beforeDestroy() {
this.$log.info("beforeDestroy called");
if (this.connectedWebsocket) {
this.disconnectWebsocket();
}
},
methods: {
connectWebsocket() {
this.$socket.client.connect();
},
disconnectWebsocket() {
if (this.$socket.connected) {
this.$socket.client.disconnect();
}
}
},
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,80 @@
<template>
<div v-if="authenticated">
<div v-if="profile.favorite_recorders.length <=0">
<p>You haven't configured favorite recorders yet click below to do so!</p>
</div>
<div v-else>
<p>Yeah, you already configured a favorite recorder :)</p>
<ul>
<li v-for="recorder in profile.favorite_recorders">{{recorder.name}}</li>
</ul>
</div>
<b-form>
<b-input-group>
<select class="form-control" v-model="favorite_recorder_id">
<option value="">No recorder selected</option>
<option v-for="recorder in recorders" v-bind:value="recorder.id">
{{ recorder.name }}
</option>
</select>
<b-input-group-append>
<b-button variant="outline-success">
<font-awesome-icon icon="check"></font-awesome-icon>
</b-button>
</b-input-group-append>
</b-input-group>
</b-form>
</div>
<div v-else>
<p>You must sign in in order to select a recorder!</p>
</div>
</template>
<script lang="ts">
import {Component, Prop, Vue} from 'vue-property-decorator';
@Component
export default class SelectRecorder extends Vue {
@Prop() private msg!: string;
@Prop() private favorite_recorder_id!: string;
get authenticated() {
return this.$store.getters.isAuthenticated;
}
get profile() {
return this.$store.state.profile;
}
get recorders() {
return this.$store.state.recorders;
}
private mounted() {
this.$store.dispatch('loadProfile');
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>

View File

@@ -34,7 +34,7 @@ import {
faAt, faAt,
faUser, faUser,
faEnvelope, faEnvelope,
faUserTag, faUserTag, faExternalLinkAlt,
} from '@fortawesome/free-solid-svg-icons'; } from '@fortawesome/free-solid-svg-icons';
import {FontAwesomeIcon} from '@fortawesome/vue-fontawesome'; import {FontAwesomeIcon} from '@fortawesome/vue-fontawesome';
@@ -48,7 +48,7 @@ import 'bootstrap-vue/dist/bootstrap-vue.css';
const isProduction = process.env.NODE_ENV === 'production'; const isProduction = process.env.NODE_ENV === 'production';
library.add(faCoffee, faTrash, faPencilAlt, faScroll, faCheck, faCircle, faList, faPlus, faDoorOpen, faCogs, faAt, library.add(faCoffee, faTrash, faPencilAlt, faScroll, faCheck, faCircle, faList, faPlus, faDoorOpen, faCogs, faAt,
faUser, faEnvelope, faUserTag); faUser, faEnvelope, faUserTag, faExternalLinkAlt);
Vue.component('font-awesome-icon', FontAwesomeIcon); Vue.component('font-awesome-icon', FontAwesomeIcon);
@@ -72,10 +72,8 @@ Vue.use(VueSweetalert2);
Vue.use(VeeValidate); Vue.use(VeeValidate);
Vue.use(VueMoment); Vue.use(VueMoment);
const socket = io('ws://localhost:5000',); // const socket = io('ws://localhost:5000',{autoConnect: false, reconnectionAttempts: 3});
console.log(socket.nsp); const socket = io('ws://localhost:5443',{autoConnect: false, reconnectionAttempts: 3});
Vue.use(VueSocketIOExt, socket); Vue.use(VueSocketIOExt, socket);

View File

@@ -32,6 +32,8 @@ const messages = {
name: 'Name', name: 'Name',
alternate_name: 'alternativer Name', alternate_name: 'alternativer Name',
group: 'Gruppe', group: 'Gruppe',
groups: 'Gruppen',
permissions: 'Berechtigungen',
created: 'erstellt', created: 'erstellt',
Comments: 'Kommentare', Comments: 'Kommentare',
Comment: 'Kommentar', Comment: 'Kommentar',

View File

@@ -7,33 +7,33 @@ import RecordRepository from '@/api/recorderRepository';
// imports of AJAX functions will go here // imports of AJAX functions will go here
import { import {
fetchSurveys, fetchSurveys,
fetchSurvey, fetchSurvey,
getProviders, getProviders,
saveSurveyResponse, saveSurveyResponse,
postNewSurvey, postNewSurvey,
authenticate, authenticate,
register, register,
oidc_login, fetchUsers, getFreshToken, fetchProfile, fetchUserGroups, oidc_login, fetchUsers, getFreshToken, fetchProfile, fetchUserGroups,
} from '@/api'; } from '@/api';
import {isValidJwt, EventBus} from '@/utils'; import {isValidJwt, EventBus} from '@/utils';
Vue.use(Vuex); Vue.use(Vuex);
const state = { const state = {
// single source of data // single source of data
surveys: [], surveys: [],
rooms: [], rooms: [],
recorders: [], recorders: [],
recorderModels: [], recorderModels: [],
recorderCommands: [], recorderCommands: [],
loginProviders: [], loginProviders: [],
currentSurvey: {}, currentSurvey: {},
profile: {}, profile: {},
users: [], users: [],
userGroups: [], userGroups: [],
access_token: '', access_token: '',
refresh_token: '', refresh_token: '',
}; };
@@ -41,293 +41,303 @@ const state = {
const actions = { const actions = {
// asynchronous operations // asynchronous operations
loadRooms(context: any) { loadRooms(context: any) {
return RoomRepository.getRooms() return RoomRepository.getRooms()
.then((response: any) => { .then((response: any) => {
Vue.$log.debug(response); Vue.$log.debug(response);
Vue.$log.debug(response.data); Vue.$log.debug(response.data);
context.commit('setRooms', {rooms: response.data}); context.commit('setRooms', {rooms: response.data});
EventBus.$emit('roomsLoaded', response.data); EventBus.$emit('roomsLoaded', response.data);
}) })
.catch((error: any) => { .catch((error: any) => {
Vue.$log.warn('Error loading rooms!', error); Vue.$log.warn('Error loading rooms!', error);
EventBus.$emit('failedLoadingRooms', error); EventBus.$emit('failedLoadingRooms', error);
}); });
}, },
loadRecorders(context: any) { loadRecorders(context: any) {
return RecordRepository.getRecorders() return RecordRepository.getRecorders()
.then((response: any) => { .then((response: any) => {
Vue.$log.debug(response); Vue.$log.debug(response);
Vue.$log.debug(response.data); Vue.$log.debug(response.data);
context.commit('setRecorders', {recorders: response.data}); context.commit('setRecorders', {recorders: response.data});
EventBus.$emit('recordersLoaded', response.data); EventBus.$emit('recordersLoaded', response.data);
}) })
.catch((error: any) => { .catch((error: any) => {
Vue.$log.warn('Error loading recorders!', error); Vue.$log.warn('Error loading recorders!', error);
EventBus.$emit('failedLoadingRecorders', error); EventBus.$emit('failedLoadingRecorders', error);
}); });
}, },
loadRecorderModels(context: any) { loadRecorderModels(context: any) {
return RecordRepository.getRecorderModels() return RecordRepository.getRecorderModels()
.then((response: any) => { .then((response: any) => {
Vue.$log.debug(response); Vue.$log.debug(response);
Vue.$log.debug(response.data); Vue.$log.debug(response.data);
Vue.$log.debug('Loaded recorder models'); Vue.$log.debug('Loaded recorder models');
context.commit('setRecorderModels', {recorderModels: response.data}); context.commit('setRecorderModels', {recorderModels: response.data});
EventBus.$emit('recorderModelsLoaded', response.data); EventBus.$emit('recorderModelsLoaded', response.data);
}) })
.catch((error: any) => { .catch((error: any) => {
Vue.$log.warn('Error loading recorder models!', error); Vue.$log.warn('Error loading recorder models!', error);
EventBus.$emit('failedLoadingRecorderModels', error); EventBus.$emit('failedLoadingRecorderModels', error);
}); });
}, },
loadRecorderCommands(context: any) { loadRecorderCommands(context: any) {
return RecordRepository.getRecorderCommands() return RecordRepository.getRecorderCommands()
.then((response: any) => { .then((response: any) => {
Vue.$log.debug(response); Vue.$log.debug(response);
Vue.$log.debug(response.data); Vue.$log.debug(response.data);
context.commit('setRecorderCommands', {recorderCommands: response.data}); context.commit('setRecorderCommands', {recorderCommands: response.data});
EventBus.$emit('recorderCommandsLoaded', response.data); EventBus.$emit('recorderCommandsLoaded', response.data);
}) })
.catch((error: any) => { .catch((error: any) => {
Vue.$log.warn('Error loading recorder commands!', error); Vue.$log.warn('Error loading recorder commands!', error);
EventBus.$emit('failedLoadingRecorderCommands', error); EventBus.$emit('failedLoadingRecorderCommands', error);
}); });
}, },
loadVirtualCommands(context: any) { loadVirtualCommands(context: any) {
return RecordRepository.getRecorderCommands() return RecordRepository.getRecorderCommands()
.then((response: any) => { .then((response: any) => {
Vue.$log.debug(response); Vue.$log.debug(response);
Vue.$log.debug(response.data); Vue.$log.debug(response.data);
context.commit('setRecorderCommands', {recorderCommands: response.data}); context.commit('setRecorderCommands', {recorderCommands: response.data});
EventBus.$emit('recorderCommandsLoaded', response.data); EventBus.$emit('recorderCommandsLoaded', response.data);
}) })
.catch((error: any) => { .catch((error: any) => {
Vue.$log.warn('Error loading recorder commands!', error); Vue.$log.warn('Error loading recorder commands!', error);
EventBus.$emit('failedLoadingRecorderCommands', error); EventBus.$emit('failedLoadingRecorderCommands', error);
}); });
}, },
loadCommands(context: any) { loadCommands(context: any) {
return context.dispatch('loadRecorderCommands').then(() => { return context.dispatch('loadRecorderCommands').then(() => {
return context.dispatch('loadVirtualCommands'); return context.dispatch('loadVirtualCommands');
});
},
loadUsers(context: any) {
return fetchUsers(context.state.access_token)
.then((response) => {
Vue.$log.debug(response);
Vue.$log.debug(response.data);
context.commit('setUsers', {users: response.data});
EventBus.$emit('usersLoaded', response.data);
})
.catch((error) => {
Vue.$log.warn('Error loading users!', error);
EventBus.$emit('failedLoadingUsers', error);
});
},
loadUserGroups(context: any) {
return fetchUserGroups(context.state.access_token)
.then((response) => {
Vue.$log.debug(response);
Vue.$log.debug(response.data);
context.commit('setUserGroups', {groups: response.data});
EventBus.$emit('groupsLoaded', response.data);
})
.catch((error) => {
Vue.$log.warn('Error loading user groups!', error);
EventBus.$emit('failedLoadingUserGroups', error);
});
},
loadProfileAuthCheck(context: any) {
if (!getters.isAuthenticated) {
EventBus.$emit('accessTokenInvalid');
if (!getters.isRefreshTokenValid) {
Vue.$log.warn('Access and refresh token invalid! User must login again!');
EventBus.$emit('refreshTokenInvalid');
EventBus.$emit('accessAndRefreshTokenInvalid');
} else {
return context.dispatch('refreshToken').then(() => {
context.commit('loadProfile');
}); });
}, }
loadUsers(context: any) { } else {
return fetchUsers(context.state.access_token) context.commit('loadProfile');
.then((response) => { }
Vue.$log.debug(response); },
Vue.$log.debug(response.data); loadProfile(context: any) {
context.commit('setUsers', {users: response.data}); return fetchProfile(context.state.access_token)
EventBus.$emit('usersLoaded', response.data); .then((response) => {
}) Vue.$log.debug(response);
.catch((error) => { Vue.$log.debug(response.data);
Vue.$log.warn('Error loading users!', error); context.commit('setProfile', {profile: response.data});
EventBus.$emit('failedLoadingUsers', error); EventBus.$emit('profileLoaded', response.data);
}); })
}, .catch((error) => {
loadUserGroups(context: any) { Vue.$log.warn('Error loading profile!', error);
return fetchUserGroups(context.state.access_token) EventBus.$emit('failedLoadingProfile', error);
.then((response) => { });
Vue.$log.debug(response); },
Vue.$log.debug(response.data); loadLoginProviders(context: any) {
context.commit('setUserGroups', {groups: response.data}); return getProviders()
EventBus.$emit('groupsLoaded', response.data); .then((response) => {
}) context.commit('setLoginProviderData', {providers: response.data});
.catch((error) => { EventBus.$emit('loginProvidersLoaded', response.data);
Vue.$log.warn('Error loading user groups!', error); });
EventBus.$emit('failedLoadingUserGroups', error); },
}); login(context: any, userData: any) {
}, context.commit('setUserData', {userData});
loadProfileAuthCheck(context: any) { return authenticate(userData)
if (!getters.isAuthenticated) { .then((response) => context.commit('setJwtToken', {tokens: response.data}))
EventBus.$emit('accessTokenInvalid'); .catch((error) => {
if (!getters.isRefreshTokenValid) { Vue.$log.warn('Error Authenticating: ', error);
Vue.$log.warn('Access and refresh token invalid! User must login again!'); EventBus.$emit('failedAuthentication', error);
EventBus.$emit('refreshTokenInvalid'); });
EventBus.$emit('accessAndRefreshTokenInvalid'); },
} else { oidc_login(context: any, redirectionUrl: any) {
return context.dispatch('refreshToken').then(() => { // context.commit('setUserData', { userData });
context.commit('loadProfile'); return oidc_login(redirectionUrl)
}); .then((response) => context.commit('setJwtToken', {tokens: response.data}))
} .catch((error) => {
} else { Vue.$log.warn('Error Authenticating: ', error);
context.commit('loadProfile'); EventBus.$emit('failedAuthentication', error);
} });
}, },
loadProfile(context: any) { refreshToken(context: any) {
return fetchProfile(context.state.access_token) EventBus.$emit('refreshingToken');
.then((response) => { Vue.$log.debug('Refreshing tokens!');
Vue.$log.debug(response); return getFreshToken(context.state.refresh_token)
Vue.$log.debug(response.data); .then((response) => {
context.commit('setProfile', {profile: response.data}); context.commit('setTokens', {tokens: response.data});
EventBus.$emit('profileLoaded', response.data); Vue.$log.debug('Tokens refreshed!');
}) })
.catch((error) => { .catch((error) => {
Vue.$log.warn('Error loading profile!', error); Vue.$log.warn('Error Refreshing token: ', error);
EventBus.$emit('failedLoadingProfile', error); EventBus.$emit('failedRefreshingToken', error);
}); });
}, },
loadLoginProviders(context: any) { storeTokens(context: any, tokens: any) {
return getProviders() context.commit('setTokens', {tokens});
.then((response) => { EventBus.$emit('storedTokens');
context.commit('setLoginProviderData', {providers: response.data}); },
EventBus.$emit('loginProvidersLoaded', response.data); register(context: any, userData: any) {
}); context.commit('setUserData', {userData});
}, return register(userData)
login(context: any, userData: any) { .then(context.dispatch('login', userData))
context.commit('setUserData', {userData}); .catch((error) => {
return authenticate(userData) Vue.$log.warn('Error Registering: ', error);
.then((response) => context.commit('setJwtToken', {tokens: response.data})) EventBus.$emit('failedRegistering: ', error);
.catch((error) => { });
Vue.$log.warn('Error Authenticating: ', error); },
EventBus.$emit('failedAuthentication', error); submitNewSurvey(context: any, survey: any) {
}); return postNewSurvey(survey, context.state.access_token);
}, },
oidc_login(context: any, redirectionUrl: any) {
// context.commit('setUserData', { userData });
return oidc_login(redirectionUrl)
.then((response) => context.commit('setJwtToken', {tokens: response.data}))
.catch((error) => {
Vue.$log.warn('Error Authenticating: ', error);
EventBus.$emit('failedAuthentication', error);
});
},
refreshToken(context: any) {
EventBus.$emit('refreshingToken');
Vue.$log.debug('Refreshing tokens!');
return getFreshToken(context.state.refresh_token)
.then((response) => {
context.commit('setTokens', {tokens: response.data});
Vue.$log.debug('Tokens refreshed!');
})
.catch((error) => {
Vue.$log.warn('Error Refreshing token: ', error);
EventBus.$emit('failedRefreshingToken', error);
});
},
storeTokens(context: any, tokens: any) {
context.commit('setTokens', {tokens});
EventBus.$emit('storedTokens');
},
register(context: any, userData: any) {
context.commit('setUserData', {userData});
return register(userData)
.then(context.dispatch('login', userData))
.catch((error) => {
Vue.$log.warn('Error Registering: ', error);
EventBus.$emit('failedRegistering: ', error);
});
},
submitNewSurvey(context: any, survey: any) {
return postNewSurvey(survey, context.state.access_token);
},
}; };
const mutations = { const mutations = {
// isolated data mutations // isolated data mutations
setSurveys(sState: any, payload: any) { setSurveys(sState: any, payload: any) {
sState.surveys = payload.surveys; sState.surveys = payload.surveys;
}, },
setSurvey(sState: any, payload: any) { setSurvey(sState: any, payload: any) {
const nQuestions = payload.survey.questions.length; const nQuestions = payload.survey.questions.length;
for (let i = 0; i < nQuestions; i++) { for (let i = 0; i < nQuestions; i++) {
payload.survey.questions[i].choice = null; payload.survey.questions[i].choice = null;
} }
sState.currentSurvey = payload.survey; sState.currentSurvey = payload.survey;
}, },
setRooms(sState: any, payload: any) { setRooms(sState: any, payload: any) {
sState.rooms = payload.rooms; sState.rooms = payload.rooms;
}, },
setRecorders(sState: any, payload: any) { setRecorders(sState: any, payload: any) {
sState.recorders = payload.recorders; sState.recorders = payload.recorders;
}, },
setRecorderModels(sState: any, payload: any) { setRecorderModels(sState: any, payload: any) {
sState.recorderModels = payload.recorderModels; sState.recorderModels = payload.recorderModels;
}, },
setRecorderCommands(sState: any, payload: any) { setRecorderCommands(sState: any, payload: any) {
sState.recorderCommands = payload.recorderCommands; sState.recorderCommands = payload.recorderCommands;
}, },
setUsers(sState: any, payload: any) { setUsers(sState: any, payload: any) {
sState.users = payload.users; sState.users = payload.users;
}, },
setUserGroups(sState: any, payload: any) { setUserGroups(sState: any, payload: any) {
sState.userGroups = payload.groups; sState.userGroups = payload.groups;
}, },
setChoice(sState: any, payload: any) { setChoice(sState: any, payload: any) {
const {questionId, choice} = payload; const {questionId, choice} = payload;
const nQuestions = sState.currentSurvey.questions.length; const nQuestions = sState.currentSurvey.questions.length;
for (let i = 0; i < nQuestions; i++) { for (let i = 0; i < nQuestions; i++) {
if (sState.currentSurvey.questions[i].id === questionId) { if (sState.currentSurvey.questions[i].id === questionId) {
sState.currentSurvey.questions[i].choice = choice; sState.currentSurvey.questions[i].choice = choice;
break; break;
} }
} }
}, },
setLoginProviderData(sState: any, payload: any) { setLoginProviderData(sState: any, payload: any) {
Vue.$log.debug('got loginProviders = ', payload); Vue.$log.debug('got loginProviders = ', payload);
sState.loginProviders = payload.providers; sState.loginProviders = payload.providers;
}, },
// probably old ... // probably old ...
setUserData(sState: any, payload: any) { setUserData(sState: any, payload: any) {
Vue.$log.debug('setUserData payload = ', payload); Vue.$log.debug('setUserData payload = ', payload);
sState.userData = payload.userData; sState.userData = payload.userData;
}, },
setProfile(sState: any, payload: any) { setProfile(sState: any, payload: any) {
Vue.$log.debug('setProfile payload = ', payload); Vue.$log.debug('setProfile payload = ', payload);
sState.profile = payload.profile; sState.profile = payload.profile;
}, },
setJwtToken(sState: any, payload: any) { setJwtToken(sState: any, payload: any) {
Vue.$log.debug('setJwtToken payload = ', payload); Vue.$log.debug('setJwtToken payload = ', payload);
localStorage.tokens = payload.tokens; localStorage.tokens = payload.tokens;
sState.access_token = payload.tokens.access_token; sState.access_token = payload.tokens.access_token;
sState.refresh_token = payload.tokens.refresh_token; sState.refresh_token = payload.tokens.refresh_token;
}, },
setTokens(sState: any, payload: any) { setTokens(sState: any, payload: any) {
Vue.$log.debug('setTokens payload = ', payload); Vue.$log.debug('setTokens payload = ', payload);
if (payload.tokens.access_token) { if (payload.tokens.access_token) {
sState.access_token = payload.tokens.access_token; sState.access_token = payload.tokens.access_token;
} }
if (payload.tokens.refresh_token) { if (payload.tokens.refresh_token) {
sState.refresh_token = payload.tokens.refresh_token; sState.refresh_token = payload.tokens.refresh_token;
} }
Vue.$log.debug('access_token: ' + sState.access_token); Vue.$log.debug('access_token: ' + sState.access_token);
Vue.$log.debug('refresh_token: ' + sState.refresh_token); Vue.$log.debug('refresh_token: ' + sState.refresh_token);
}, },
}; };
const getters = { const getters = {
// reusable data accessors // reusable data accessors
isAuthenticated(sState: any) { isAuthenticated(sState: any) {
const valid = isValidJwt(sState.access_token); const valid = isValidJwt(sState.access_token);
Vue.$log.debug('Access token is valid?: ', valid); Vue.$log.debug('Access token is valid?: ', valid);
Vue.$log.debug(sState.access_token); Vue.$log.debug(sState.access_token);
return valid; return valid;
}, },
isRefreshTokenValid(sState: any) { isRefreshTokenValid(sState: any) {
const valid = isValidJwt(sState.refresh_token); const valid = isValidJwt(sState.refresh_token);
Vue.$log.debug('Refresh token is valid?: ', valid); Vue.$log.debug('Refresh token is valid?: ', valid);
Vue.$log.debug('sState.refresh_token'); Vue.$log.debug('sState.refresh_token');
return valid; return valid;
}, },
getLoginProviders(sState: any) { getLoginProviders(sState: any) {
return sState.loginProviders; return sState.loginProviders;
}, },
hasAccessRight(sState: any) { getUserName(sState: any) {
(requested_permission: string) => { if (sState.profile == null || Object.keys(sState.profile).length === 0) {
return sState.profile.effective_permissions.find((permission: any) => { return '';
permission.name === requested_permission }
}); if (sState.profile.nickname) {
}; return sState.profile.nickname;
}, }
return sState.profile.first_name + ' ' + sState.profile.last_name;
},
// this is probably wrong!!
hasAccessRight(sState: any) {
(requested_permission: string) => {
return sState.profile.effective_permissions.find((permission: any) => {
permission.name === requested_permission;
});
};
},
}; };
const store = new Vuex.Store({ const store = new Vuex.Store({
state, state,
actions, actions,
mutations, mutations,
getters, getters,
plugins: [createPersistedState()], plugins: [createPersistedState()],
}); });
export default store; export default store;

View File

@@ -1,30 +1,63 @@
<template> <template>
<div class="home"> <div class="home">
<b-alert show>Default Alert</b-alert> <div class="container">
<section class="section">
<img alt="Vue logo" src="../assets/logo.png"> <HelloWorld v-if="!authenticated" msg="you are not authenticated!"/>
<HelloWorld msg="Welcome to Your Vue.js + TypeScript App"/> <div v-else>
<h1>Welcome <span v-if="profile.last_seen!=null">back</span> {{$store.getters.getUserName}}! <span
v-if="profile.last_seen!=null">(Last seen: {{profile.last_seen | moment("dddd, MMMM Do YYYY")}})</span>
</h1>
<SelectRecorder/>
<div v-if="profile.favorite_recorders.length >0">
<ul>
<li v-for="recorder in profile.favorite_recorders">{{recorder.name}}</li>
</ul>
<RecorderState v-for="recorder in profile.favorite_recorders" :recorder="recorder"/>
</div>
</div>
</section>
</div>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import {Component, Vue} from 'vue-property-decorator'; import {Component, Vue} from 'vue-property-decorator';
import HelloWorld from '@/components/HelloWorld.vue'; // @ is an alias to /src import HelloWorld from '@/components/HelloWorld.vue'; // @ is an alias to /src
import i18n from '@/plugins/i18n'; import i18n from '@/plugins/i18n';
import SelectRecorder from '@/components/SelectRecorder.vue';
@Component({ import RecorderState from '@/components/RecorderState.vue';
components: {
HelloWorld,
},
})
export default class Home extends Vue {
public data() {
return {
};
}
@Component({
components: {
RecorderState,
SelectRecorder,
HelloWorld,
},
})
export default class Home extends Vue {
public data() {
return {};
} }
mounted() {
if (this.profile == null || Object.keys(this.profile).length === 0) {
this.$store.dispatch('loadProfile');
}
}
get authenticated() {
return this.$store.getters.isAuthenticated;
}
get profile() {
return this.$store.state.profile;
}
}
</script> </script>
<style> <style>