Merge branch 'dev' into warmFix_customerDescriptorActions
gitea/salix-front/pipeline/pr-dev This commit looks good
Details
gitea/salix-front/pipeline/pr-dev This commit looks good
Details
This commit is contained in:
commit
61cd8c49c6
|
@ -4,8 +4,9 @@ import { Router } from 'src/router';
|
||||||
import useNotify from 'src/composables/useNotify.js';
|
import useNotify from 'src/composables/useNotify.js';
|
||||||
import { useStateQueryStore } from 'src/stores/useStateQueryStore';
|
import { useStateQueryStore } from 'src/stores/useStateQueryStore';
|
||||||
|
|
||||||
let session, notify, stateQuery;
|
const session = useSession();
|
||||||
|
const { notify } = useNotify();
|
||||||
|
const stateQuery = useStateQueryStore();
|
||||||
const baseUrl = '/api/';
|
const baseUrl = '/api/';
|
||||||
|
|
||||||
axios.defaults.baseURL = baseUrl;
|
axios.defaults.baseURL = baseUrl;
|
||||||
|
@ -50,15 +51,9 @@ const onResponseError = (error) => {
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
};
|
};
|
||||||
|
|
||||||
export function setupAxios() {
|
axios.interceptors.request.use(onRequest, onRequestError);
|
||||||
session = useSession();
|
axios.interceptors.response.use(onResponse, onResponseError);
|
||||||
notify = useNotify().notify;
|
axiosNoError.interceptors.request.use(onRequest);
|
||||||
stateQuery = useStateQueryStore();
|
axiosNoError.interceptors.response.use(onResponse);
|
||||||
|
|
||||||
axios.interceptors.request.use(onRequest, onRequestError);
|
|
||||||
axios.interceptors.response.use(onResponse, onResponseError);
|
|
||||||
axiosNoError.interceptors.request.use(onRequest);
|
|
||||||
axiosNoError.interceptors.response.use(onResponse);
|
|
||||||
}
|
|
||||||
|
|
||||||
export { onRequest, onResponseError, axiosNoError };
|
export { onRequest, onResponseError, axiosNoError };
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { boot } from 'quasar/wrappers';
|
import { boot } from 'quasar/wrappers';
|
||||||
import qFormMixin from './qformMixin';
|
import qFormMixin from './qformMixin';
|
||||||
import keyShortcut from './keyShortcut';
|
import keyShortcut from './keyShortcut';
|
||||||
import { setupAxios } from 'src/boot/axios';
|
|
||||||
import useNotify from 'src/composables/useNotify.js';
|
import useNotify from 'src/composables/useNotify.js';
|
||||||
import { CanceledError } from 'axios';
|
import { CanceledError } from 'axios';
|
||||||
|
|
||||||
|
@ -49,5 +48,4 @@ export default boot(({ app }) => {
|
||||||
|
|
||||||
notify(message ?? 'globals.error', 'negative', 'error');
|
notify(message ?? 'globals.error', 'negative', 'error');
|
||||||
};
|
};
|
||||||
setupAxios();
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -17,19 +17,12 @@ const config = reactive({
|
||||||
const type = Object.keys(config).find((key) => key in useAttrs()) || 'sip';
|
const type = Object.keys(config).find((key) => key in useAttrs()) || 'sip';
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
onBeforeMount(async () => {
|
||||||
let url;
|
|
||||||
let { channel } = config[type];
|
let { channel } = config[type];
|
||||||
|
|
||||||
if (type === 'say-simple') {
|
if (type === 'say-simple') {
|
||||||
url = (await axios.get('SaySimpleConfigs/findOne')).data.url;
|
const { url, defaultChannel } = (await axios.get('SaySimpleConfigs/findOne'))
|
||||||
if (!channel)
|
.data;
|
||||||
channel = (
|
if (!channel) channel = defaultChannel;
|
||||||
await axios.get('SaySimpleCountries/findOne', {
|
|
||||||
params: {
|
|
||||||
filter: { fields: ['channel'], where: { countryFk: 0 } },
|
|
||||||
},
|
|
||||||
})
|
|
||||||
).data?.channel;
|
|
||||||
|
|
||||||
config[
|
config[
|
||||||
type
|
type
|
||||||
|
|
|
@ -247,6 +247,7 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateStateParams() {
|
function updateStateParams() {
|
||||||
|
if (!route?.path) return;
|
||||||
const newUrl = { path: route.path, query: { ...(route.query ?? {}) } };
|
const newUrl = { path: route.path, query: { ...(route.query ?? {}) } };
|
||||||
if (store?.searchUrl)
|
if (store?.searchUrl)
|
||||||
newUrl.query[store.searchUrl] = JSON.stringify(store.currentFilter);
|
newUrl.query[store.searchUrl] = JSON.stringify(store.currentFilter);
|
||||||
|
|
|
@ -8,13 +8,9 @@ import useNotify from './useNotify';
|
||||||
import { useTokenConfig } from './useTokenConfig';
|
import { useTokenConfig } from './useTokenConfig';
|
||||||
const TOKEN_MULTIMEDIA = 'tokenMultimedia';
|
const TOKEN_MULTIMEDIA = 'tokenMultimedia';
|
||||||
const TOKEN = 'token';
|
const TOKEN = 'token';
|
||||||
let router;
|
|
||||||
export default {
|
|
||||||
setup() {
|
|
||||||
router = useRouter();
|
|
||||||
},
|
|
||||||
};
|
|
||||||
export function useSession() {
|
export function useSession() {
|
||||||
|
const router = useRouter();
|
||||||
const { notify } = useNotify();
|
const { notify } = useNotify();
|
||||||
let isCheckingToken = false;
|
let isCheckingToken = false;
|
||||||
let intervalId = null;
|
let intervalId = null;
|
||||||
|
|
|
@ -2,10 +2,9 @@
|
||||||
import { computed, onBeforeMount, ref, watch, nextTick } from 'vue';
|
import { computed, onBeforeMount, ref, watch, nextTick } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
import VnInputDate from 'components/common/VnInputDate.vue';
|
import VnInputDate from 'components/common/VnInputDate.vue';
|
||||||
import VnInput from 'src/components/common/VnInput.vue';
|
import VnInput from 'src/components/common/VnInput.vue';
|
||||||
|
import VnRow from 'components/ui/VnRow.vue';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import useNotify from 'src/composables/useNotify';
|
import useNotify from 'src/composables/useNotify';
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
|
|
|
@ -194,14 +194,14 @@ const getItemPackagingType = (ticketSales) => {
|
||||||
redirect="ticket"
|
redirect="ticket"
|
||||||
>
|
>
|
||||||
<template #column-nickname="{ row }">
|
<template #column-nickname="{ row }">
|
||||||
<span class="link">
|
<span class="link" @click.stop>
|
||||||
{{ row.nickname }}
|
{{ row.nickname }}
|
||||||
<CustomerDescriptorProxy :id="row.clientFk" />
|
<CustomerDescriptorProxy :id="row.clientFk" />
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #column-routeFk="{ row }">
|
<template #column-routeFk="{ row }">
|
||||||
<span class="link">
|
<span class="link" @click.stop>
|
||||||
{{ row.routeFk }}
|
{{ row.routeFk }}
|
||||||
<RouteDescriptorProxy :id="row.routeFk" />
|
<RouteDescriptorProxy :id="row.routeFk" />
|
||||||
</span>
|
</span>
|
||||||
|
@ -218,7 +218,7 @@ const getItemPackagingType = (ticketSales) => {
|
||||||
<span v-else> {{ toCurrency(row.totalWithVat) }}</span>
|
<span v-else> {{ toCurrency(row.totalWithVat) }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #column-state="{ row }">
|
<template #column-state="{ row }">
|
||||||
<span v-if="row.invoiceOut">
|
<span v-if="row.invoiceOut" @click.stop>
|
||||||
<span :class="{ link: row.invoiceOut.ref }">
|
<span :class="{ link: row.invoiceOut.ref }">
|
||||||
{{ row.invoiceOut.ref }}
|
{{ row.invoiceOut.ref }}
|
||||||
<InvoiceOutDescriptorProxy :id="row.invoiceOut.id" />
|
<InvoiceOutDescriptorProxy :id="row.invoiceOut.id" />
|
||||||
|
|
|
@ -99,7 +99,7 @@ const travelDialogRef = ref(false);
|
||||||
const tableRef = ref();
|
const tableRef = ref();
|
||||||
const travel = ref(null);
|
const travel = ref(null);
|
||||||
const userParams = ref({
|
const userParams = ref({
|
||||||
dated: Date.vnNew(),
|
dated: Date.vnNew().toJSON(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const filter = ref({
|
const filter = ref({
|
||||||
|
@ -219,6 +219,7 @@ function round(value) {
|
||||||
data-key="StockBoughts"
|
data-key="StockBoughts"
|
||||||
url="StockBoughts/getStockBought"
|
url="StockBoughts/getStockBought"
|
||||||
save-url="StockBoughts/crud"
|
save-url="StockBoughts/crud"
|
||||||
|
search-url="StockBoughts"
|
||||||
order="reserve DESC"
|
order="reserve DESC"
|
||||||
:right-search="false"
|
:right-search="false"
|
||||||
:is-editable="true"
|
:is-editable="true"
|
||||||
|
|
|
@ -18,7 +18,7 @@ const $props = defineProps({
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const customUrl = `StockBoughts/getStockBoughtDetail?workerFk=${$props.workerFk}&date=${$props.dated}`;
|
const customUrl = `StockBoughts/getStockBoughtDetail?workerFk=${$props.workerFk}&dated=${$props.dated}`;
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
|
|
@ -27,7 +27,7 @@ onMounted(async () => {
|
||||||
<VnFilterPanel
|
<VnFilterPanel
|
||||||
:data-key="props.dataKey"
|
:data-key="props.dataKey"
|
||||||
:search-button="true"
|
:search-button="true"
|
||||||
search-url="table"
|
search-url="StockBoughts"
|
||||||
@set-user-params="setUserParams"
|
@set-user-params="setUserParams"
|
||||||
>
|
>
|
||||||
<template #tags="{ tag, formatFn }">
|
<template #tags="{ tag, formatFn }">
|
||||||
|
@ -36,12 +36,19 @@ onMounted(async () => {
|
||||||
<span>{{ formatFn(tag.value) }}</span>
|
<span>{{ formatFn(tag.value) }}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #body="{ params }">
|
<template #body="{ params, searchFn }">
|
||||||
<QItem class="q-my-sm">
|
<QItem class="q-my-sm">
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnInputDate
|
<VnInputDate
|
||||||
id="date"
|
id="date"
|
||||||
v-model="params.dated"
|
v-model="params.dated"
|
||||||
|
@update:model-value="
|
||||||
|
(value) => {
|
||||||
|
params.dated = value;
|
||||||
|
setUserParams(params);
|
||||||
|
searchFn();
|
||||||
|
}
|
||||||
|
"
|
||||||
:label="t('Date')"
|
:label="t('Date')"
|
||||||
is-outlined
|
is-outlined
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -268,6 +268,7 @@ onMounted(() => (stateStore.rightDrawer = false));
|
||||||
:label="t('basicData.price')"
|
:label="t('basicData.price')"
|
||||||
type="number"
|
type="number"
|
||||||
min="0"
|
min="0"
|
||||||
|
step="any"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</VnTable>
|
</VnTable>
|
||||||
|
|
|
@ -105,11 +105,14 @@ watch(
|
||||||
<template #option="{ itemProps, opt }">
|
<template #option="{ itemProps, opt }">
|
||||||
<QItem v-bind="itemProps">
|
<QItem v-bind="itemProps">
|
||||||
<QItemSection v-if="opt.code">
|
<QItemSection v-if="opt.code">
|
||||||
<QItemLabel>{{ opt.code }}</QItemLabel>
|
<QItemLabel>
|
||||||
<QItemLabel caption
|
{{ `${opt.code}, ${opt.town?.name}` }}
|
||||||
>{{ opt.town?.province?.name }},
|
</QItemLabel>
|
||||||
{{ opt.town?.province?.country?.name }}</QItemLabel
|
<QItemLabel caption>
|
||||||
>
|
{{
|
||||||
|
`${opt.town?.province?.name}, ${opt.town?.province?.country?.name}`
|
||||||
|
}}
|
||||||
|
</QItemLabel>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -22,7 +22,12 @@ const agencies = ref([]);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<FetchData url="agencies" @on-fetch="(data) => (agencies = data)" auto-load />
|
<FetchData
|
||||||
|
url="AgencyModes"
|
||||||
|
:filter="{ fields: ['id', 'name'] }"
|
||||||
|
@on-fetch="(data) => (agencies = data)"
|
||||||
|
auto-load
|
||||||
|
/>
|
||||||
<VnFilterPanel
|
<VnFilterPanel
|
||||||
:data-key="props.dataKey"
|
:data-key="props.dataKey"
|
||||||
:search-button="true"
|
:search-button="true"
|
||||||
|
|
|
@ -73,6 +73,7 @@ const columns = computed(() => [
|
||||||
inWhere: true,
|
inWhere: true,
|
||||||
attrs: {
|
attrs: {
|
||||||
url: 'AgencyModes',
|
url: 'AgencyModes',
|
||||||
|
fields: ['id', 'name'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
columnField: {
|
columnField: {
|
||||||
|
|
|
@ -14,8 +14,8 @@ import { useUserConfig } from 'src/composables/useUserConfig';
|
||||||
import { useTokenConfig } from 'src/composables/useTokenConfig';
|
import { useTokenConfig } from 'src/composables/useTokenConfig';
|
||||||
import { useAcl } from 'src/composables/useAcl';
|
import { useAcl } from 'src/composables/useAcl';
|
||||||
|
|
||||||
let state, session;
|
const state = useState();
|
||||||
|
const session = useSession();
|
||||||
const { t, te } = i18n.global;
|
const { t, te } = i18n.global;
|
||||||
|
|
||||||
const createHistory = process.env.SERVER
|
const createHistory = process.env.SERVER
|
||||||
|
@ -43,10 +43,8 @@ const Router = createRouter({
|
||||||
* with the Router instance.
|
* with the Router instance.
|
||||||
*/
|
*/
|
||||||
export { Router };
|
export { Router };
|
||||||
export default route((/* { store, ssrContext } */) => {
|
export default route(function (/* { store, ssrContext } */) {
|
||||||
Router.beforeEach(async (to, from, next) => {
|
Router.beforeEach(async (to, from, next) => {
|
||||||
state = useState();
|
|
||||||
session = useSession();
|
|
||||||
const { isLoggedIn } = session;
|
const { isLoggedIn } = session;
|
||||||
const outLayout = Router.options.routes[0].children.map((r) => r.name);
|
const outLayout = Router.options.routes[0].children.map((r) => r.name);
|
||||||
if (!isLoggedIn() && !outLayout.includes(to.name)) {
|
if (!isLoggedIn() && !outLayout.includes(to.name)) {
|
||||||
|
|
|
@ -1,38 +1,23 @@
|
||||||
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
import { Notify } from 'quasar';
|
||||||
import { setupAxios, onRequest, onResponseError } from 'src/boot/axios';
|
import { onRequest, onResponseError } from 'src/boot/axios';
|
||||||
import { useSession } from 'src/composables/useSession';
|
import { describe, expect, it, vi } from 'vitest';
|
||||||
import useNotify from 'src/composables/useNotify';
|
|
||||||
import { useStateQueryStore } from 'src/stores/useStateQueryStore';
|
|
||||||
|
|
||||||
vi.mock('src/composables/useSession');
|
vi.mock('src/composables/useSession', () => ({
|
||||||
vi.mock('src/composables/useNotify');
|
useSession: () => ({
|
||||||
vi.mock('src/stores/useStateQueryStore');
|
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('Axios boot', () => {
|
||||||
let sessionMock, notifyMock, stateQueryMock;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
sessionMock = {
|
|
||||||
getToken: vi.fn().mockReturnValue('DEFAULT_TOKEN'),
|
|
||||||
isLoggedIn: vi.fn().mockReturnValue(true),
|
|
||||||
destroy: vi.fn(),
|
|
||||||
};
|
|
||||||
|
|
||||||
notifyMock = {
|
|
||||||
notify: vi.fn(),
|
|
||||||
};
|
|
||||||
|
|
||||||
stateQueryMock = {
|
|
||||||
add: vi.fn(),
|
|
||||||
remove: vi.fn(),
|
|
||||||
};
|
|
||||||
|
|
||||||
useSession.mockReturnValue(sessionMock);
|
|
||||||
useNotify.mockReturnValue(notifyMock);
|
|
||||||
useStateQueryStore.mockReturnValue(stateQueryMock);
|
|
||||||
|
|
||||||
setupAxios();
|
|
||||||
});
|
|
||||||
describe('onRequest()', async () => {
|
describe('onRequest()', async () => {
|
||||||
it('should set the "Authorization" property on the headers', async () => {
|
it('should set the "Authorization" property on the headers', async () => {
|
||||||
const config = { headers: {} };
|
const config = { headers: {} };
|
||||||
|
|
Loading…
Reference in New Issue