Merge pull request 'Renew token' (!89) from wbuezas/hedera-web-mindshore:feature/RenewToken into 4922-vueMigration
Reviewed-on: #89
This commit is contained in:
commit
8021a171f8
|
@ -2,11 +2,14 @@
|
||||||
import { useAppStore } from 'stores/app';
|
import { useAppStore } from 'stores/app';
|
||||||
import { useUserStore } from 'stores/user';
|
import { useUserStore } from 'stores/user';
|
||||||
import { onBeforeMount } from 'vue';
|
import { onBeforeMount } from 'vue';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
onBeforeMount(async () => {
|
||||||
await userStore.init();
|
await userStore.init(router);
|
||||||
await appStore.init();
|
await appStore.init();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -5,8 +5,7 @@ import { useQuasar } from 'quasar';
|
||||||
|
|
||||||
export function usePrintService() {
|
export function usePrintService() {
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
const userStore = useUserStore();
|
const { getTokenMultimedia } = useUserStore();
|
||||||
const token = userStore.token;
|
|
||||||
|
|
||||||
function sendEmail(path, params) {
|
function sendEmail(path, params) {
|
||||||
return axios.post(path, params).then(() =>
|
return axios.post(path, params).then(() =>
|
||||||
|
@ -18,17 +17,17 @@ export function usePrintService() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function openReport(path, params) {
|
function openReport(path, params, isNewTab = '_self') {
|
||||||
|
if (typeof params === 'string') params = JSON.parse(params);
|
||||||
params = Object.assign(
|
params = Object.assign(
|
||||||
{
|
{
|
||||||
access_token: token
|
access_token: getTokenMultimedia()
|
||||||
},
|
},
|
||||||
params
|
params
|
||||||
);
|
);
|
||||||
|
|
||||||
const query = new URLSearchParams(params).toString();
|
const query = new URLSearchParams(params).toString();
|
||||||
|
window.open(`api/${path}?${query}`, isNewTab);
|
||||||
window.open(`api/${path}?${query}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -73,7 +73,7 @@ export default {
|
||||||
Reports: 'Informes',
|
Reports: 'Informes',
|
||||||
Configuration: 'Configuració',
|
Configuration: 'Configuració',
|
||||||
Shelves: 'Prestatgeries',
|
Shelves: 'Prestatgeries',
|
||||||
Account: 'Compte',
|
Account: 'Configuració',
|
||||||
Addresses: 'Adreces',
|
Addresses: 'Adreces',
|
||||||
OrderSummary: 'Resum de la comanda',
|
OrderSummary: 'Resum de la comanda',
|
||||||
Checkout: `Configurar l'encarrec`,
|
Checkout: `Configurar l'encarrec`,
|
||||||
|
@ -162,5 +162,10 @@ export default {
|
||||||
ErrCantWrite: "No s'ha pogut escriure el fitxer al disc",
|
ErrCantWrite: "No s'ha pogut escriure el fitxer al disc",
|
||||||
ErrExtension: "La pujada del fitxer s'ha aturat per una extensió",
|
ErrExtension: "La pujada del fitxer s'ha aturat per una extensió",
|
||||||
ErrDefault: 'Error de pujada desconegut',
|
ErrDefault: 'Error de pujada desconegut',
|
||||||
'Sync complete': 'Sincronització completa'
|
'Sync complete': 'Sincronització completa',
|
||||||
|
// Errors
|
||||||
|
errors: {
|
||||||
|
statusUnauthorized: 'Accés denegat',
|
||||||
|
tokenConfig: 'Error al obtenir la configuració del token'
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -85,7 +85,7 @@ export default {
|
||||||
Reports: 'Reports',
|
Reports: 'Reports',
|
||||||
Configuration: 'Configuration',
|
Configuration: 'Configuration',
|
||||||
Shelves: 'Shelves',
|
Shelves: 'Shelves',
|
||||||
Account: 'Account',
|
Account: 'Configuration',
|
||||||
Addresses: 'Addresses',
|
Addresses: 'Addresses',
|
||||||
OrderSummary: 'Order summary',
|
OrderSummary: 'Order summary',
|
||||||
Checkout: 'Configure order',
|
Checkout: 'Configure order',
|
||||||
|
@ -195,5 +195,10 @@ export default {
|
||||||
ErrCantWrite: 'Failed to write file to disk',
|
ErrCantWrite: 'Failed to write file to disk',
|
||||||
ErrExtension: 'File upload stopped by extension',
|
ErrExtension: 'File upload stopped by extension',
|
||||||
ErrDefault: 'Unknown upload error',
|
ErrDefault: 'Unknown upload error',
|
||||||
'Sync complete': 'Synchronization complete'
|
'Sync complete': 'Synchronization complete',
|
||||||
|
// Errors
|
||||||
|
errors: {
|
||||||
|
statusUnauthorized: 'Access denied',
|
||||||
|
tokenConfig: 'Error fetching token config'
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -67,11 +67,11 @@ export default {
|
||||||
'Pending orders': 'Pedidos pendientes',
|
'Pending orders': 'Pedidos pendientes',
|
||||||
'Last orders': 'Pedidos confirmados',
|
'Last orders': 'Pedidos confirmados',
|
||||||
Invoices: 'Facturas',
|
Invoices: 'Facturas',
|
||||||
Basket: 'Cesta',
|
Basket: 'Cesta de la compra',
|
||||||
Catalog: 'Catálogo',
|
Catalog: 'Catálogo',
|
||||||
Administration: 'Administración',
|
Administration: 'Administración',
|
||||||
'Control panel': 'Panel de control',
|
'Control panel': 'Panel de control',
|
||||||
Users: 'Usuarios',
|
Users: 'Gestión de usuarios',
|
||||||
Connections: 'Conexiones',
|
Connections: 'Conexiones',
|
||||||
Visits: 'Visitas',
|
Visits: 'Visitas',
|
||||||
News: 'Gestión de noticias',
|
News: 'Gestión de noticias',
|
||||||
|
@ -82,7 +82,7 @@ export default {
|
||||||
Reports: 'Informes',
|
Reports: 'Informes',
|
||||||
Configuration: 'Configuración',
|
Configuration: 'Configuración',
|
||||||
Shelves: 'Estanterías',
|
Shelves: 'Estanterías',
|
||||||
Account: 'Cuenta',
|
Account: 'Configuración',
|
||||||
Addresses: 'Direcciones',
|
Addresses: 'Direcciones',
|
||||||
OrderSummary: 'Resumen del pedido',
|
OrderSummary: 'Resumen del pedido',
|
||||||
Checkout: 'Configurar pedido',
|
Checkout: 'Configurar pedido',
|
||||||
|
@ -108,7 +108,7 @@ export default {
|
||||||
Connections: 'Conexiones',
|
Connections: 'Conexiones',
|
||||||
Visits: 'Visitas',
|
Visits: 'Visitas',
|
||||||
News: 'Noticias',
|
News: 'Noticias',
|
||||||
Photos: 'Imágenes',
|
Photos: 'Fotos',
|
||||||
Items: 'Artículos',
|
Items: 'Artículos',
|
||||||
Account: 'Cuenta',
|
Account: 'Cuenta',
|
||||||
Addresses: 'Direcciones'
|
Addresses: 'Direcciones'
|
||||||
|
@ -194,5 +194,10 @@ export default {
|
||||||
ErrCantWrite: 'Failed to write file to disk',
|
ErrCantWrite: 'Failed to write file to disk',
|
||||||
ErrExtension: 'File upload stopped by extension',
|
ErrExtension: 'File upload stopped by extension',
|
||||||
ErrDefault: 'Unknown upload error',
|
ErrDefault: 'Unknown upload error',
|
||||||
'Sync complete': 'Sincronización completada'
|
'Sync complete': 'Sincronización completada',
|
||||||
|
// Errors
|
||||||
|
errors: {
|
||||||
|
statusUnauthorized: 'Acceso denegado',
|
||||||
|
tokenConfig: 'Error al obtener configuración de token'
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -73,7 +73,7 @@ export default {
|
||||||
Reports: 'Rapports',
|
Reports: 'Rapports',
|
||||||
Configuration: 'Configuration',
|
Configuration: 'Configuration',
|
||||||
Shelves: 'Étagères',
|
Shelves: 'Étagères',
|
||||||
Account: 'Compte',
|
Account: 'Configuration',
|
||||||
Addresses: 'Adresses',
|
Addresses: 'Adresses',
|
||||||
OrderSummary: 'Résumé de la commande',
|
OrderSummary: 'Résumé de la commande',
|
||||||
Checkout: 'Configurer la commande',
|
Checkout: 'Configurer la commande',
|
||||||
|
@ -166,5 +166,11 @@ export default {
|
||||||
ErrCantWrite: "Échec de l'écriture du fichier sur le disque",
|
ErrCantWrite: "Échec de l'écriture du fichier sur le disque",
|
||||||
ErrExtension: 'Téléchargement du fichier arrêté par extension',
|
ErrExtension: 'Téléchargement du fichier arrêté par extension',
|
||||||
ErrDefault: 'Erreur de téléchargement inconnue',
|
ErrDefault: 'Erreur de téléchargement inconnue',
|
||||||
'Sync complete': 'Synchronisation terminée'
|
'Sync complete': 'Synchronisation terminée',
|
||||||
|
// Errors
|
||||||
|
errors: {
|
||||||
|
statusUnauthorized: 'Accès refusé',
|
||||||
|
tokenConfig:
|
||||||
|
'Erreur lors de la récupération de la configuration du jeton'
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -72,7 +72,7 @@ export default {
|
||||||
Reports: 'Informes',
|
Reports: 'Informes',
|
||||||
Configuration: 'Configuração',
|
Configuration: 'Configuração',
|
||||||
Shelves: 'Estantes',
|
Shelves: 'Estantes',
|
||||||
Account: 'Conta',
|
Account: 'Configuração',
|
||||||
Addresses: 'Moradas',
|
Addresses: 'Moradas',
|
||||||
OrderSummary: 'Resumo da encomenda',
|
OrderSummary: 'Resumo da encomenda',
|
||||||
Checkout: 'Configurar encomenda',
|
Checkout: 'Configurar encomenda',
|
||||||
|
@ -159,5 +159,10 @@ export default {
|
||||||
ErrCantWrite: 'Erro ao gravar arquivo no disco',
|
ErrCantWrite: 'Erro ao gravar arquivo no disco',
|
||||||
ErrExtension: 'Erro de extensão do arquivo',
|
ErrExtension: 'Erro de extensão do arquivo',
|
||||||
ErrDefault: 'Erro desconhecido ao subir arquivo',
|
ErrDefault: 'Erro desconhecido ao subir arquivo',
|
||||||
'Sync complete': 'Sincronização completa'
|
'Sync complete': 'Sincronização completa',
|
||||||
|
// Errors
|
||||||
|
errors: {
|
||||||
|
statusUnauthorized: 'Acesso negado',
|
||||||
|
tokenConfig: 'Erro ao obter configuração do token'
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, computed } from 'vue';
|
import { ref, onMounted } from 'vue';
|
||||||
|
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
@ -10,19 +10,19 @@ import { useAppStore } from 'stores/app';
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
const hiddenMenuItems = new Set(['Reports']);
|
|
||||||
|
|
||||||
const refreshContentKey = ref(0);
|
const refreshContentKey = ref(0);
|
||||||
const { user, supplantedUser } = storeToRefs(userStore);
|
const { mainUser, supplantedUser } = storeToRefs(userStore);
|
||||||
const { menuEssentialLinks, title, subtitle, useRightDrawer, rightDrawerOpen } =
|
const {
|
||||||
storeToRefs(appStore);
|
menuTitle,
|
||||||
|
subtitle,
|
||||||
|
useRightDrawer,
|
||||||
|
rightDrawerOpen,
|
||||||
|
filteredMenuItems
|
||||||
|
} = storeToRefs(appStore);
|
||||||
const actions = ref(null);
|
const actions = ref(null);
|
||||||
const leftDrawerOpen = ref(false);
|
const leftDrawerOpen = ref(false);
|
||||||
const filteredMenuItems = computed(() =>
|
|
||||||
menuEssentialLinks.value.filter(
|
|
||||||
item => !hiddenMenuItems.has(item.description)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
const toggleLeftDrawer = () => {
|
const toggleLeftDrawer = () => {
|
||||||
leftDrawerOpen.value = !leftDrawerOpen.value;
|
leftDrawerOpen.value = !leftDrawerOpen.value;
|
||||||
};
|
};
|
||||||
|
@ -58,7 +58,7 @@ const logoutSupplantedUser = async () => {
|
||||||
@click="toggleLeftDrawer"
|
@click="toggleLeftDrawer"
|
||||||
/>
|
/>
|
||||||
<QToolbarTitle>
|
<QToolbarTitle>
|
||||||
{{ title }}
|
{{ menuTitle }}
|
||||||
<div v-if="subtitle" class="subtitle text-caption">
|
<div v-if="subtitle" class="subtitle text-caption">
|
||||||
{{ subtitle }}
|
{{ subtitle }}
|
||||||
</div>
|
</div>
|
||||||
|
@ -82,7 +82,7 @@ const logoutSupplantedUser = async () => {
|
||||||
</QToolbar>
|
</QToolbar>
|
||||||
<div class="user-info">
|
<div class="user-info">
|
||||||
<div>
|
<div>
|
||||||
<span id="user-name">{{ user?.nickname }}</span>
|
<span id="user-name">{{ mainUser?.nickname }}</span>
|
||||||
<QBtn flat icon="logout" alt="_Exit" @click="logout()" />
|
<QBtn flat icon="logout" alt="_Exit" @click="logout()" />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="supplantedUser" id="supplant" class="supplant">
|
<div v-if="supplantedUser" id="supplant" class="supplant">
|
||||||
|
|
|
@ -57,6 +57,15 @@ const formatMailData = data => {
|
||||||
data.isToBeMailed = Boolean(data.isToBeMailed);
|
data.isToBeMailed = Boolean(data.isToBeMailed);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const updateConfigLang = async lang => {
|
||||||
|
try {
|
||||||
|
await vnFormRef.value.submit();
|
||||||
|
userStore.updateUserLang(lang);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
onMounted(() => fetchLanguagesSql());
|
onMounted(() => fetchLanguagesSql());
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -113,9 +122,7 @@ onMounted(() => fetchLanguagesSql());
|
||||||
option-label="name"
|
option-label="name"
|
||||||
option-value="code"
|
option-value="code"
|
||||||
:options="langOptions"
|
:options="langOptions"
|
||||||
@update:model-value="
|
@update:model-value="updateConfigLang(data.lang)"
|
||||||
userStore.updateUserLang(data.lang)
|
|
||||||
"
|
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #extraForm>
|
<template #extraForm>
|
||||||
|
|
|
@ -104,21 +104,27 @@ const fetchData = async () => {
|
||||||
:to="{ name: 'checkout', params: { id: orderId } }"
|
:to="{ name: 'checkout', params: { id: orderId } }"
|
||||||
rounded
|
rounded
|
||||||
no-caps
|
no-caps
|
||||||
/>
|
>
|
||||||
|
<QTooltip>{{ t('configureOrder') }}</QTooltip>
|
||||||
|
</QBtn>
|
||||||
<QBtn
|
<QBtn
|
||||||
icon="shopping_bag"
|
icon="shopping_bag"
|
||||||
:label="t('catalog')"
|
:label="t('catalog')"
|
||||||
:to="{ name: 'catalog' }"
|
:to="{ name: 'catalog' }"
|
||||||
rounded
|
rounded
|
||||||
no-caps
|
no-caps
|
||||||
/>
|
>
|
||||||
|
<QTooltip>{{ t('catalog') }}</QTooltip>
|
||||||
|
</QBtn>
|
||||||
<QBtn
|
<QBtn
|
||||||
icon="shopping_cart_checkout"
|
icon="shopping_cart_checkout"
|
||||||
:label="t('checkout')"
|
:label="t('checkout')"
|
||||||
:to="{ name: 'confirm', params: { id: orderId } }"
|
:to="{ name: 'confirm', params: { id: orderId } }"
|
||||||
rounded
|
rounded
|
||||||
no-caps
|
no-caps
|
||||||
/>
|
>
|
||||||
|
<QTooltip>{{ t('checkout') }}</QTooltip>
|
||||||
|
</QBtn>
|
||||||
</Teleport>
|
</Teleport>
|
||||||
<QPage>
|
<QPage>
|
||||||
<TicketDetails
|
<TicketDetails
|
||||||
|
|
|
@ -626,7 +626,7 @@ const getItemFamilies = async () => {
|
||||||
JOIN vn.itemTypeL10n l ON l.id = t.id
|
JOIN vn.itemTypeL10n l ON l.id = t.id
|
||||||
WHERE t.order >= 0
|
WHERE t.order >= 0
|
||||||
AND t.categoryFk = #category
|
AND t.categoryFk = #category
|
||||||
ORDER BY t.order, l.name;
|
ORDER BY t.order, l.name ASC;
|
||||||
DROP TEMPORARY TABLE tmp.itemAvailable`,
|
DROP TEMPORARY TABLE tmp.itemAvailable`,
|
||||||
{
|
{
|
||||||
category: selectedCategory.value,
|
category: selectedCategory.value,
|
||||||
|
@ -650,7 +650,7 @@ const getItemColors = async () => {
|
||||||
JOIN tmp.itemAvailable a ON a.id = i.id
|
JOIN tmp.itemAvailable a ON a.id = i.id
|
||||||
JOIN vn.inkL10n l ON l.id = i.inkFk
|
JOIN vn.inkL10n l ON l.id = i.inkFk
|
||||||
WHERE (${queryFilter.value})
|
WHERE (${queryFilter.value})
|
||||||
ORDER BY name;
|
ORDER BY name ASC;
|
||||||
DROP TEMPORARY TABLE tmp.itemAvailable;`,
|
DROP TEMPORARY TABLE tmp.itemAvailable;`,
|
||||||
{
|
{
|
||||||
orderId: basketOrderId.value
|
orderId: basketOrderId.value
|
||||||
|
@ -683,7 +683,7 @@ const getProducers = async () => {
|
||||||
JOIN tmp.itemAvailable a ON a.id = i.id
|
JOIN tmp.itemAvailable a ON a.id = i.id
|
||||||
JOIN vn.producer p ON p.id = i.producerFk
|
JOIN vn.producer p ON p.id = i.producerFk
|
||||||
WHERE (${queryFilter.value})
|
WHERE (${queryFilter.value})
|
||||||
ORDER BY name;
|
ORDER BY name ASC;
|
||||||
DROP TEMPORARY TABLE tmp.itemAvailable;`,
|
DROP TEMPORARY TABLE tmp.itemAvailable;`,
|
||||||
{ orderId: basketOrderId.value }
|
{ orderId: basketOrderId.value }
|
||||||
);
|
);
|
||||||
|
@ -704,7 +704,7 @@ const getOrigins = async () => {
|
||||||
JOIN vn.origin o ON o.id = i.originFk
|
JOIN vn.origin o ON o.id = i.originFk
|
||||||
JOIN vn.originL10n l ON l.id = o.id
|
JOIN vn.originL10n l ON l.id = o.id
|
||||||
WHERE (${queryFilter.value})
|
WHERE (${queryFilter.value})
|
||||||
ORDER BY name;
|
ORDER BY name ASC;
|
||||||
DROP TEMPORARY TABLE tmp.itemAvailable;`,
|
DROP TEMPORARY TABLE tmp.itemAvailable;`,
|
||||||
{ orderId: basketOrderId.value }
|
{ orderId: basketOrderId.value }
|
||||||
);
|
);
|
||||||
|
@ -723,7 +723,7 @@ const getSubcategories = async () => {
|
||||||
JOIN vn.itemType t ON t.id = i.typeFk
|
JOIN vn.itemType t ON t.id = i.typeFk
|
||||||
JOIN tmp.itemAvailable a ON a.id = i.id
|
JOIN tmp.itemAvailable a ON a.id = i.id
|
||||||
WHERE (${queryFilter.value})
|
WHERE (${queryFilter.value})
|
||||||
ORDER BY category;
|
ORDER BY category ASC;
|
||||||
DROP TEMPORARY TABLE tmp.itemAvailable;`,
|
DROP TEMPORARY TABLE tmp.itemAvailable;`,
|
||||||
{ orderId: basketOrderId.value }
|
{ orderId: basketOrderId.value }
|
||||||
);
|
);
|
||||||
|
|
|
@ -5,17 +5,16 @@ import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
import TicketDetails from 'src/pages/Ecomerce/TicketDetails.vue';
|
import TicketDetails from 'src/pages/Ecomerce/TicketDetails.vue';
|
||||||
|
|
||||||
import { useUserStore } from 'stores/user';
|
|
||||||
import { useAppStore } from 'stores/app';
|
import { useAppStore } from 'stores/app';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
|
import { usePrintService } from 'src/composables/usePrintService';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const jApi = inject('jApi');
|
const jApi = inject('jApi');
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const userStore = useUserStore();
|
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
const { isHeaderMounted } = storeToRefs(appStore);
|
const { isHeaderMounted } = storeToRefs(appStore);
|
||||||
const { user, token } = storeToRefs(userStore);
|
const { openReport } = usePrintService();
|
||||||
|
|
||||||
const ticket = ref({});
|
const ticket = ref({});
|
||||||
const rows = ref([]);
|
const rows = ref([]);
|
||||||
|
@ -38,16 +37,8 @@ onMounted(async () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const onPrintClick = () => {
|
const onPrintClick = () =>
|
||||||
const params = new URLSearchParams({
|
openReport(`Tickets/${ticket.value.id}/delivery-note-pdf`, {}, '_blank');
|
||||||
access_token: token.value,
|
|
||||||
recipientId: user.value.id,
|
|
||||||
type: 'deliveryNote'
|
|
||||||
});
|
|
||||||
window.open(
|
|
||||||
`/api/Tickets/${ticket.value.id}/delivery-note-pdf?${params.toString()}`
|
|
||||||
);
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
|
@ -5,14 +5,18 @@ import { useI18n } from 'vue-i18n';
|
||||||
import { useUserStore } from 'stores/user';
|
import { useUserStore } from 'stores/user';
|
||||||
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';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
import { useAppStore } from 'src/stores/app';
|
||||||
|
|
||||||
const { notify } = useNotify();
|
const { notify } = useNotify();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { locale } = useI18n({ useScope: 'global' });
|
const { locale } = useI18n({ useScope: 'global' });
|
||||||
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
const appStore = useAppStore();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const { siteLang, localeOptions } = storeToRefs(appStore);
|
||||||
|
|
||||||
const email = ref(null);
|
const email = ref(null);
|
||||||
const password = ref(null);
|
const password = ref(null);
|
||||||
const remember = ref(false);
|
const remember = ref(false);
|
||||||
|
@ -20,12 +24,11 @@ const showPwd = ref(false);
|
||||||
|
|
||||||
const selectedLocaleValue = computed({
|
const selectedLocaleValue = computed({
|
||||||
get() {
|
get() {
|
||||||
return userStore.localeOptions.find(
|
return siteLang.value;
|
||||||
option => option.lang === locale.value
|
|
||||||
).value;
|
|
||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
locale.value = value;
|
locale.value = value;
|
||||||
|
appStore.updateSiteLocale(value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -44,7 +47,6 @@ onMounted(() => {
|
||||||
|
|
||||||
const onLogin = async () => {
|
const onLogin = async () => {
|
||||||
await userStore.fetchUser();
|
await userStore.fetchUser();
|
||||||
await userStore.updateUserLang(selectedLocaleValue.value);
|
|
||||||
await router.push('/');
|
await router.push('/');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -90,7 +92,7 @@ const loginAsGuest = async () => {
|
||||||
/>
|
/>
|
||||||
<QSelect
|
<QSelect
|
||||||
v-model="selectedLocaleValue"
|
v-model="selectedLocaleValue"
|
||||||
:options="userStore.localeOptions"
|
:options="localeOptions"
|
||||||
:label="t('language')"
|
:label="t('language')"
|
||||||
option-value="lang"
|
option-value="lang"
|
||||||
dense
|
dense
|
||||||
|
|
|
@ -7,7 +7,6 @@ import {
|
||||||
createWebHashHistory
|
createWebHashHistory
|
||||||
} from 'vue-router';
|
} from 'vue-router';
|
||||||
import routes from './routes';
|
import routes from './routes';
|
||||||
import { i18n } from 'src/boot/i18n';
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If not building with SSR mode, you can
|
* If not building with SSR mode, you can
|
||||||
|
@ -40,10 +39,9 @@ export default route(function (/* { store, ssrContext } */) {
|
||||||
Router.afterEach((to, from) => {
|
Router.afterEach((to, from) => {
|
||||||
if (from.name === to.name) return;
|
if (from.name === to.name) return;
|
||||||
const app = useAppStore();
|
const app = useAppStore();
|
||||||
|
|
||||||
app.$patch({
|
app.$patch({
|
||||||
title: i18n.global.t(
|
title: to.meta.title || 'Home',
|
||||||
to.meta.title ? `titles.${to.meta.title}` : 'titles.Home'
|
|
||||||
),
|
|
||||||
subtitle: null,
|
subtitle: null,
|
||||||
useRightDrawer: false,
|
useRightDrawer: false,
|
||||||
rightDrawerOpen: true
|
rightDrawerOpen: true
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { useQuasar } from 'quasar';
|
||||||
|
|
||||||
const { notify } = useNotify();
|
const { notify } = useNotify();
|
||||||
const storageOrderName = 'hederaBasket';
|
const storageOrderName = 'hederaBasket';
|
||||||
|
const { t } = i18n.global;
|
||||||
|
|
||||||
export const useAppStore = defineStore('hedera', {
|
export const useAppStore = defineStore('hedera', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
|
@ -16,15 +17,23 @@ export const useAppStore = defineStore('hedera', {
|
||||||
rightDrawerOpen: false,
|
rightDrawerOpen: false,
|
||||||
isHeaderMounted: false,
|
isHeaderMounted: false,
|
||||||
menuEssentialLinks: [],
|
menuEssentialLinks: [],
|
||||||
|
hiddenMenuLinks: new Set(['Reports']),
|
||||||
basketOrderId: null,
|
basketOrderId: null,
|
||||||
localeDates: {
|
localeDates: {
|
||||||
days: [],
|
days: [],
|
||||||
months: [],
|
months: [],
|
||||||
daysShort: [],
|
daysShort: [],
|
||||||
monthsShort: []
|
monthsShort: []
|
||||||
}
|
},
|
||||||
|
siteLang: 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' }
|
||||||
|
]
|
||||||
}),
|
}),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
async getMenuLinks() {
|
async getMenuLinks() {
|
||||||
const sections = await jApi.query('SELECT * FROM myMenu');
|
const sections = await jApi.query('SELECT * FROM myMenu');
|
||||||
|
@ -51,7 +60,6 @@ export const useAppStore = defineStore('hedera', {
|
||||||
|
|
||||||
this.menuEssentialLinks = sectionTree;
|
this.menuEssentialLinks = sectionTree;
|
||||||
},
|
},
|
||||||
|
|
||||||
async loadConfig() {
|
async loadConfig() {
|
||||||
const imageUrl = await jApi.getValue('SELECT url FROM imageConfig');
|
const imageUrl = await jApi.getValue('SELECT url FROM imageConfig');
|
||||||
this.$patch({ imageUrl });
|
this.$patch({ imageUrl });
|
||||||
|
@ -68,7 +76,7 @@ export const useAppStore = defineStore('hedera', {
|
||||||
},
|
},
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
// this.router.push({ name: 'login' });
|
this.updateSiteLocale(localStorage.getItem('siteLang') || 'es-ES');
|
||||||
this.getBasketOrderId();
|
this.getBasketOrderId();
|
||||||
this.getLocaleDates();
|
this.getLocaleDates();
|
||||||
},
|
},
|
||||||
|
@ -145,9 +153,24 @@ export const useAppStore = defineStore('hedera', {
|
||||||
onLogout() {
|
onLogout() {
|
||||||
this.unloadOrder();
|
this.unloadOrder();
|
||||||
this.menuEssentialLinks = [];
|
this.menuEssentialLinks = [];
|
||||||
|
},
|
||||||
|
|
||||||
|
updateSiteLocale(locale = null) {
|
||||||
|
const _locale = locale || 'es-ES';
|
||||||
|
i18n.global.locale.value = _locale;
|
||||||
|
this.siteLang = _locale;
|
||||||
|
localStorage.setItem('siteLang', _locale);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
|
filteredMenuItems: state => {
|
||||||
|
return (state.menuEssentialLinks || []).filter(
|
||||||
|
item => !state.hiddenMenuLinks.has(item.description)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
siteLocaleOption: state =>
|
||||||
|
state.localeOptions.find(l => l.value === state.siteLang),
|
||||||
|
menuTitle: state => t(`titles.${state.title}`),
|
||||||
isMobile() {
|
isMobile() {
|
||||||
const $q = useQuasar();
|
const $q = useQuasar();
|
||||||
return $q?.screen?.width <= 768;
|
return $q?.screen?.width <= 768;
|
||||||
|
|
|
@ -1,146 +1,327 @@
|
||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
|
import { ref, computed, watch } from 'vue';
|
||||||
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';
|
import useNotify from 'src/composables/useNotify.js';
|
||||||
import { useAppStore } from 'src/stores/app.js';
|
import { useAppStore } from 'src/stores/app.js';
|
||||||
|
|
||||||
const { t } = i18n.global;
|
|
||||||
const { notify } = useNotify();
|
const { notify } = useNotify();
|
||||||
|
const TOKEN_MULTIMEDIA = 'tokenMultimedia';
|
||||||
|
const TOKEN = 'token';
|
||||||
|
|
||||||
export const useUserStore = defineStore('user', {
|
export const useUserStore = defineStore('user', () => {
|
||||||
state: () => {
|
const token = ref('');
|
||||||
const token =
|
const tokenMultimedia = ref('');
|
||||||
sessionStorage.getItem('vnToken') ||
|
const isGuest = ref(false);
|
||||||
localStorage.getItem('vnToken');
|
const user = ref(null); // Usuario en uso => supplantedUser || mainUser
|
||||||
|
const supplantedUser = ref(null); // Usuario suplantado
|
||||||
|
const mainUser = ref(null); // Usuario principal logueado
|
||||||
|
|
||||||
return {
|
const keepLogin = ref(false);
|
||||||
token,
|
const intervalId = ref(null);
|
||||||
isGuest: false,
|
const isCheckingToken = ref(false);
|
||||||
user: null,
|
const tokenConfig = ref(null);
|
||||||
supplantedUser: null,
|
let router;
|
||||||
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: {
|
const loggedIn = computed(() => !!token.value);
|
||||||
loggedIn: state => state.token != null,
|
const storage = computed(() =>
|
||||||
userLocaleOption: state =>
|
keepLogin.value ? localStorage : sessionStorage
|
||||||
state.localeOptions?.find(l => l.value === state?.user?.lang)
|
);
|
||||||
},
|
|
||||||
|
|
||||||
actions: {
|
const init = async _router => {
|
||||||
async init() {
|
router = _router;
|
||||||
this.isGuest = localStorage.getItem('hederaGuest') || false;
|
isGuest.value = localStorage.getItem('hederaGuest') || false;
|
||||||
const autoLoginStatus = await this.tryAutoLogin();
|
await getToken();
|
||||||
|
if (!loggedIn.value) {
|
||||||
|
const autoLoginStatus = await tryAutoLogin();
|
||||||
if (!autoLoginStatus) {
|
if (!autoLoginStatus) {
|
||||||
this.router.push({ name: 'login' });
|
router.push({ name: 'login' });
|
||||||
}
|
}
|
||||||
await this.fetchUser();
|
|
||||||
await this.supplantInit();
|
|
||||||
this.updateSiteLocale();
|
|
||||||
},
|
|
||||||
|
|
||||||
async getToken() {
|
|
||||||
this.token =
|
|
||||||
sessionStorage.getItem('vnToken') ||
|
|
||||||
localStorage.getItem('vnToken');
|
|
||||||
},
|
|
||||||
|
|
||||||
async tryAutoLogin() {
|
|
||||||
const guest = localStorage.getItem('hederaGuest');
|
|
||||||
|
|
||||||
if (this.isGuest || guest) {
|
|
||||||
localStorage.setItem('hederaGuest', true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.token) this.getToken();
|
|
||||||
|
|
||||||
if (this.token) return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
async login(user, password, remember) {
|
|
||||||
const params = { user, password };
|
|
||||||
const res = await api.post('Accounts/login', params);
|
|
||||||
|
|
||||||
if (remember) {
|
|
||||||
localStorage.setItem('vnToken', res.data.token);
|
|
||||||
} else {
|
|
||||||
sessionStorage.setItem('vnToken', res.data.token);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$patch({
|
|
||||||
token: res.data.token,
|
|
||||||
name: user
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
async logout() {
|
|
||||||
if (this.token != null) {
|
|
||||||
try {
|
|
||||||
await api.post('Accounts/logout');
|
|
||||||
} catch (e) {}
|
|
||||||
localStorage.removeItem('vnToken');
|
|
||||||
sessionStorage.removeItem('vnToken');
|
|
||||||
}
|
|
||||||
this.$reset();
|
|
||||||
localStorage.removeItem('hederaGuest');
|
|
||||||
useAppStore().onLogout();
|
|
||||||
},
|
|
||||||
|
|
||||||
async fetchUser(userType = 'user') {
|
|
||||||
try {
|
|
||||||
const userData = await jApi.getObject(
|
|
||||||
'SELECT id, nickname, name, lang FROM account.myUser'
|
|
||||||
);
|
|
||||||
this.$patch({ [userType]: userData });
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error fetching user: ', error);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
async supplantUser(supplantUser) {
|
|
||||||
const json = await jApi.send('client/supplant', {
|
|
||||||
supplantUser
|
|
||||||
});
|
|
||||||
this.token = json;
|
|
||||||
sessionStorage.setItem('supplantUser', supplantUser);
|
|
||||||
await this.fetchUser('supplantedUser');
|
|
||||||
},
|
|
||||||
|
|
||||||
async supplantInit() {
|
|
||||||
const user = sessionStorage.getItem('supplantUser');
|
|
||||||
if (user == null) return;
|
|
||||||
await this.supplantUser(user);
|
|
||||||
},
|
|
||||||
|
|
||||||
async logoutSupplantedUser() {
|
|
||||||
sessionStorage.removeItem('supplantUser');
|
|
||||||
this.supplantedUser = null;
|
|
||||||
await api.post('Accounts/logout');
|
|
||||||
this.getToken();
|
|
||||||
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');
|
|
||||||
}
|
}
|
||||||
}
|
await fetchTokenConfig();
|
||||||
|
await fetchUser();
|
||||||
|
await supplantInit();
|
||||||
|
startInterval();
|
||||||
|
};
|
||||||
|
|
||||||
|
const getToken = () => {
|
||||||
|
const tokenValue =
|
||||||
|
sessionStorage.getItem(TOKEN) || localStorage.getItem(TOKEN);
|
||||||
|
token.value = tokenValue;
|
||||||
|
return tokenValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getTokenMultimedia = () => {
|
||||||
|
const tokenMultimediaValue =
|
||||||
|
sessionStorage.getItem(TOKEN_MULTIMEDIA) ||
|
||||||
|
localStorage.getItem(TOKEN_MULTIMEDIA);
|
||||||
|
tokenMultimedia.value = tokenMultimediaValue;
|
||||||
|
return tokenMultimediaValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
const setToken = ({ _token, _tokenMultimedia }) => {
|
||||||
|
storage.value.setItem(TOKEN, _token);
|
||||||
|
storage.value.setItem(TOKEN_MULTIMEDIA, _tokenMultimedia);
|
||||||
|
token.value = _token;
|
||||||
|
tokenMultimedia.value = _tokenMultimedia;
|
||||||
|
};
|
||||||
|
|
||||||
|
const destroyToken = async (url, storageType, key) => {
|
||||||
|
if (storageType.getItem(key)) {
|
||||||
|
try {
|
||||||
|
await api.post(url, null, {
|
||||||
|
headers: { Authorization: storageType.getItem(key) }
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
notify('errors.statusUnauthorized', 'negative');
|
||||||
|
} finally {
|
||||||
|
storageType.removeItem(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const destroy = async (destroyTokens = true) => {
|
||||||
|
const tokens = {
|
||||||
|
tokenMultimedia: 'Accounts/logout',
|
||||||
|
token: 'VnUsers/logout'
|
||||||
|
};
|
||||||
|
let destroyTokenPromises = [];
|
||||||
|
try {
|
||||||
|
if (destroyTokens) {
|
||||||
|
const { data: isValidToken } = await api.get(
|
||||||
|
'VnUsers/validateToken'
|
||||||
|
);
|
||||||
|
if (isValidToken) {
|
||||||
|
destroyTokenPromises = Object.entries(tokens).map(
|
||||||
|
([key, url]) => destroyToken(url, storage.value, key)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
localStorage.clear();
|
||||||
|
sessionStorage.clear();
|
||||||
|
await Promise.allSettled(destroyTokenPromises);
|
||||||
|
user.value = null;
|
||||||
|
stopRenewer();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const setSession = data => {
|
||||||
|
setToken({
|
||||||
|
_token: data.token,
|
||||||
|
_tokenMultimedia: data.tokenMultimedia
|
||||||
|
});
|
||||||
|
storage.value.setItem('hederaLastUser', data.username);
|
||||||
|
storage.value.setItem('created', data.created);
|
||||||
|
storage.value.setItem('ttl', data.ttl);
|
||||||
|
localStorage.setItem('keepLogin', keepLogin.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchMultimediaToken = async data => {
|
||||||
|
const {
|
||||||
|
data: { multimediaToken }
|
||||||
|
} = await api.get('VnUsers/ShareToken', {
|
||||||
|
headers: { Authorization: data.token }
|
||||||
|
});
|
||||||
|
return multimediaToken;
|
||||||
|
};
|
||||||
|
|
||||||
|
const login = async (username, password, remember) => {
|
||||||
|
const params = { user: username, password };
|
||||||
|
const { data } = await api.post('Accounts/login', params);
|
||||||
|
|
||||||
|
const multimediaToken = await fetchMultimediaToken(data);
|
||||||
|
if (!multimediaToken) return;
|
||||||
|
|
||||||
|
keepLogin.value = remember;
|
||||||
|
setSession({
|
||||||
|
created: Date.now(),
|
||||||
|
tokenMultimedia: multimediaToken.id,
|
||||||
|
username,
|
||||||
|
...data
|
||||||
|
});
|
||||||
|
await fetchTokenConfig();
|
||||||
|
startInterval();
|
||||||
|
};
|
||||||
|
|
||||||
|
const tryAutoLogin = async () => {
|
||||||
|
if (isGuest.value) {
|
||||||
|
localStorage.setItem('hederaGuest', true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!token.value) getToken();
|
||||||
|
|
||||||
|
if (token.value) return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const logout = async () => {
|
||||||
|
try {
|
||||||
|
await api.post('Accounts/logout');
|
||||||
|
} catch (e) {}
|
||||||
|
destroy();
|
||||||
|
$reset();
|
||||||
|
useAppStore().onLogout();
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchTokenConfig = async () => {
|
||||||
|
try {
|
||||||
|
const { data } = await api.get('AccessTokenConfigs/findOne', {
|
||||||
|
filter: { fields: ['renewInterval', 'renewPeriod'] }
|
||||||
|
});
|
||||||
|
if (!data) return;
|
||||||
|
tokenConfig.value = data;
|
||||||
|
storage.value.setItem('renewPeriod', data.renewPeriod);
|
||||||
|
return data;
|
||||||
|
} catch (error) {
|
||||||
|
notify('errors.tokenConfig', 'negative');
|
||||||
|
console.error('Error fetching token config:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const renewToken = async () => {
|
||||||
|
const _token = getToken();
|
||||||
|
const tokenData = await api.post('VnUsers/renewToken', {
|
||||||
|
headers: { Authorization: _token }
|
||||||
|
});
|
||||||
|
|
||||||
|
const _tokenMultimedia = getTokenMultimedia();
|
||||||
|
const tokenMultimedia = await api.post('VnUsers/renewToken', {
|
||||||
|
headers: { Authorization: _tokenMultimedia }
|
||||||
|
});
|
||||||
|
|
||||||
|
setToken({
|
||||||
|
_token: tokenData.data.id,
|
||||||
|
_tokenMultimedia: tokenMultimedia.data.id
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const checkValidity = async () => {
|
||||||
|
const created = +storage.value.getItem('created');
|
||||||
|
const ttl = +storage.value.getItem('ttl');
|
||||||
|
|
||||||
|
if (isCheckingToken.value || !created) return;
|
||||||
|
isCheckingToken.value = true;
|
||||||
|
|
||||||
|
const renewPeriodInSeconds =
|
||||||
|
Math.min(ttl, tokenConfig.value?.renewPeriod) * 1000;
|
||||||
|
const maxDate = created + renewPeriodInSeconds;
|
||||||
|
const now = new Date().getTime();
|
||||||
|
|
||||||
|
if (isNaN(renewPeriodInSeconds) || now <= maxDate) {
|
||||||
|
isCheckingToken.value = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await renewToken();
|
||||||
|
isCheckingToken.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const stopRenewer = () => {
|
||||||
|
clearInterval(intervalId.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const startInterval = () => {
|
||||||
|
stopRenewer();
|
||||||
|
const renewPeriod = +storage.value.getItem('renewPeriod');
|
||||||
|
if (!renewPeriod) return;
|
||||||
|
intervalId.value = setInterval(
|
||||||
|
() => checkValidity(),
|
||||||
|
renewPeriod * 1000
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchUser = async (userType = 'user') => {
|
||||||
|
try {
|
||||||
|
const userData = await jApi.getObject(
|
||||||
|
'SELECT id, nickname, name, lang FROM account.myUser'
|
||||||
|
);
|
||||||
|
if (userType === 'user') mainUser.value = userData;
|
||||||
|
else supplantedUser.value = userData;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching user: ', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const supplantUser = async supplantUser => {
|
||||||
|
const json = await jApi.send('client/supplant', { supplantUser });
|
||||||
|
token.value = json;
|
||||||
|
sessionStorage.setItem('supplantUser', supplantUser);
|
||||||
|
await fetchUser('supplantedUser');
|
||||||
|
};
|
||||||
|
|
||||||
|
const supplantInit = async () => {
|
||||||
|
const user = sessionStorage.getItem('supplantUser');
|
||||||
|
if (!user) return;
|
||||||
|
await supplantUser(user);
|
||||||
|
};
|
||||||
|
|
||||||
|
const logoutSupplantedUser = async () => {
|
||||||
|
sessionStorage.removeItem('supplantUser');
|
||||||
|
supplantedUser.value = null;
|
||||||
|
await api.post('Accounts/logout');
|
||||||
|
getToken();
|
||||||
|
await fetchUser();
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateUserLang = async lang => {
|
||||||
|
if (!user.value || user.value.lang === lang) return;
|
||||||
|
user.value.lang = lang;
|
||||||
|
};
|
||||||
|
|
||||||
|
const $reset = () => {
|
||||||
|
token.value = '';
|
||||||
|
isGuest.value = false;
|
||||||
|
user.value = null;
|
||||||
|
supplantedUser.value = null;
|
||||||
|
mainUser.value = null;
|
||||||
|
keepLogin.value = false;
|
||||||
|
intervalId.value = null;
|
||||||
|
isCheckingToken.value = false;
|
||||||
|
tokenConfig.value = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(
|
||||||
|
[mainUser, supplantedUser],
|
||||||
|
() => (user.value = supplantedUser.value || mainUser.value),
|
||||||
|
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
token,
|
||||||
|
tokenMultimedia,
|
||||||
|
isGuest,
|
||||||
|
user,
|
||||||
|
supplantedUser,
|
||||||
|
mainUser,
|
||||||
|
keepLogin,
|
||||||
|
intervalId,
|
||||||
|
isCheckingToken,
|
||||||
|
tokenConfig,
|
||||||
|
loggedIn,
|
||||||
|
storage,
|
||||||
|
getToken,
|
||||||
|
getTokenMultimedia,
|
||||||
|
setToken,
|
||||||
|
destroyToken,
|
||||||
|
destroy,
|
||||||
|
setSession,
|
||||||
|
login,
|
||||||
|
tryAutoLogin,
|
||||||
|
logout,
|
||||||
|
fetchTokenConfig,
|
||||||
|
renewToken,
|
||||||
|
checkValidity,
|
||||||
|
stopRenewer,
|
||||||
|
startInterval,
|
||||||
|
fetchUser,
|
||||||
|
supplantUser,
|
||||||
|
supplantInit,
|
||||||
|
logoutSupplantedUser,
|
||||||
|
updateUserLang,
|
||||||
|
init,
|
||||||
|
$reset
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue