0
0
Fork 0

Merge pull request 'Router improvements and load roles on login' (#8) from router-improvements into dev

Reviewed-on: verdnatura/salix-front#8
This commit is contained in:
Carlos Jimenez Ruiz 2022-04-06 06:53:38 +00:00
commit aada44755c
13 changed files with 59 additions and 39 deletions

View File

@ -1,15 +1,15 @@
{
"baseUrl": "http://localhost:8080/",
"fixturesFolder": "test/cypress/fixtures",
"integrationFolder": "test/cypress/integration",
"pluginsFile": "test/cypress/plugins/index.js",
"screenshotsFolder": "test/cypress/screenshots",
"supportFile": "test/cypress/support/index.js",
"videosFolder": "test/cypress/videos",
"fixturesFolder": "tests/cypress/fixtures",
"integrationFolder": "tests/cypress/integration",
"pluginsFile": "tests/cypress/plugins/index.js",
"screenshotsFolder": "tests/cypress/screenshots",
"supportFile": "tests/cypress/support/index.js",
"videosFolder": "tests/cypress/videos",
"video": true,
"component": {
"componentFolder": "src",
"testFiles": "**/*.spec.js",
"supportFile": "test/cypress/support/unit.js"
"supportFile": "tests/cypress/support/unit.js"
}
}

View File

@ -32,7 +32,7 @@ defineEmits(['toggle-drawer']);
<q-icon name="arrow_drop_down" size="s" />
<q-menu>
<q-list style="min-width: 150px">
<q-item clickable>
<q-item :to="{ path: '/customer/create' }" clickable>
<q-item-section>New customer</q-item-section>
</q-item>
<q-item clickable>

View File

@ -3,14 +3,15 @@ import { onMounted, computed } from 'vue';
import { Dark, useQuasar } from 'quasar';
import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router';
import axios from 'axios';
import { useState } from 'src/composables/useState';
import { useSession } from 'src/composables/useSession';
import { useRole } from 'src/composables/useRole';
const quasar = useQuasar();
const state = useState();
const session = useSession();
const role = useRole();
const router = useRouter();
const { t, locale } = useI18n();
@ -28,11 +29,10 @@ const token = session.getToken();
onMounted(async () => {
try {
const { data } = await axios.get('/api/accounts/acl');
const roles = data.roles.map(userRoles => userRoles.role.name);
state.setUser(data.user);
state.setRoles(roles);
const stateRoles = state.getRoles().value
if (stateRoles.length === 0) {
await role.fetch();
}
} catch (error) {
quasar.notify({
message: t('errors.statusUnauthorized'),

View File

@ -12,7 +12,7 @@ jest.mock('vue-router', () => ({
describe('UserPanel', () => {
describe('onMounted', () => {
it('should define the user into state', async () => {
it.only('should define the user into state', async () => {
const userMock = {
user: {
id: 1,
@ -30,7 +30,7 @@ describe('UserPanel', () => {
expect(vm.state.getUser().value).toEqual(expectedUser);
});
xit('should logout and notify the expected error', async () => {
it('should logout and notify the expected error', async () => {
jest.spyOn(axios, 'get').mockRejectedValue(new Error('error'));
const { vm } = createWrapper(UserPanel);

View File

@ -1,9 +1,19 @@
import { useState } from './useState';
import axios from 'axios';
const state = useState();
export function useRole() {
async function fetch() {
const { data } = await axios.get('/api/accounts/acl');
const roles = data.roles.map(userRoles => userRoles.role.name);
state.setUser(data.user);
state.setRoles(roles);
}
function hasAny(roles) {
const { getRoles } = useState();
const roleStore = getRoles();
const roleStore = state.getRoles();
for (const role of roles) {
if (roleStore.value.indexOf(role) !== -1) return true;
@ -13,6 +23,7 @@ export function useRole() {
}
return {
fetch,
hasAny,
};
}

View File

@ -1,4 +1,5 @@
import { useState } from './useState';
import { useRole } from './useRole';
export function useSession() {
function getToken() {
@ -29,6 +30,14 @@ export function useSession() {
});
}
async function login(token, keepLogin) {
const { fetch } = useRole();
setToken({ token, keepLogin });
await fetch();
}
function isLoggedIn() {
const localToken = localStorage.getItem('token');
const sessionToken = sessionStorage.getItem('token');
@ -40,6 +49,7 @@ export function useSession() {
getToken,
setToken,
destroy,
login,
isLoggedIn,
};
}

View File

@ -1,3 +1,3 @@
<template>
<q-card>asd</q-card>
<q-card>Basic Data</q-card>
</template>

View File

@ -4,7 +4,7 @@
<q-card square>
<router-link :to="{ path: '/customer/list' }">
<q-icon name="arrow_back" size="md" color="primary" />
</router-link>
</router-link>Descriptor
</q-card>
</div>

View File

@ -1,13 +1,9 @@
<script setup>
import { ref, computed } from 'vue';
import { useRole } from '/src/composables/useRole';
import { ref } from 'vue';
const slide = ref('style');
const slideText = 'Description text';
const { hasAny } = useRole();
const isSalesPerson = computed(() => hasAny(['salesPerson']));
</script>
@ -19,9 +15,8 @@ const isSalesPerson = computed(() => hasAny(['salesPerson']));
rounded
class="bg-orange text-white q-mb-lg"
>
{{ isSalesPerson }}
Employee notification message
<template #action>
<q-btn flat label="Turn ON Wifi" />
<q-btn flat label="Dismiss" />
</template>
</q-banner>

View File

@ -32,17 +32,19 @@ async function onSubmit() {
password: password.value,
});
session.setToken({
token: data.token,
keepLogin: keepLogin.value,
});
await session.login(data.token, keepLogin.value);
quasar.notify({
message: t('login.loginSuccess'),
type: 'positive',
});
await router.push({ path: '/dashboard' });
const currentRoute = router.currentRoute.value;
if (currentRoute.query && currentRoute.query.redirect) {
router.push(currentRoute.query.redirect);
} else {
router.push({ name: 'Dashboard' });
}
} catch (error) {
if (axios.isAxiosError(error)) {
const errorCode = error.response && error.response.status;

View File

@ -7,6 +7,7 @@ const mockPush = jest.fn();
jest.mock('vue-router', () => ({
useRouter: () => ({
push: mockPush,
currentRoute: { value: 'myCurrentRoute' }
}),
}));
@ -18,6 +19,7 @@ describe('Login', () => {
it('should successfully set the token into session', async () => {
jest.spyOn(axios, 'post').mockResolvedValue({ data: { token: 'token' } });
jest.spyOn(axios, 'get').mockResolvedValue({ data: { roles: [], user: { id: 1 } } });
jest.spyOn(vm.quasar, 'notify')
expect(vm.session.getToken()).toEqual('');

View File

@ -36,18 +36,18 @@ export default route(function (/* { store, ssrContext } */) {
Router.beforeEach((to, from, next) => {
const { isLoggedIn } = session;
if (!isLoggedIn && to.name !== 'Login') {
next({ path: '/login', query: { redirect: to.fullPath } });
if (!isLoggedIn() && to.name !== 'Login') {
next({ name: 'Login', query: { redirect: to.fullPath } });
} else {
const pathRoutes = to.matched;
const droles = pathRoutes.every(route => {
const matches = to.matched;
const hasRequiredRoles = matches.every(route => {
const meta = route.meta;
if (meta.roles)
if (meta && meta.roles)
return role.hasAny(meta.roles)
return true;
});
if (droles) {
if (hasRequiredRoles) {
next();
} else {
next({ path: '/' });

View File

@ -6,7 +6,7 @@ const routes = [
path: '/login',
name: 'Login',
meta: { title: 'logIn' },
component: () => import('../pages/Login/Login.vue'),
component: () => import('../pages/Login/Login.vue')
},
{
path: '/',