Merge pull request 'Apply lang selector and update user config' (!85) from wbuezas/hedera-web-mindshore:feature/ApplyLangSelector into 4922-vueMigration

Reviewed-on: #85
Reviewed-by: Javier Segarra <jsegarra@verdnatura.es>
This commit is contained in:
Javier Segarra 2024-09-17 07:51:00 +00:00
commit d824df5eb0
9 changed files with 163 additions and 63 deletions

View File

@ -1,9 +1,14 @@
<script setup> <script setup>
import { useAppStore } from 'stores/app'; import { useAppStore } from 'stores/app';
import { useUserStore } from 'stores/user';
import { onBeforeMount } from 'vue'; import { onBeforeMount } from 'vue';
const appStore = useAppStore(); const appStore = useAppStore();
const userStore = useUserStore();
onBeforeMount(() => appStore.init()); onBeforeMount(async () => {
await userStore.init();
await appStore.init();
});
</script> </script>
<template> <template>

View File

@ -1,4 +1,13 @@
export default { export default {
language: 'Idioma',
langs: {
en: 'Anglès',
es: 'Espanyol',
ca: 'Català',
fr: 'Francès',
mn: 'Rus',
pt: 'Portuguès'
},
date: { date: {
days: [ days: [
'Diumenge', 'Diumenge',
@ -81,7 +90,17 @@ export default {
noData: 'Sense dades', noData: 'Sense dades',
confirm: 'Confirmar', confirm: 'Confirmar',
delete: 'Esborrar', delete: 'Esborrar',
confirmDelete: 'Estàs segur que vols esborrar la línia?',
emptyList: 'Llista buida', emptyList: 'Llista buida',
modify: 'Modificar',
confirmDelete: 'Estàs segur que vols esborrar la línia?' logInAsGuest: `Accedir com a convidat`,
haveForgottenPassword: '¿Has oblidat la teva contrasenya?',
signUp: 'Registrar-me',
notACustomerYet: `Encara no ets client?`,
loginPhone: '+34 963 242 100',
loginMail: "{'info'}{'@'}{'verdnatura.es'}",
remindMe: "Recorda'm",
user: 'Usuari',
password: 'Contrasenya',
modify: 'Modificar'
}; };

View File

@ -12,6 +12,15 @@ export default {
today: 'Today', today: 'Today',
yesterday: 'Yesterday', yesterday: 'Yesterday',
tomorrow: 'Tomorrow', tomorrow: 'Tomorrow',
language: 'Language',
langs: {
en: 'English',
es: 'Spanish',
ca: 'Catalan',
fr: 'French',
mn: 'Russian',
pt: 'Portuguese'
},
date: { date: {
days: [ days: [
'Sunday', 'Sunday',
@ -117,5 +126,13 @@ export default {
save: 'Save', save: 'Save',
cancel: 'Cancel', cancel: 'Cancel',
of: 'of', of: 'of',
loginAsGuest: 'Login as guest',
haveForgottenPassword: 'Have you forgotten your password?',
signUp: 'Sign up',
notACustomerYet: 'Not a customer yet?',
loginPhone: '+34 963 242 100',
loginMail: "{'info'}{'@'}{'verdnatura.es'}",
remindMe: 'Remember me',
password: 'Password',
modify: 'Modify' modify: 'Modify'
}; };

View File

@ -1,4 +1,13 @@
export default { export default {
language: 'Langue',
langs: {
en: 'Anglais',
es: 'Espagnol',
ca: 'Catalan',
fr: 'Français',
mn: 'Russe',
pt: 'Portugais'
},
date: { date: {
days: [ days: [
'Dimanche', 'Dimanche',
@ -81,7 +90,17 @@ export default {
noData: 'Aucune donnée', noData: 'Aucune donnée',
confirm: 'Confirmer', confirm: 'Confirmer',
delete: 'Effacer', delete: 'Effacer',
emptyList: 'Vider la liste', confirmDelete: 'Voulez-vous vraiment supprimer la ligne?',
modify: 'Modifier', emptyList: 'Liste vide',
confirmDelete: 'Voulez-vous vraiment supprimer la ligne?'
logInAsGuest: `Entrez en tant qu'invité`,
haveForgottenPassword: 'Avez-vous oublié votre mot de passe?',
signUp: `S'inscrire`,
notACustomerYet: `Pas encore client?`,
loginPhone: '+34 963 242 100',
loginMail: "{'info'}{'@'}{'verdnatura.es'}",
remindMe: `Rappelle-moi`,
user: 'Utilisateur',
password: 'Mot de passe',
modify: 'Modifier'
}; };

View File

@ -1,4 +1,13 @@
export default { export default {
language: 'Língua',
langs: {
en: 'Inglês',
es: 'Espanhol',
ca: 'Catalão',
fr: 'Francês',
mn: 'Russo',
pt: 'Português'
},
date: { date: {
days: [ days: [
'Domingo', 'Domingo',
@ -79,7 +88,17 @@ export default {
noData: 'Sem dados', noData: 'Sem dados',
confirm: 'Confirme', confirm: 'Confirme',
delete: 'Eliminar', delete: 'Eliminar',
confirmDelete: 'Tens certeza que queres eliminar esta linha?',
emptyList: 'Lista vazia', emptyList: 'Lista vazia',
modify: 'Modificar',
confirmDelete: 'Tens certeza que queres eliminar esta linha?' logInAsGuest: 'Entrar como convidado',
haveForgottenPassword: 'Esqueceu a senha?',
signUp: 'Registar',
notACustomerYet: 'Ainda não é cliente?',
loginPhone: '+34 963 242 100',
loginMail: "{'info'}{'@'}{'verdnatura.es'}",
remindMe: 'Lembrar-me',
user: 'Utilizador',
password: 'Senha',
modify: 'Modificar'
}; };

View File

@ -22,11 +22,9 @@ const toggleLeftDrawer = () => {
}; };
onMounted(async () => { onMounted(async () => {
appStore.isHeaderMounted = true;
await userStore.fetchUser();
await appStore.loadConfig(); await appStore.loadConfig();
await userStore.supplantInit();
await appStore.getMenuLinks(); await appStore.getMenuLinks();
appStore.isHeaderMounted = true;
}); });
const logout = async () => { const logout = async () => {

View File

@ -99,7 +99,9 @@ onMounted(() => fetchLanguagesSql());
option-label="name" option-label="name"
option-value="code" option-value="code"
:options="langOptions" :options="langOptions"
@update:model-value="vnFormRef.submit()" @update:model-value="
userStore.updateUserLang(data.lang)
"
/> />
</template> </template>
<template #extraForm> <template #extraForm>

View File

@ -1,12 +1,15 @@
<script setup> <script setup>
import { onMounted, ref, computed } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useUserStore } from 'stores/user'; import { useUserStore } from 'stores/user';
import { onMounted, ref } from 'vue';
import useNotify from 'src/composables/useNotify.js'; import useNotify from 'src/composables/useNotify.js';
import { useRouter, useRoute } from 'vue-router'; import { useRouter, useRoute } from 'vue-router';
const { notify } = useNotify();
const t = useI18n(); const { notify } = useNotify();
const { t } = useI18n();
const { locale } = useI18n({ useScope: 'global' });
const userStore = useUserStore(); const userStore = useUserStore();
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
@ -15,7 +18,17 @@ const password = ref(null);
const remember = ref(false); const remember = ref(false);
const showPwd = ref(false); const showPwd = ref(false);
const langs = ['en', 'es', 'ca', 'fr', 'mn', 'pt']; const selectedLocaleValue = computed({
get() {
return userStore.localeOptions.find(
option => option.lang === locale.value
).value;
},
set(value) {
locale.value = value;
}
});
onMounted(() => { onMounted(() => {
if (route.query.emailConfirmed !== undefined) { if (route.query.emailConfirmed !== undefined) {
notify({ notify({
@ -30,7 +43,9 @@ onMounted(() => {
}); });
async function onLogin() { async function onLogin() {
await userStore.login(email.value, password.value, remember.value); await userStore.login(email.value, password.value, remember.value);
router.push('/'); await userStore.fetchUser();
await userStore.updateUserLang(selectedLocaleValue.value);
await router.push('/');
} }
</script> </script>
@ -57,29 +72,25 @@ async function onLogin() {
/> />
</template> </template>
</QInput> </QInput>
<div class="text-center"> <div class="row justify-between text-center">
<QCheckbox <QCheckbox
v-model="remember" v-model="remember"
:label="$t('remindMe')" :label="$t('remindMe')"
dense dense
class="col"
/>
<QSelect
v-model="selectedLocaleValue"
:options="userStore.localeOptions"
:label="t('language')"
option-value="lang"
dense
borderless
emit-value
map-options
options-dense
class="col-4"
/> />
<QBtn
id="switchLanguage"
:label="$t('language')"
icon="translate"
color="primary"
size="sm"
flat
rounded
>
<QMenu auto-close>
<QList dense v-for="lang in langs" :key="lang">
<QItem disabled v-ripple clickable>
{{ $t(`langs.${lang}`) }}
</QItem>
</QList>
</QMenu>
</QBtn>
</div> </div>
</div> </div>
<div class="justify-center"> <div class="justify-center">
@ -177,28 +188,3 @@ a {
} }
} }
</style> </style>
<i18n lang="yaml">
en-US:
user: User
password: Password
remindMe: Remind me
logInAsGuest: Log in as guest
logIn: Log in
loginMail: infoverdnatura.es
loginPhone: +34 607 562 391
haveForgottenPassword: Have you forgotten your password?
notACustomerYet: Not a customer yet?
signUp: Register
es-ES:
user: Usuario
password: Contraseña
remindMe: Recuérdame
logInAsGuest: Entrar como invitado
logIn: Iniciar sesión
loginMail: infoverdnatura.es
loginPhone: +34 963 242 100
haveForgottenPassword: ¿Has olvidado tu contraseña?
notACustomerYet: ¿Todavía no eres cliente?
signUp: Registrarme
</i18n>

View File

@ -1,5 +1,10 @@
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import { api, jApi } from 'boot/axios'; import { api, jApi } from 'boot/axios';
import { i18n } from 'src/boot/i18n';
import useNotify from 'src/composables/useNotify.js';
const { t } = i18n.global;
const { notify } = useNotify();
export const useUserStore = defineStore('user', { export const useUserStore = defineStore('user', {
state: () => { state: () => {
@ -11,20 +16,36 @@ export const useUserStore = defineStore('user', {
token, token,
isGuest: false, isGuest: false,
user: null, user: null,
supplantedUser: null supplantedUser: null,
localeOptions: [
{ label: t('langs.en'), lang: 'en-US', value: 'en' },
{ label: t('langs.es'), lang: 'es-ES', value: 'es' },
{ label: t('langs.ca'), lang: 'ca-ES', value: 'ca' },
{ label: t('langs.fr'), lang: 'fr-FR', value: 'fr' },
{ label: t('langs.pt'), lang: 'pt-PT', value: 'pt' }
]
}; };
}, },
getters: { getters: {
loggedIn: state => state.token != null loggedIn: state => state.token != null,
userLocaleOption: state =>
state.localeOptions?.find(l => l.value === state?.user?.lang)
}, },
actions: { actions: {
async init() {
await this.fetchUser();
await this.supplantInit();
this.updateSiteLocale();
},
async getToken() { async getToken() {
this.token = this.token =
sessionStorage.getItem('vnToken') || sessionStorage.getItem('vnToken') ||
localStorage.getItem('vnToken'); localStorage.getItem('vnToken');
}, },
async login(user, password, remember) { async login(user, password, remember) {
const params = { user, password }; const params = { user, password };
const res = await api.post('Accounts/login', params); const res = await api.post('Accounts/login', params);
@ -40,6 +61,7 @@ export const useUserStore = defineStore('user', {
name: user name: user
}); });
}, },
async logout() { async logout() {
if (this.token != null) { if (this.token != null) {
try { try {
@ -54,7 +76,7 @@ export const useUserStore = defineStore('user', {
async fetchUser(userType = 'user') { async fetchUser(userType = 'user') {
try { try {
const userData = await jApi.getObject( const userData = await jApi.getObject(
'SELECT id, nickname, name FROM account.myUser' 'SELECT id, nickname, name, lang FROM account.myUser'
); );
this.$patch({ [userType]: userData }); this.$patch({ [userType]: userData });
} catch (error) { } catch (error) {
@ -83,6 +105,19 @@ export const useUserStore = defineStore('user', {
await api.post('Accounts/logout'); await api.post('Accounts/logout');
this.getToken(); this.getToken();
await this.fetchUser(); await this.fetchUser();
},
updateSiteLocale(locale = null) {
i18n.global.locale.value =
locale || this.userLocaleOption.lang || 'en-US';
},
async updateUserLang(lang) {
if (!this.user || this.user.lang === lang) return;
this.user.lang = lang;
this.updateSiteLocale();
notify(t('dataSaved'), 'positive');
} }
} }
}); });