@@ -3,6 +3,7 @@ import Router from 'vue-router'; | |||
import HomePage from '../account/HomePage' | |||
import ActivationPage from '../auth/ActivationPage' | |||
import ModelSetupPage from '../admin/ModelSetupPage' | |||
import RegisterPage from '../auth/RegisterPage' | |||
import LoginPage from '../auth/LoginPage' | |||
import MultifactorAuthPage from '../auth/MultifactorAuthPage' | |||
@@ -74,6 +75,7 @@ export const router = new Router({ | |||
{ path: '/admin/accounts', component: AccountsPage }, | |||
{ path: '/admin/accounts/:uuid', component: ProfilePage }, | |||
{ path: '/admin/model', component: ModelSetupPage }, | |||
// otherwise redirect to home | |||
{ path: '*', redirect: '/' } | |||
@@ -1,6 +1,7 @@ | |||
let landingPage = null; | |||
export const util = { | |||
USER_KEY: 'user', | |||
getLandingPage: function () { return landingPage; }, | |||
setLandingPage: function (page) { landingPage = page; }, | |||
resetLandingPage: function () { landingPage = null; }, | |||
@@ -11,6 +11,7 @@ export const userService = { | |||
updatePolicyById, | |||
addPolicyContactById, | |||
removePolicyContactByUuid, | |||
setLocale, | |||
update, | |||
delete: _delete, | |||
approveAction, | |||
@@ -104,6 +105,16 @@ function denyAction(id, code, messages, errors) { | |||
return fetch(`${config.apiUrl}/auth/deny/${code}`, util.postWithAuth()).then(util.handleCrudResponse(messages, errors)); | |||
} | |||
function setLocale(locale, messages, errors) { | |||
const user = util.currentUser(); | |||
if (user != null && user.token) { | |||
return fetch(`${config.apiUrl}/me/locale/${locale}`, util.postWithAuth()).then(util.handleCrudResponse(messages, errors)); | |||
} else { | |||
const loc = {locale: locale}; | |||
return Promise.resolve(loc); | |||
} | |||
} | |||
function update(user, messages, errors) { | |||
return fetch(`${config.apiUrl}/users/${user.uuid}`, util.postWithAuth(user)).then(util.handleCrudResponse(messages, errors)); | |||
} | |||
@@ -1,16 +1,14 @@ | |||
import { userService, systemService } from '../_services'; | |||
import { router, util } from '../_helpers'; | |||
// todo: why can't we import currentUser from api-util and use that here? | |||
// when I try to do that, webpack succeeds but then an error occurs loading any page, with the | |||
// error message "_helpers.currentUser is not defined" | |||
// const user = JSON.parse(localStorage.getItem('user')); | |||
const user = util.currentUser(); | |||
const defaultStatus = { | |||
loggingIn: false, | |||
loggedIn: false, | |||
registering: false, | |||
updating: false, | |||
settingLocale: false, | |||
activating: false, | |||
approving: false, | |||
denying: false, | |||
@@ -22,12 +20,13 @@ const state = { | |||
activated: null, | |||
status: Object.assign({}, defaultStatus, {loggedIn: (user != null)}), | |||
user: user, | |||
actionStatus: {} | |||
actionStatus: {}, | |||
locale: user == null ? 'detect' : (typeof user.locale !== 'undefined' && user.locale !== null ? user.locale : 'detect') | |||
}; | |||
const actions = { | |||
refreshUser({ commit }) { | |||
commit('refreshUser', JSON.parse(localStorage.getItem('user'))); | |||
commit('refreshUser', JSON.parse(localStorage.getItem(util.USER_KEY))); | |||
}, | |||
login({ dispatch, commit }, { user, messages, errors }) { | |||
commit('loginRequest', { name: user.name }); | |||
@@ -75,6 +74,15 @@ const actions = { | |||
} | |||
); | |||
}, | |||
setLocale({ commit }, {locale, messages, errors}) { | |||
state.locale = locale; | |||
commit('setLocaleRequest', locale); | |||
userService.setLocale(locale, messages, errors) | |||
.then( | |||
user => commit('setLocaleSuccess', user), | |||
error => commit('setLocaleFailure', error) | |||
); | |||
}, | |||
update({ dispatch, commit }, {user, messages, errors}) { | |||
commit('updateRequest', user); | |||
userService.update(user, messages, errors) | |||
@@ -152,8 +160,9 @@ const mutations = { | |||
} else { | |||
state.status = {}; | |||
} | |||
localStorage.setItem('user', JSON.stringify(user)); | |||
localStorage.setItem(util.USER_KEY, JSON.stringify(user)); | |||
state.user = user; | |||
state.locale = (typeof user.locale !== 'undefined' && user.locale !== null ? user.locale : state.locale); | |||
}, | |||
loginFailure(state) { | |||
state.status.loggingIn = false; | |||
@@ -171,13 +180,54 @@ const mutations = { | |||
}, | |||
registerSuccess(state, user) { | |||
state.status.registering = false; | |||
localStorage.setItem(util.USER_KEY, JSON.stringify(user)); | |||
state.user = user; | |||
state.locale = (typeof user.locale !== 'undefined' && user.locale !== null ? user.locale : state.locale); | |||
}, | |||
registerFailure(state) { | |||
state.status.registering = false; | |||
state.status = {}; | |||
}, | |||
setLocaleRequest(state, locale) { | |||
console.log('setLocaleRequest: setting locale='+locale); | |||
state.status.settingLocale = true; | |||
state.locale = locale; | |||
const user = util.currentUser(); | |||
if (user === null) { | |||
localStorage.setItem(util.USER_KEY, JSON.stringify({locale: locale})); | |||
} else { | |||
user.locale = locale; | |||
localStorage.setItem(util.USER_KEY, JSON.stringify(user)); | |||
} | |||
state.user = user; | |||
}, | |||
setLocaleSuccess(state, user) { | |||
console.log('setLocaleSuccess: user='+JSON.stringify(user)); | |||
state.locale = ''+state.locale; | |||
state.status.settingLocale = false; | |||
}, | |||
setLocaleFailure(state) { | |||
console.log('setLocaleFailure'); | |||
state.status.settingLocale = false; | |||
state.status = {}; | |||
}, | |||
updateRequest(state, user) { | |||
state.status.updating = true; | |||
state.user = user; | |||
}, | |||
updateSuccess(state, user) { | |||
state.status.updating = false; | |||
localStorage.setItem(util.USER_KEY, JSON.stringify(user)); | |||
state.user = user; | |||
state.locale = (typeof user.locale !== 'undefined' && user.locale !== null ? user.locale : state.locale); | |||
}, | |||
updateFailure(state) { | |||
state.status.updating = false; | |||
state.status = {}; | |||
}, | |||
approveActionRequest(state) { | |||
state.status.approving = true; | |||
state.actionStatus = { requesting: true, type: 'approve' }; | |||
@@ -216,7 +266,7 @@ const mutations = { | |||
state.user = user; | |||
} else if (user.multifactorAuth) { | |||
state.user.multifactorAuth = user.multifactorAuth; | |||
localStorage.setItem('user', JSON.stringify(user)); | |||
localStorage.setItem(util.USER_KEY, JSON.stringify(user)); | |||
} | |||
}, | |||
sendAuthenticatorCodeFailure(state, error) { | |||
@@ -1,12 +1,15 @@ | |||
import { systemService } from '../_services'; | |||
import { account } from "./account.module"; | |||
import {router} from "../_helpers"; | |||
import { router } from "../_helpers"; | |||
const state = { | |||
configs: { | |||
allowRegistration: false, | |||
paymentsEnabled: false, | |||
sageLauncher: false | |||
sageLauncher: false, | |||
cloudDrivers: [], | |||
entityClasses: [], | |||
locales: ['en_US'] | |||
}, | |||
status: { activating: false }, | |||
activated: null, | |||
@@ -26,6 +29,7 @@ const state = { | |||
return {count: parseInt(ms), units: ''}; | |||
} | |||
}, | |||
messageGroupsLoaded: [], | |||
countries: [], | |||
locales: [], | |||
timezones: [], | |||
@@ -74,6 +78,11 @@ const actions = { | |||
error => commit('loadMessagesFailure', error) | |||
); | |||
}, | |||
reloadMessages({ commit }, locale) { | |||
for (let i=0; i<this.messageGroupsLoaded.length; i++) { | |||
this.loadMessages(this.messageGroupsLoaded[i], locale); | |||
} | |||
}, | |||
loadTimezones({ commit }) { | |||
commit('loadTimezonesRequest'); | |||
systemService.loadTimezones().then( | |||
@@ -141,6 +150,10 @@ const getters = { | |||
href: '/admin/users', | |||
title: messages.label_menu_admin_users, | |||
icon: messages.label_menu_admin_users_icon | |||
}, { | |||
href: '/admin/model', | |||
title: messages.label_menu_admin_model, | |||
icon: messages.label_menu_admin_model_icon | |||
}] | |||
}; | |||
menu.splice(1, 0, admin_menu); | |||
@@ -213,6 +226,7 @@ const mutations = { | |||
loadMessagesRequest(state) {}, | |||
loadMessagesSuccess(state, {group, messages}) { | |||
// console.log('loadMessages (group='+group+'), messages='+JSON.stringify(messages)); | |||
if (state.messageGroupsLoaded.indexOf(group) === -1) state.messageGroupsLoaded.push(group); | |||
state.messages = new Proxy(Object.assign({}, state.messages, messages), messageNotFoundHandler); | |||
if (messages.country_codes) { | |||
const countries = []; | |||
@@ -0,0 +1,42 @@ | |||
<template> | |||
<div> | |||
<h2>{{messages.form_title_model_setup}}</h2> | |||
<form @submit.prevent="setupModel"> | |||
<div class="form-group"> | |||
<label for="configType">{{messages.field_label_entity_type}}</label> | |||
<select v-model="configType" name="configType" class="form-control"> | |||
<option v-for="opt in system.configs.entityClasses" v-bind:value="opt">{{opt}}</option> | |||
</select> | |||
</div> | |||
</form> | |||
</div> | |||
</template> | |||
<script> | |||
import { mapState, mapActions, mapGetters } from 'vuex' | |||
export default { | |||
data() { | |||
return { | |||
configType: system.configs.entityClasses[0] | |||
}; | |||
}, | |||
computed: { | |||
...mapState('system', ['configs', 'messages']) | |||
}, | |||
created () { | |||
const locale = 'detect'; | |||
this.loadSystemConfigs(); // determine if we can show the registration link | |||
this.loadMessages('pre_auth', locale); | |||
this.loadMessages('post_auth', locale); | |||
}, | |||
methods: { | |||
// ...mapActions('system', ['loadIsActivated', 'activate']), | |||
...mapActions('system', ['loadIsActivated', 'loadSystemConfigs', 'loadMessages', 'loadTimezones']), | |||
setupModel(e) { | |||
console.log('setupModel called'); | |||
} | |||
} | |||
}; | |||
</script> |
@@ -9,25 +9,55 @@ | |||
</div> | |||
</div> | |||
</div> | |||
<div> | |||
<hr/> | |||
<button @click="toggleLocaleView()">{{messages.button_label_set_locale}}</button> | |||
<div v-if="showLocaleSelector"> | |||
<div class="form-group"> | |||
<label for="locale">{{messages.field_label_locale}}</label> | |||
<select v-if="this.locales && this.locales.length > 0" v-model="selectedLocale" name="locale" class="form-control"> | |||
<option value="detect">{{messages['locale_detect']}}</option> | |||
<option v-for="opt in this.locales" v-bind:value="opt">{{messages['locale_'+opt]}}</option> | |||
</select> | |||
<div v-if="errors.has('locale')" class="invalid-feedback">{{ errors.first('locale') }}</div> | |||
</div> | |||
<button @click="updateLocale" class="btn btn-primary">{{messages.button_label_set_locale}}</button> | |||
</div> | |||
</div> | |||
</div> | |||
</template> | |||
<script> | |||
import { mapState, mapGetters, mapActions } from 'vuex' | |||
import { util } from '../_helpers' | |||
export default { | |||
name: 'app', | |||
data() { | |||
return { | |||
showLocaleSelector: false, | |||
selectedLocale: 'detect' | |||
} | |||
}, | |||
computed: { | |||
...mapState('account', ['status']), | |||
...mapState('account', ['status', 'user', 'locale']), | |||
...mapState('system', ['activated', 'configs', 'messages', 'menu']), | |||
...mapGetters('system', ['menu']), | |||
...mapState({ | |||
alert: state => state.alert | |||
}) | |||
}), | |||
locales () { return this.configs.locales; } | |||
}, | |||
methods: { | |||
...mapActions({ clearAlert: 'alert/clear' }), | |||
...mapActions('system', ['loadIsActivated', 'loadSystemConfigs', 'loadMessages', 'loadTimezones']) | |||
...mapActions('account', ['setLocale']), | |||
...mapActions('system', ['loadIsActivated', 'loadSystemConfigs', 'loadMessages', 'reloadMessages', 'loadTimezones']), | |||
toggleLocaleView() { this.showLocaleSelector = !this.showLocaleSelector; }, | |||
updateLocale() { | |||
if (this.selectedLocale) { | |||
this.setLocale({locale: this.selectedLocale, messages: this.messages, errors: this.errors}); | |||
} | |||
} | |||
}, | |||
watch: { | |||
$route (to, from){ | |||
@@ -35,20 +65,30 @@ export default { | |||
this.clearAlert(); | |||
}, | |||
activated (active) { | |||
console.log('App.watch.activated: received: '+active); | |||
if (!active) this.$router.replace('/activate'); | |||
}, | |||
user (u) { | |||
if (typeof u === 'undefined' || u === null || typeof u.locale === 'undefined' || u.locale === null) { | |||
return; | |||
} | |||
this.selectedLocale = u.locale; | |||
this.reloadMessages(this.selectedLocale); | |||
}, | |||
locale (loc) { | |||
this.selectedLocale = loc; | |||
this.reloadMessages(this.selectedLocale) | |||
} | |||
}, | |||
created() { | |||
const user = util.currentUser(); | |||
this.selectedLocale = (user !== null && typeof user.locale !== 'undefined' && user.locale !== null ? user.locale : 'detect'); | |||
this.loadIsActivated(); | |||
this.loadSystemConfigs(); // determine if we can show the registration link | |||
// todo: allow user to choose locale | |||
const locale = 'detect'; | |||
this.loadMessages('pre_auth', locale); | |||
this.loadMessages('countries', locale); | |||
this.loadMessages('timezones', locale); | |||
this.loadTimezones(); | |||
this.loadMessages('pre_auth', this.selectedLocale); | |||
this.loadMessages('countries', this.selectedLocale); | |||
this.loadMessages('timezones', this.selectedLocale); | |||
} | |||
}; | |||
</script> |