diff --git a/cypress.config.js b/cypress.config.js
index f8e771093..e9aeb547a 100644
--- a/cypress.config.js
+++ b/cypress.config.js
@@ -1,4 +1,7 @@
const { defineConfig } = require('cypress');
+// https://docs.cypress.io/app/tooling/reporters
+// https://docs.cypress.io/app/references/configuration
+// https://www.npmjs.com/package/cypress-mochawesome-reporter
module.exports = defineConfig({
e2e: {
@@ -16,6 +19,7 @@ module.exports = defineConfig({
reporterOptions: {
charts: true,
reportPageTitle: 'Cypress Inline Reporter',
+ reportFilename: '[status]_[datetime]-report',
embeddedScreenshots: true,
reportDir: 'test/cypress/reports',
inlineAssets: true,
diff --git a/src/components/CreateNewCityForm.vue b/src/components/CreateNewCityForm.vue
index 85d13beb1..e51a18ef8 100644
--- a/src/components/CreateNewCityForm.vue
+++ b/src/components/CreateNewCityForm.vue
@@ -17,10 +17,6 @@ const $props = defineProps({
type: Number,
default: null,
},
- provinces: {
- type: Array,
- default: () => [],
- },
});
const { t } = useI18n();
@@ -48,7 +44,7 @@ const onDataSaved = (...args) => {
@@ -56,7 +52,6 @@ const onDataSaved = (...args) => {
:province-selected="$props.provinceSelected"
:country-fk="$props.countryFk"
v-model="data.provinceFk"
- :provinces="$props.provinces"
/>
diff --git a/src/components/CreateNewPostcodeForm.vue b/src/components/CreateNewPostcodeForm.vue
index 03cba8ac7..907e49499 100644
--- a/src/components/CreateNewPostcodeForm.vue
+++ b/src/components/CreateNewPostcodeForm.vue
@@ -1,5 +1,5 @@
@@ -143,10 +143,20 @@ async function handleCountries(data) {
ref="townsFetchDataRef"
:sort-by="['name ASC']"
:limit="30"
+ :filter="townFilter"
@on-fetch="handleTowns"
auto-load
url="Towns/location"
/>
+
setTown(value, data)"
+ @filter="filterTowns"
:tooltip="t('Create city')"
v-model="data.townFk"
:options="townsOptions"
@@ -193,7 +204,6 @@ async function handleCountries(data) {
onCityCreated(requestResponse, data)
@@ -208,20 +218,20 @@ async function handleCountries(data) {
:province-selected="data.provinceFk"
@update:model-value="(value) => setProvince(value, data)"
v-model="data.provinceFk"
- :clearable="true"
- :provinces="provincesOptions"
+ @on-province-fetched="handleProvinces"
@on-province-created="onProvinceCreated"
/>
setCountry(value, data)"
/>
diff --git a/src/components/CreateNewProvinceForm.vue b/src/components/CreateNewProvinceForm.vue
index d7df38f9f..a0e681f77 100644
--- a/src/components/CreateNewProvinceForm.vue
+++ b/src/components/CreateNewProvinceForm.vue
@@ -1,5 +1,5 @@
@@ -41,9 +47,7 @@ const onDataSaved = (dataSaved, requestResponse) => {
@on-fetch="(data) => (autonomiesOptions = data)"
auto-load
:filter="{
- where: {
- countryFk: $props.countryFk,
- },
+ where,
}"
url="Autonomies/location"
:sort-by="['name ASC']"
diff --git a/src/components/EditPictureForm.vue b/src/components/EditPictureForm.vue
index cd6107aca..1f158e785 100644
--- a/src/components/EditPictureForm.vue
+++ b/src/components/EditPictureForm.vue
@@ -156,26 +156,22 @@ const rotateRight = () => {
};
const onSubmit = () => {
- try {
- if (!newPhoto.files && !newPhoto.url) {
- notify(t('Select an image'), 'negative');
- return;
- }
-
- const options = {
- type: 'blob',
- };
-
- editor.value
- .result(options)
- .then((result) => {
- const file = new File([result], newPhoto.files?.name || '');
- newPhoto.blob = file;
- })
- .then(() => makeRequest());
- } catch (err) {
- console.error('Error uploading image');
+ if (!newPhoto.files && !newPhoto.url) {
+ notify(t('Select an image'), 'negative');
+ return;
}
+
+ const options = {
+ type: 'blob',
+ };
+
+ editor.value
+ .result(options)
+ .then((result) => {
+ const file = new File([result], newPhoto.files?.name || '');
+ newPhoto.blob = file;
+ })
+ .then(() => makeRequest());
};
const makeRequest = async () => {
diff --git a/src/components/EditTableCellValueForm.vue b/src/components/EditTableCellValueForm.vue
index 14709e884..7755df9ab 100644
--- a/src/components/EditTableCellValueForm.vue
+++ b/src/components/EditTableCellValueForm.vue
@@ -51,21 +51,17 @@ const onDataSaved = () => {
};
const onSubmit = async () => {
- try {
- isLoading.value = true;
- const rowsToEdit = $props.rows.map((row) => ({ id: row.id, itemFk: row.itemFk }));
- const payload = {
- field: selectedField.value.field,
- newValue: newValue.value,
- lines: rowsToEdit,
- };
+ isLoading.value = true;
+ const rowsToEdit = $props.rows.map((row) => ({ id: row.id, itemFk: row.itemFk }));
+ const payload = {
+ field: selectedField.value.field,
+ newValue: newValue.value,
+ lines: rowsToEdit,
+ };
- await axios.post($props.editUrl, payload);
- onDataSaved();
- isLoading.value = false;
- } catch (err) {
- console.error('Error submitting table cell edit');
- }
+ await axios.post($props.editUrl, payload);
+ onDataSaved();
+ isLoading.value = false;
};
const closeForm = () => {
diff --git a/src/components/FilterItemForm.vue b/src/components/FilterItemForm.vue
index d1ceff4ce..34968ccef 100644
--- a/src/components/FilterItemForm.vue
+++ b/src/components/FilterItemForm.vue
@@ -84,34 +84,30 @@ const tableColumns = computed(() => [
]);
const onSubmit = async () => {
- try {
- let filter = itemFilter;
- const params = itemFilterParams;
- const where = {};
- for (let key in params) {
- const value = params[key];
- if (!value) continue;
+ let filter = itemFilter;
+ const params = itemFilterParams;
+ const where = {};
+ for (let key in params) {
+ const value = params[key];
+ if (!value) continue;
- switch (key) {
- case 'name':
- where[key] = { like: `%${value}%` };
- break;
- case 'producerFk':
- case 'typeFk':
- case 'size':
- case 'inkFk':
- where[key] = value;
- }
+ switch (key) {
+ case 'name':
+ where[key] = { like: `%${value}%` };
+ break;
+ case 'producerFk':
+ case 'typeFk':
+ case 'size':
+ case 'inkFk':
+ where[key] = value;
}
- filter.where = where;
-
- const { data } = await axios.get(props.url, {
- params: { filter: JSON.stringify(filter) },
- });
- tableRows.value = data;
- } catch (err) {
- console.error('Error fetching entries items');
}
+ filter.where = where;
+
+ const { data } = await axios.get(props.url, {
+ params: { filter: JSON.stringify(filter) },
+ });
+ tableRows.value = data;
};
const closeForm = () => {
diff --git a/src/components/FilterTravelForm.vue b/src/components/FilterTravelForm.vue
index a471552f2..9fc91457a 100644
--- a/src/components/FilterTravelForm.vue
+++ b/src/components/FilterTravelForm.vue
@@ -86,32 +86,28 @@ const tableColumns = computed(() => [
]);
const onSubmit = async () => {
- try {
- let filter = travelFilter;
- const params = travelFilterParams;
- const where = {};
- for (let key in params) {
- const value = params[key];
- if (!value) continue;
+ let filter = travelFilter;
+ const params = travelFilterParams;
+ const where = {};
+ for (let key in params) {
+ const value = params[key];
+ if (!value) continue;
- switch (key) {
- case 'agencyModeFk':
- case 'warehouseInFk':
- case 'warehouseOutFk':
- case 'shipped':
- case 'landed':
- where[key] = value;
- }
+ switch (key) {
+ case 'agencyModeFk':
+ case 'warehouseInFk':
+ case 'warehouseOutFk':
+ case 'shipped':
+ case 'landed':
+ where[key] = value;
}
-
- filter.where = where;
- const { data } = await axios.get('Travels', {
- params: { filter: JSON.stringify(filter) },
- });
- tableRows.value = data;
- } catch (err) {
- console.error('Error fetching travels');
}
+
+ filter.where = where;
+ const { data } = await axios.get('Travels', {
+ params: { filter: JSON.stringify(filter) },
+ });
+ tableRows.value = data;
};
const closeForm = () => {
diff --git a/src/components/FormModel.vue b/src/components/FormModel.vue
index c668769e5..bfb470c48 100644
--- a/src/components/FormModel.vue
+++ b/src/components/FormModel.vue
@@ -91,6 +91,10 @@ const $props = defineProps({
type: Boolean,
default: true,
},
+ maxWidth: {
+ type: [String, Boolean],
+ default: '800px',
+ },
});
const emit = defineEmits(['onFetch', 'onDataSaved']);
const modelValue = computed(
@@ -283,6 +287,7 @@ defineExpose({
@submit="save"
@reset="reset"
class="q-pa-md"
+ :style="maxWidth ? 'max-width: ' + maxWidth : ''"
id="formModel"
>
@@ -371,7 +376,6 @@ defineExpose({
color: black;
}
#formModel {
- max-width: 800px;
width: 100%;
}
diff --git a/src/components/FormPopup.vue b/src/components/FormPopup.vue
index d7f744984..e1c15fcf4 100644
--- a/src/components/FormPopup.vue
+++ b/src/components/FormPopup.vue
@@ -4,7 +4,7 @@ import { useI18n } from 'vue-i18n';
const emit = defineEmits(['onSubmit']);
-defineProps({
+const $props = defineProps({
title: {
type: String,
default: '',
@@ -25,16 +25,21 @@ defineProps({
type: String,
default: '',
},
+ submitOnEnter: {
+ type: Boolean,
+ default: true,
+ },
});
const { t } = useI18n();
-
const closeButton = ref(null);
const isLoading = ref(false);
const onSubmit = () => {
- emit('onSubmit');
- closeForm();
+ if ($props.submitOnEnter) {
+ emit('onSubmit');
+ closeForm();
+ }
};
const closeForm = () => {
diff --git a/src/components/ItemsFilterPanel.vue b/src/components/ItemsFilterPanel.vue
index 938dceb4d..405577095 100644
--- a/src/components/ItemsFilterPanel.vue
+++ b/src/components/ItemsFilterPanel.vue
@@ -88,20 +88,16 @@ const applyTags = (params, search) => {
};
const fetchItemTypes = async (id) => {
- try {
- const filter = {
- fields: ['id', 'name', 'categoryFk'],
- where: { categoryFk: id },
- include: 'category',
- order: 'name ASC',
- };
- const { data } = await axios.get('ItemTypes', {
- params: { filter: JSON.stringify(filter) },
- });
- itemTypesOptions.value = data;
- } catch (err) {
- console.error('Error fetching item types', err);
- }
+ const filter = {
+ fields: ['id', 'name', 'categoryFk'],
+ where: { categoryFk: id },
+ include: 'category',
+ order: 'name ASC',
+ };
+ const { data } = await axios.get('ItemTypes', {
+ params: { filter: JSON.stringify(filter) },
+ });
+ itemTypesOptions.value = data;
};
const getCategoryClass = (category, params) => {
@@ -111,23 +107,19 @@ const getCategoryClass = (category, params) => {
};
const getSelectedTagValues = async (tag) => {
- try {
- if (!tag?.selectedTag?.id) return;
- tag.value = null;
- const filter = {
- fields: ['value'],
- order: 'value ASC',
- limit: 30,
- };
+ if (!tag?.selectedTag?.id) return;
+ tag.value = null;
+ const filter = {
+ fields: ['value'],
+ order: 'value ASC',
+ limit: 30,
+ };
- const params = { filter: JSON.stringify(filter) };
- const { data } = await axios.get(`Tags/${tag.selectedTag.id}/filterValue`, {
- params,
- });
- tag.valueOptions = data;
- } catch (err) {
- console.error('Error getting selected tag values');
- }
+ const params = { filter: JSON.stringify(filter) };
+ const { data } = await axios.get(`Tags/${tag.selectedTag.id}/filterValue`, {
+ params,
+ });
+ tag.valueOptions = data;
};
const removeTag = (index, params, search) => {
diff --git a/src/components/RefundInvoiceForm.vue b/src/components/RefundInvoiceForm.vue
index 9d9f0cff1..590acede0 100644
--- a/src/components/RefundInvoiceForm.vue
+++ b/src/components/RefundInvoiceForm.vue
@@ -39,14 +39,10 @@ const refund = async () => {
invoiceCorrectionTypeFk: invoiceParams.invoiceCorrectionTypeFk,
};
- try {
- const { data } = await axios.post('InvoiceOuts/refundAndInvoice', params);
- notify(t('Refunded invoice'), 'positive');
- const [id] = data?.refundId || [];
- if (id) router.push({ name: 'InvoiceOutSummary', params: { id } });
- } catch (err) {
- console.error('Error refunding invoice', err);
- }
+ const { data } = await axios.post('InvoiceOuts/refundAndInvoice', params);
+ notify(t('Refunded invoice'), 'positive');
+ const [id] = data?.refundId || [];
+ if (id) router.push({ name: 'InvoiceOutSummary', params: { id } });
};
diff --git a/src/components/TransferInvoiceForm.vue b/src/components/TransferInvoiceForm.vue
index f7050cdba..aa71070d6 100644
--- a/src/components/TransferInvoiceForm.vue
+++ b/src/components/TransferInvoiceForm.vue
@@ -49,36 +49,32 @@ const makeInvoice = async () => {
makeInvoice: checked.value,
};
- try {
- if (checked.value && hasToInvoiceByAddress) {
- const response = await new Promise((resolve) => {
- quasar
- .dialog({
- component: VnConfirm,
- componentProps: {
- title: t('Bill destination client'),
- message: t('transferInvoiceInfo'),
- },
- })
- .onOk(() => {
- resolve(true);
- })
- .onCancel(() => {
- resolve(false);
- });
- });
- if (!response) {
- return;
- }
+ if (checked.value && hasToInvoiceByAddress) {
+ const response = await new Promise((resolve) => {
+ quasar
+ .dialog({
+ component: VnConfirm,
+ componentProps: {
+ title: t('Bill destination client'),
+ message: t('transferInvoiceInfo'),
+ },
+ })
+ .onOk(() => {
+ resolve(true);
+ })
+ .onCancel(() => {
+ resolve(false);
+ });
+ });
+ if (!response) {
+ return;
}
-
- const { data } = await axios.post('InvoiceOuts/transfer', params);
- notify(t('Transferred invoice'), 'positive');
- const id = data?.[0];
- if (id) router.push({ name: 'InvoiceOutSummary', params: { id } });
- } catch (err) {
- console.error('Error transfering invoice', err);
}
+
+ const { data } = await axios.post('InvoiceOuts/transfer', params);
+ notify(t('Transferred invoice'), 'positive');
+ const id = data?.[0];
+ if (id) router.push({ name: 'InvoiceOutSummary', params: { id } });
};
diff --git a/src/components/VnSelectProvince.vue b/src/components/VnSelectProvince.vue
index 9fcbef11e..bfc4ab7b7 100644
--- a/src/components/VnSelectProvince.vue
+++ b/src/components/VnSelectProvince.vue
@@ -1,5 +1,5 @@
{
};
const fetchViewConfigData = async () => {
- try {
- const userConfigFilter = {
- where: { tableCode: $props.tableCode, userFk: user.value.id },
- };
- const userConfig = await getConfig('UserConfigViews', userConfigFilter);
+ const userConfigFilter = {
+ where: { tableCode: $props.tableCode, userFk: user.value.id },
+ };
+ const userConfig = await getConfig('UserConfigViews', userConfigFilter);
- if (userConfig) {
- initialUserConfigViewData.value = userConfig;
- setUserConfigViewData(userConfig.configuration);
- return;
- }
+ if (userConfig) {
+ initialUserConfigViewData.value = userConfig;
+ setUserConfigViewData(userConfig.configuration);
+ return;
+ }
- const defaultConfigFilter = { where: { tableCode: $props.tableCode } };
- const defaultConfig = await getConfig('DefaultViewConfigs', defaultConfigFilter);
+ const defaultConfigFilter = { where: { tableCode: $props.tableCode } };
+ const defaultConfig = await getConfig('DefaultViewConfigs', defaultConfigFilter);
- if (defaultConfig) {
- // Si el backend devuelve una configuración por defecto la usamos
- setUserConfigViewData(defaultConfig.columns);
- return;
- } else {
- // Si no hay configuración por defecto mostramos todas las columnas
- const defaultColumns = {};
- $props.allColumns.forEach((col) => (defaultColumns[col] = true));
- setUserConfigViewData(defaultColumns);
- }
- } catch (err) {
- console.error('Error fetching config view data', err);
+ if (defaultConfig) {
+ // Si el backend devuelve una configuración por defecto la usamos
+ setUserConfigViewData(defaultConfig.columns);
+ return;
+ } else {
+ // Si no hay configuración por defecto mostramos todas las columnas
+ const defaultColumns = {};
+ $props.allColumns.forEach((col) => (defaultColumns[col] = true));
+ setUserConfigViewData(defaultColumns);
}
};
const saveConfig = async () => {
- try {
- const params = {};
- const configuration = {};
+ const params = {};
+ const configuration = {};
- formattedCols.value.forEach((col) => {
- const { name, active } = col;
- configuration[name] = active;
- });
+ formattedCols.value.forEach((col) => {
+ const { name, active } = col;
+ configuration[name] = active;
+ });
- // Si existe una view config del usuario hacemos un update si no la creamos
- if (initialUserConfigViewData.value) {
- params.updates = [
- {
- data: {
- configuration: configuration,
- },
- where: {
- id: initialUserConfigViewData.value.id,
- },
- },
- ];
- } else {
- params.creates = [
- {
- userFk: user.value.id,
- tableCode: $props.tableCode,
- tableConfig: $props.tableCode,
+ // Si existe una view config del usuario hacemos un update si no la creamos
+ if (initialUserConfigViewData.value) {
+ params.updates = [
+ {
+ data: {
configuration: configuration,
},
- ];
- }
-
- const response = await axios.post('UserConfigViews/crud', params);
- if (response.data && response.data[0]) {
- initialUserConfigViewData.value = response.data[0];
- }
- emitSavedConfig();
- notify('globals.dataSaved', 'positive');
- popupProxyRef.value.hide();
- } catch (err) {
- console.error('Error saving user view config', err);
+ where: {
+ id: initialUserConfigViewData.value.id,
+ },
+ },
+ ];
+ } else {
+ params.creates = [
+ {
+ userFk: user.value.id,
+ tableCode: $props.tableCode,
+ tableConfig: $props.tableCode,
+ configuration: configuration,
+ },
+ ];
}
+
+ const response = await axios.post('UserConfigViews/crud', params);
+ if (response.data && response.data[0]) {
+ initialUserConfigViewData.value = response.data[0];
+ }
+ emitSavedConfig();
+ notify('globals.dataSaved', 'positive');
+ popupProxyRef.value.hide();
};
const emitSavedConfig = () => {
diff --git a/src/components/common/VnAccountNumber.vue b/src/components/common/VnAccountNumber.vue
index f7273a72d..c4fa78674 100644
--- a/src/components/common/VnAccountNumber.vue
+++ b/src/components/common/VnAccountNumber.vue
@@ -1,20 +1,24 @@
-
+
diff --git a/src/components/common/VnInput.vue b/src/components/common/VnInput.vue
index 4672529c6..57a495ac3 100644
--- a/src/components/common/VnInput.vue
+++ b/src/components/common/VnInput.vue
@@ -1,5 +1,5 @@
@@ -89,10 +127,12 @@ const mixinRules = [
:type="$attrs.type"
:class="{ required: isRequired }"
@keyup.enter="emit('keyup.enter')"
+ @keydown="handleKeydown"
:clearable="false"
:rules="mixinRules"
:lazy-rules="true"
hide-bottom-space
+ :data-cy="$attrs.dataCy ?? $attrs.label + '_input'"
>
@@ -129,9 +169,11 @@ const mixinRules = [
en:
inputMin: Must be more than {value}
+ maxLength: The value exceeds {value} characters
inputMax: Must be less than {value}
es:
inputMin: Debe ser mayor a {value}
+ maxLength: El valor excede los {value} carácteres
inputMax: Debe ser menor a {value}