diff --git a/src/boot/axios.js b/src/boot/axios.js
index 99a163cca..3bd80f487 100644
--- a/src/boot/axios.js
+++ b/src/boot/axios.js
@@ -2,9 +2,11 @@ import axios from 'axios';
import { useSession } from 'src/composables/useSession';
import { Router } from 'src/router';
import useNotify from 'src/composables/useNotify.js';
+import { useStateQueryStore } from 'src/stores/useStateQueryStore';
const session = useSession();
const { notify } = useNotify();
+const stateQuery = useStateQueryStore();
const baseUrl = '/api/';
axios.defaults.baseURL = baseUrl;
@@ -15,7 +17,7 @@ const onRequest = (config) => {
if (token.length && !config.headers.Authorization) {
config.headers.Authorization = token;
}
-
+ stateQuery.add(config);
return config;
};
@@ -24,10 +26,10 @@ const onRequestError = (error) => {
};
const onResponse = (response) => {
- const { method } = response.config;
+ const config = response.config;
+ stateQuery.remove(config);
- const isSaveRequest = method === 'patch';
- if (isSaveRequest) {
+ if (config.method === 'patch') {
notify('globals.dataSaved', 'positive');
}
@@ -35,6 +37,8 @@ const onResponse = (response) => {
};
const onResponseError = (error) => {
+ stateQuery.remove(error.config);
+
let message = '';
const response = error.response;
diff --git a/src/components/NavBar.vue b/src/components/NavBar.vue
index 00faaebc2..9b0393489 100644
--- a/src/components/NavBar.vue
+++ b/src/components/NavBar.vue
@@ -3,6 +3,7 @@ import { onMounted, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useState } from 'src/composables/useState';
import { useStateStore } from 'stores/useStateStore';
+import { useStateQueryStore } from 'src/stores/useStateQueryStore';
import { useQuasar } from 'quasar';
import PinnedModules from './PinnedModules.vue';
import UserPanel from 'components/UserPanel.vue';
@@ -12,6 +13,7 @@ import VnAvatar from './ui/VnAvatar.vue';
const { t } = useI18n();
const stateStore = useStateStore();
const quasar = useQuasar();
+const stateQuery = useStateQueryStore();
const state = useState();
const user = state.getUser();
const appName = 'Lilium';
@@ -50,6 +52,14 @@ const pinnedModulesRef = ref();
+
diff --git a/src/css/app.scss b/src/css/app.scss
index 905934d4c..d4c76ad6b 100644
--- a/src/css/app.scss
+++ b/src/css/app.scss
@@ -288,3 +288,7 @@ input::-webkit-inner-spin-button {
color: $info;
}
}
+
+.no-visible {
+ visibility: hidden;
+}
diff --git a/src/pages/Item/ItemRequest.vue b/src/pages/Item/ItemRequest.vue
index 8a41bbe04..82c3b48e0 100644
--- a/src/pages/Item/ItemRequest.vue
+++ b/src/pages/Item/ItemRequest.vue
@@ -229,7 +229,7 @@ onBeforeMount(() => {
>
- {{ row.ticketFk }}
+ {{ row.ticketFk }}
@@ -251,7 +251,7 @@ onBeforeMount(() => {
- {{ row.requesterName }}
+ {{ row.requesterName }}
@@ -292,7 +292,7 @@ onBeforeMount(() => {
- {{ row.itemDescription }}
+ {{ row.itemDescription }}
diff --git a/src/pages/Item/ItemRequestFilter.vue b/src/pages/Item/ItemRequestFilter.vue
index 0e81ff5a5..64bc0e575 100644
--- a/src/pages/Item/ItemRequestFilter.vue
+++ b/src/pages/Item/ItemRequestFilter.vue
@@ -174,6 +174,16 @@ const decrement = (paramsObj, key) => {
+
+
+
+
+
@@ -274,11 +284,11 @@ en:
to: To
mine: For me
state: State
+ myTeam: My team
dateFiltersTooltip: Cannot choose a range of dates and days onward at the same time
denied: Denied
accepted: Accepted
pending: Pending
-
es:
params:
search: Búsqueda general
@@ -291,6 +301,7 @@ es:
to: Hasta
mine: Para mi
state: Estado
+ myTeam: Mi equipo
dateFiltersTooltip: No se puede seleccionar un rango de fechas y días en adelante a la vez
denied: Denegada
accepted: Aceptada
diff --git a/src/stores/useStateQueryStore.js b/src/stores/useStateQueryStore.js
new file mode 100644
index 000000000..d25dbb921
--- /dev/null
+++ b/src/stores/useStateQueryStore.js
@@ -0,0 +1,31 @@
+import { ref, computed } from 'vue';
+import { defineStore } from 'pinia';
+
+export const useStateQueryStore = defineStore('stateQueryStore', () => {
+ const queries = ref(new Set());
+
+ function add(query) {
+ queries.value.add(query);
+ return query;
+ }
+
+ function isLoading() {
+ return computed(() => queries.value.size);
+ }
+
+ function remove(query) {
+ queries.value.delete(query);
+ }
+
+ function reset() {
+ queries.value = new Set();
+ }
+
+ return {
+ add,
+ isLoading,
+ remove,
+ queries,
+ reset,
+ };
+});
diff --git a/test/vitest/__tests__/boot/axios.spec.js b/test/vitest/__tests__/boot/axios.spec.js
index feb0d93ea..7a802b4d2 100644
--- a/test/vitest/__tests__/boot/axios.spec.js
+++ b/test/vitest/__tests__/boot/axios.spec.js
@@ -7,41 +7,46 @@ vi.mock('src/composables/useSession', () => ({
getToken: () => 'DEFAULT_TOKEN',
isLoggedIn: () => vi.fn(),
destroy: () => vi.fn(),
- })
+ }),
+}));
+
+vi.mock('src/stores/useStateQueryStore', () => ({
+ useStateQueryStore: () => ({
+ add: () => vi.fn(),
+ remove: () => vi.fn(),
+ }),
}));
describe('Axios boot', () => {
-
describe('onRequest()', async () => {
it('should set the "Authorization" property on the headers', async () => {
const config = { headers: {} };
const resultConfig = onRequest(config);
- expect(resultConfig).toEqual(expect.objectContaining({
- headers: {
- Authorization: 'DEFAULT_TOKEN'
- }
- }));
+ expect(resultConfig).toEqual(
+ expect.objectContaining({
+ headers: {
+ Authorization: 'DEFAULT_TOKEN',
+ },
+ })
+ );
});
- })
+ });
describe('onResponseError()', async () => {
it('should call to the Notify plugin with a message error for an status code "500"', async () => {
- Notify.create = vi.fn()
+ Notify.create = vi.fn();
const error = {
response: {
- status: 500
- }
+ status: 500,
+ },
};
const result = onResponseError(error);
-
- expect(result).rejects.toEqual(
- expect.objectContaining(error)
- );
+ expect(result).rejects.toEqual(expect.objectContaining(error));
expect(Notify.create).toHaveBeenCalledWith(
expect.objectContaining({
message: 'An internal server error has ocurred',
@@ -51,25 +56,22 @@ describe('Axios boot', () => {
});
it('should call to the Notify plugin with a message from the response property', async () => {
- Notify.create = vi.fn()
+ Notify.create = vi.fn();
const error = {
response: {
status: 401,
data: {
error: {
- message: 'Invalid user or password'
- }
- }
- }
+ message: 'Invalid user or password',
+ },
+ },
+ },
};
const result = onResponseError(error);
-
- expect(result).rejects.toEqual(
- expect.objectContaining(error)
- );
+ expect(result).rejects.toEqual(expect.objectContaining(error));
expect(Notify.create).toHaveBeenCalledWith(
expect.objectContaining({
message: 'Invalid user or password',
@@ -77,5 +79,5 @@ describe('Axios boot', () => {
})
);
});
- })
+ });
});
diff --git a/test/vitest/__tests__/stores/useStateQueryStore.spec.js b/test/vitest/__tests__/stores/useStateQueryStore.spec.js
new file mode 100644
index 000000000..ab3afb007
--- /dev/null
+++ b/test/vitest/__tests__/stores/useStateQueryStore.spec.js
@@ -0,0 +1,58 @@
+import { describe, expect, it, beforeEach, beforeAll } from 'vitest';
+import { createWrapper } from 'app/test/vitest/helper';
+
+import { useStateQueryStore } from 'src/stores/useStateQueryStore';
+
+describe('useStateQueryStore', () => {
+ beforeAll(() => {
+ createWrapper({}, {});
+ });
+
+ const stateQueryStore = useStateQueryStore();
+ const { add, isLoading, remove, reset } = useStateQueryStore();
+ const firstQuery = { url: 'myQuery' };
+
+ function getQueries() {
+ return stateQueryStore.queries;
+ }
+
+ beforeEach(() => {
+ reset();
+ expect(getQueries().size).toBeFalsy();
+ });
+
+ it('should add two queries', async () => {
+ expect(getQueries().size).toBeFalsy();
+ add(firstQuery);
+
+ expect(getQueries().size).toBeTruthy();
+ expect(getQueries().has(firstQuery)).toBeTruthy();
+
+ add();
+ expect(getQueries().size).toBe(2);
+ });
+
+ it('should add and remove loading state', async () => {
+ expect(isLoading().value).toBeFalsy();
+ add(firstQuery);
+ expect(isLoading().value).toBeTruthy();
+ remove(firstQuery);
+ expect(isLoading().value).toBeFalsy();
+ });
+
+ it('should add and remove query', async () => {
+ const secondQuery = { ...firstQuery };
+ const thirdQuery = { ...firstQuery };
+
+ add(firstQuery);
+ add(secondQuery);
+
+ const beforeCount = getQueries().size;
+ add(thirdQuery);
+ expect(getQueries().has(thirdQuery)).toBeTruthy();
+
+ remove(thirdQuery);
+ expect(getQueries().has(thirdQuery)).toBeFalsy();
+ expect(getQueries().size).toBe(beforeCount);
+ });
+});