-
diff --git a/src/components/ui/CardSummary.vue b/src/components/ui/CardSummary.vue
new file mode 100644
index 0000000000..87b7002dc5
--- /dev/null
+++ b/src/components/ui/CardSummary.vue
@@ -0,0 +1,119 @@
+
+
+
+
+
+
+
diff --git a/src/components/ui/Confirm.vue b/src/components/ui/VnConfirm.vue
similarity index 53%
rename from src/components/ui/Confirm.vue
rename to src/components/ui/VnConfirm.vue
index bd261f7b45..1b92477ebe 100644
--- a/src/components/ui/Confirm.vue
+++ b/src/components/ui/VnConfirm.vue
@@ -3,30 +3,42 @@ import { ref } from 'vue';
import { useDialogPluginComponent } from 'quasar';
import { useI18n } from 'vue-i18n';
-const $props = defineProps({
+const { t } = useI18n();
+
+const props = defineProps({
+ icon: {
+ type: String,
+ default: null,
+ },
question: {
type: String,
- default: '',
+ default: null,
},
message: {
type: String,
- default: '',
+ default: null,
},
});
defineEmits(['confirm', ...useDialogPluginComponent.emits]);
const { dialogRef, onDialogOK } = useDialogPluginComponent();
-const { t } = useI18n();
-const question = ref($props.question);
-const message = ref($props.question);
+const question = props.question || t('question');
+const message = props.message || t('message');
const isLoading = ref(false);
-
+
+
{{ message }}
@@ -36,7 +48,12 @@ const isLoading = ref(false);
-
+
@@ -47,3 +64,15 @@ const isLoading = ref(false);
min-width: 350px;
}
+
+
+ "en": {
+ "question": "Are you sure you want to continue?",
+ "message": "Confirm"
+ }
+
+ "es": {
+ "question": "¿Seguro que quieres continuar?",
+ "message": "Confirmar"
+ }
+
diff --git a/src/components/ui/VnFilterPanel.vue b/src/components/ui/VnFilterPanel.vue
new file mode 100644
index 0000000000..06bd167235
--- /dev/null
+++ b/src/components/ui/VnFilterPanel.vue
@@ -0,0 +1,198 @@
+
+
+
+
+
+
+
+ {{ t('Applied filters') }}
+
+
+
+
+
+ {{ t('Remove filters') }}
+
+
+ {{ t('Refresh') }}
+
+
+
+
+
+
+ {{ t(`You didn't enter any filter`) }}
+
+
+
+
+
+ {{ chip.label }}:
+ "{{ chip.value }}"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+es:
+ You didn't enter any filter: No has introducido ningún filtro
+ Applied filters: Filtros aplicados
+ Remove filters: Eliminar filtros
+ Refresh: Refrescar
+ Search: Buscar
+ Yes: Si
+ No: No
+
diff --git a/src/components/ui/VnSearchbar.vue b/src/components/ui/VnSearchbar.vue
new file mode 100644
index 0000000000..04f4d72450
--- /dev/null
+++ b/src/components/ui/VnSearchbar.vue
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ props.info }}
+
+
+
+
+
+
+
diff --git a/src/composables/useArrayData.js b/src/composables/useArrayData.js
new file mode 100644
index 0000000000..10e80c7274
--- /dev/null
+++ b/src/composables/useArrayData.js
@@ -0,0 +1,149 @@
+import { onMounted, ref, computed } from 'vue';
+import { useRouter, useRoute } from 'vue-router';
+import axios from 'axios';
+import { useArrayDataStore } from 'stores/useArrayDataStore';
+
+const arrayDataStore = useArrayDataStore();
+
+export function useArrayData(key, userOptions) {
+ if (!key) throw new Error('ArrayData: A key is required to use this composable');
+
+ if (!arrayDataStore.get(key)) {
+ arrayDataStore.set(key);
+ }
+
+ const store = arrayDataStore.get(key);
+ const hasMoreData = ref(false);
+ const router = useRouter();
+ const route = useRoute();
+ let canceller = null;
+
+ const page = ref(1);
+
+ if (typeof userOptions === 'object') {
+ if (userOptions.filter) store.filter = userOptions.filter;
+ if (userOptions.url) store.url = userOptions.url;
+ if (userOptions.limit) store.limit = userOptions.limit;
+ if (userOptions.order) store.order = userOptions.order;
+ }
+
+ onMounted(() => {
+ const query = route.query;
+ if (query.params) {
+ store.userParams = JSON.parse(query.params);
+ }
+ });
+
+ async function fetch({ append = false }) {
+ if (!store.url) return;
+
+ cancelRequest();
+ canceller = new AbortController();
+
+ const filter = {
+ order: store.order,
+ limit: store.limit,
+ skip: store.skip,
+ };
+
+ Object.assign(filter, store.userFilter);
+ Object.assign(store.filter, filter);
+
+ const params = {
+ filter: JSON.stringify(filter),
+ };
+
+ Object.assign(params, store.userParams);
+
+ const response = await axios.get(store.url, {
+ signal: canceller.signal,
+ params,
+ });
+
+ const { limit } = filter;
+
+ hasMoreData.value = response.data.length === limit;
+
+ if (append === true) {
+ if (!store.data) store.data = [];
+ for (const row of response.data) store.data.push(row);
+ }
+
+ if (append === false) {
+ store.data = response.data;
+
+ updateStateParams();
+ }
+
+ canceller = null;
+ }
+
+ function destroy() {
+ if (arrayDataStore.get(key)) {
+ arrayDataStore.clear(key);
+ }
+ }
+
+ function cancelRequest() {
+ if (canceller) {
+ canceller.abort();
+ canceller = null;
+ }
+ }
+
+ async function applyFilter({ filter, params }) {
+ if (filter) store.userFilter = filter;
+ if (params) store.userParams = Object.assign({}, params);
+
+ await fetch({ append: false });
+ }
+
+ async function addFilter({ filter, params }) {
+ if (filter) store.userFilter = Object.assign(store.userFilter, filter);
+ if (params) store.userParams = Object.assign(store.userParams, params);
+
+ await fetch({ append: false });
+ }
+
+ async function loadMore() {
+ if (!hasMoreData.value) return;
+
+ store.skip = store.limit * page.value;
+ page.value += 1;
+
+ await fetch({ append: true });
+ }
+
+ async function refresh() {
+ await fetch({ append: false });
+ }
+
+ function updateStateParams() {
+ const query = {};
+ if (store.order) query.order = store.order;
+ if (store.limit) query.limit = store.limit;
+ if (store.skip) query.skip = store.skip;
+ if (store.userParams && Object.keys(store.userParams).length !== 0)
+ query.params = JSON.stringify(store.userParams);
+
+ router.replace({
+ path: route.path,
+ query: query,
+ });
+ }
+
+ const totalRows = computed(() => store.data && store.data.length | 0);
+
+ return {
+ fetch,
+ applyFilter,
+ addFilter,
+ refresh,
+ destroy,
+ loadMore,
+ store,
+ hasMoreData,
+ totalRows,
+ updateStateParams,
+ };
+}
diff --git a/src/css/app.scss b/src/css/app.scss
index 73660398b5..29e5bb6006 100644
--- a/src/css/app.scss
+++ b/src/css/app.scss
@@ -13,3 +13,20 @@ a {
.link:hover {
color: $orange-4;
}
+
+// Removes chrome autofill background
+input:-webkit-autofill,
+select:-webkit-autofill {
+ color: $input-text-color !important;
+ font-family: $typography-font-family;
+ -webkit-text-fill-color: $input-text-color !important;
+ -webkit-background-clip: text !important;
+ background-clip: text !important;
+}
+
+body.body--light {
+ .q-header .q-toolbar {
+ background-color: white;
+ color: #555;
+ }
+}
diff --git a/src/css/quasar.variables.scss b/src/css/quasar.variables.scss
index aa89a88d97..6ebf7a7a77 100644
--- a/src/css/quasar.variables.scss
+++ b/src/css/quasar.variables.scss
@@ -16,8 +16,6 @@ $primary: #ff9800;
$secondary: #26a69a;
$accent: #9c27b0;
-$dark: #1d1d1d;
-
$positive: #21ba45;
$negative: #c10015;
$info: #31ccec;
@@ -28,6 +26,6 @@ $color-spacer: rgba(255, 255, 255, 0.3);
$border-thin-light: 1px solid $color-spacer-light;
$dark-shadow-color: #000;
+$dark: #292929;
$layout-shadow-dark: 0 0 10px 2px rgba(0, 0, 0, 0.2), 0 0px 10px rgba(0, 0, 0, 0.24);
-
$spacing-md: 16px;
diff --git a/src/filters/toDate.js b/src/filters/toDate.js
index 932c0557e8..8fe8f38366 100644
--- a/src/filters/toDate.js
+++ b/src/filters/toDate.js
@@ -3,10 +3,14 @@ import { useI18n } from 'vue-i18n';
export default function (value, options = {}) {
if (!value) return;
- if (!options.dateStyle) options.dateStyle = 'short';
+ if (!options.dateStyle && !options.timeStyle) {
+ options.day = '2-digit';
+ options.month = '2-digit';
+ options.year = 'numeric';
+ }
const { locale } = useI18n();
const date = new Date(value);
- return new Intl.DateTimeFormat(locale.value, options).format(date)
-}
\ No newline at end of file
+ return new Intl.DateTimeFormat(locale.value, options).format(date);
+}
diff --git a/src/i18n/en/index.js b/src/i18n/en/index.js
index ea56c88f85..b0be9e39ed 100644
--- a/src/i18n/en/index.js
+++ b/src/i18n/en/index.js
@@ -241,6 +241,7 @@ export default {
summary: 'Summary',
basicData: 'Basic Data',
rma: 'RMA',
+ photos: 'Photos',
},
list: {
customer: 'Customer',
@@ -294,6 +295,11 @@ export default {
picked: 'Picked',
returnOfMaterial: 'Return of material authorization (RMA)',
},
+ photo: {
+ fileDescription: 'Claim id {claimId} from client {clientName} id {clientId}',
+ noData: 'There are no images/videos, click here or drag and drop the file',
+ dragDrop: 'Drag and drop it here',
+ },
},
invoiceOut: {
pageTitles: {
diff --git a/src/i18n/es/index.js b/src/i18n/es/index.js
index ffe0f23c51..2b58d7950f 100644
--- a/src/i18n/es/index.js
+++ b/src/i18n/es/index.js
@@ -13,7 +13,7 @@ export default {
darkMode: 'Modo oscuro',
logOut: 'Cerrar sesión',
dataSaved: 'Datos guardados',
- dataDeleted: 'Data deleted',
+ dataDeleted: 'Datos eliminados',
add: 'Añadir',
create: 'Crear',
save: 'Guardar',
@@ -240,6 +240,7 @@ export default {
summary: 'Resumen',
basicData: 'Datos básicos',
rma: 'RMA',
+ photos: 'Fotos',
},
list: {
customer: 'Cliente',
@@ -293,6 +294,12 @@ export default {
picked: 'Recogida',
returnOfMaterial: 'Autorización de retorno de materiales (RMA)',
},
+ photo: {
+ fileDescription:
+ 'Reclamacion ID {claimId} del cliente {clientName} id {clientId}',
+ noData: 'No hay imágenes/videos, haz click aquí o arrastra y suelta el archivo',
+ dragDrop: 'Arrástralo y sueltalo aquí',
+ },
},
invoiceOut: {
pageTitles: {
diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue
index a28f6e1d78..a8d149d0a7 100644
--- a/src/layouts/MainLayout.vue
+++ b/src/layouts/MainLayout.vue
@@ -2,13 +2,26 @@
import { useQuasar } from 'quasar';
import Navbar from 'src/components/NavBar.vue';
+import { useStateStore } from 'stores/useStateStore';
+
const quasar = useQuasar();
+const stateStore = useStateStore();
+
+
+
+
+
diff --git a/src/pages/Claim/Card/ClaimCard.vue b/src/pages/Claim/Card/ClaimCard.vue
index cf8f7687c9..e5116a360f 100644
--- a/src/pages/Claim/Card/ClaimCard.vue
+++ b/src/pages/Claim/Card/ClaimCard.vue
@@ -1,12 +1,23 @@
-
+
+
+
+
@@ -20,31 +31,8 @@ const state = useState();
-
-
-
+
+es:
+ Search claim: Buscar reclamación
+ You can search by claim id or customer name: Puedes buscar por id de la reclamación o nombre del cliente
+
diff --git a/src/pages/Claim/Card/ClaimDescriptor.vue b/src/pages/Claim/Card/ClaimDescriptor.vue
index c3959b7d2c..84b924c2f3 100644
--- a/src/pages/Claim/Card/ClaimDescriptor.vue
+++ b/src/pages/Claim/Card/ClaimDescriptor.vue
@@ -1,13 +1,12 @@
-
-
-
-
+
+
+
-
+
+
+ {{ entity.client.name }}
+ {{ entity.client.name }}
+
+
+
{{ t('claim.card.created') }}
- {{ toDate(claim.created) }}
+ {{ toDate(entity.created) }}
-
+
{{ t('claim.card.state') }}
-
- {{ claim.claimState.description }}
+
+ {{ entity.claimState.description }}
- {{ t('claim.card.ticketId') }}
-
- {{ claim.ticketFk }}
-
-
-
+
+ {{ t('claim.card.ticketId') }}
+
+
+
+ {{ entity.ticketFk }}
+
+
+
+
-
- {{ t('claim.card.assignedTo') }}
- {{ claim.worker.user.name }}
+
+
+ {{ t('claim.card.assignedTo') }}
+
+ {{ entity.worker.user.name }}
@@ -102,7 +106,7 @@ function stateColor(code) {
size="md"
icon="vn:client"
color="primary"
- :to="{ name: 'CustomerCard', params: { id: claim.clientFk } }"
+ :to="{ name: 'CustomerCard', params: { id: entity.clientFk } }"
>
{{ t('claim.card.customerSummary') }}
@@ -110,7 +114,7 @@ function stateColor(code) {
size="md"
icon="vn:ticket"
color="primary"
- :to="{ name: 'TicketCard', params: { id: claim.ticketFk } }"
+ :to="{ name: 'TicketCard', params: { id: entity.ticketFk } }"
>
{{ t('claim.card.claimedTicket') }}
diff --git a/src/pages/Claim/Card/ClaimPhoto.vue b/src/pages/Claim/Card/ClaimPhoto.vue
new file mode 100644
index 0000000000..9e89211b2e
--- /dev/null
+++ b/src/pages/Claim/Card/ClaimPhoto.vue
@@ -0,0 +1,376 @@
+
+
+ setClaimDms(data)"
+ limit="20"
+ auto-load
+ ref="claimDmsRef"
+ />
+ (dmsType = data)"
+ auto-load
+ />
+ (config = data)"
+ auto-load
+ />
+
+
+
+
+ {{ t('claim.photo.dragDrop') }}
+
+
+
+
+
+
+ {{ t('claim.photo.noData') }}
+
+
+
+
+
+
+
+
+
+
+ {{ t('globals.add') }}
+
+
+
+
+
+
+
+
+
+
+ {{ t('globals.add') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ es:
+ This file will be deleted: Este archivo va a ser borrado
+
diff --git a/src/pages/Claim/Card/ClaimRma.vue b/src/pages/Claim/Card/ClaimRma.vue
index 8461eb6bd6..bbcd6e12c6 100644
--- a/src/pages/Claim/Card/ClaimRma.vue
+++ b/src/pages/Claim/Card/ClaimRma.vue
@@ -1,37 +1,47 @@
(claim = data)"
+ :filter="claimFilter"
+ @on-fetch="onFetch"
auto-load
/>
-
+
-
+
- {{ t('claim.rma.user') }}
- {{ row.worker.user.name }}
+
+ {{ t('claim.rma.user') }}
+
+
+ {{ row.worker.user.name }}
+
- {{ t('claim.rma.created') }}
+
+ {{ t('claim.rma.created') }}
+
- {{ toDate(row.created, { timeStyle: 'medium' }) }}
+ {{
+ toDate(row.created, {
+ timeStyle: 'medium',
+ })
+ }}
-
+
{{ t('globals.remove') }}
-
+
-
-
-
-
- {{ t('globals.confirmRemove') }}
-
-
-
-
-
-
-
-
diff --git a/src/pages/Claim/Card/ClaimSummary.vue b/src/pages/Claim/Card/ClaimSummary.vue
index 7c6eeb6d7d..98027b4adb 100644
--- a/src/pages/Claim/Card/ClaimSummary.vue
+++ b/src/pages/Claim/Card/ClaimSummary.vue
@@ -1,12 +1,9 @@
-
-
-
-
-
-
-
-
- {{ t('claim.summary.created') }}
- {{ toDate(claim.created) }}
-
-
- {{ t('claim.summary.state') }}
-
-
- {{ claim.claimState.description }}
-
-
-
-
-
-
- {{ t('claim.summary.assignedTo') }}
- {{ claim.worker.user.nickname }}
-
-
- {{ t('claim.summary.attendedBy') }}
- {{ claim.client.salesPersonUser.name }}
-
-
-
-
- {{ t('claim.summary.details') }}
-
-
-
-
- {{ t(col.label) }}
-
-
-
-
-
-
- {{ t('claim.summary.actions') }}
-
-
-
-
-
-
-
-
-
-
-
+
+
+ {{ claim.id }} - {{ claim.client.name }}
+
+
+
+
+
+
+
+
+ {{ t('claim.summary.created') }}
+
+ {{ toDate(claim.created) }}
+
+
+ {{
+ t('claim.summary.state')
+ }}
+
+
+ {{ claim.claimState.description }}
+
+
+
+
+
+
+ {{
+ t('claim.summary.assignedTo')
+ }}
+ {{
+ claim.worker.user.nickname
+ }}
+
+
+ {{
+ t('claim.summary.attendedBy')
+ }}
+ {{
+ claim.client.salesPersonUser.name
+ }}
+
+
+
+
+
+
+ {{ t('claim.summary.details') }}
+
+
+
+
+ {{ t(col.label) }}
+
+
+
+
+
+
+ {{ t('claim.summary.actions') }}
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/pages/Claim/ClaimFilter.vue b/src/pages/Claim/ClaimFilter.vue
new file mode 100644
index 0000000000..dc33d1808d
--- /dev/null
+++ b/src/pages/Claim/ClaimFilter.vue
@@ -0,0 +1,217 @@
+
+
+
+ (states = data)" auto-load />
+ (workers = data)"
+ auto-load
+ />
+
+
+
+ {{ t(`params.${tag.label}`) }}:
+ {{ formatFn(tag.value) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+en:
+ params:
+ search: Contains
+ clientFk: Customer
+ clientName: Customer
+ salesPersonFk: Salesperson
+ attenderFk: Attender
+ claimResponsibleFk: Responsible
+ claimStateFk: State
+ created: Created
+es:
+ params:
+ search: Contiene
+ clientFk: Cliente
+ clientName: Cliente
+ salesPersonFk: Comercial
+ attenderFk: Asistente
+ claimResponsibleFk: Responsable
+ claimStateFk: Estado
+ created: Creada
+ Customer ID: ID cliente
+ Client Name: Nombre del cliente
+ Salesperson: Comercial
+ Attender: Asistente
+ Responsible: Responsable
+ State: Estado
+ Item: Artículo
+ Created: Creada
+ More options: Más opciones
+
diff --git a/src/pages/Claim/ClaimList.vue b/src/pages/Claim/ClaimList.vue
index 9ab22117e4..708472108f 100644
--- a/src/pages/Claim/ClaimList.vue
+++ b/src/pages/Claim/ClaimList.vue
@@ -1,32 +1,24 @@
+
+
+
+
+
+
-
+
-
+
- {{ row.client.name }}
-
-
-
+ {{ row.clientName }}
#{{ row.id }}
- {{ t('claim.list.customer') }}
- {{ row.client.name }}
+
+ {{ t('claim.list.customer') }}
+
+ {{ row.clientName }}
- {{ t('claim.list.assignedTo') }}
- {{ row.worker.user.name }}
+
+ {{ t('claim.list.assignedTo') }}
+
+ {{ row.workerName }}
- {{ t('claim.list.created') }}
- {{ toDate(row.created) }}
+
+ {{ t('claim.list.created') }}
+
+
+ {{ toDate(row.created) }}
+
- {{ t('claim.list.state') }}
+
+ {{ t('claim.list.state') }}
+
-
- {{ row.claimState.description }}
-
+
+ {{ row.stateDescription }}
+
@@ -111,16 +128,34 @@ function viewSummary(id) {
-->
-
- {{ t('components.smartCard.openCard') }}
+
+
+ {{ t('components.smartCard.openCard') }}
+
-
- {{ t('components.smartCard.openSummary') }}
+
+
+ {{ t('components.smartCard.openSummary') }}
+
- {{ t('components.smartCard.viewDescription') }}
+
+ {{ t('components.smartCard.viewDescription') }}
+
-
+
@@ -130,3 +165,9 @@ function viewSummary(id) {
+
+
+es:
+ Search claim: Buscar reclamación
+ You can search by claim id or customer name: Puedes buscar por id de la reclamación o nombre del cliente
+
diff --git a/src/pages/Claim/ClaimMain.vue b/src/pages/Claim/ClaimMain.vue
index fd50f15216..e4350a6e79 100644
--- a/src/pages/Claim/ClaimMain.vue
+++ b/src/pages/Claim/ClaimMain.vue
@@ -1,12 +1,12 @@
-
+
diff --git a/src/pages/Claim/ClaimRmaList.vue b/src/pages/Claim/ClaimRmaList.vue
index 367169dc45..d4ef1fcf02 100644
--- a/src/pages/Claim/ClaimRmaList.vue
+++ b/src/pages/Claim/ClaimRmaList.vue
@@ -4,16 +4,15 @@ import { useI18n } from 'vue-i18n';
import { useQuasar } from 'quasar';
import axios from 'axios';
import Paginate from 'src/components/PaginateData.vue';
+import { useArrayData } from 'src/composables/useArrayData';
+import VnConfirm from 'src/components/ui/VnConfirm.vue';
const quasar = useQuasar();
const { t } = useI18n();
-const rmas = ref([]);
-const card = ref(null);
-
-function onFetch(data) {
- rmas.value = data.value;
-}
+const arrayData = useArrayData('ClaimRmaList');
+const isLoading = ref(false);
+const input = ref();
const newRma = ref({
code: '',
@@ -24,46 +23,38 @@ function onInputUpdate(value) {
newRma.value.code = value.toUpperCase();
}
-function submit() {
+async function submit() {
const formData = newRma.value;
if (formData.code === '') return;
- axios
- .post('ClaimRmas', formData)
- .then(() => {
- newRma.value = {
- code: '',
- crated: new Date(),
- };
- })
- .then(() => card.value.refresh());
+ isLoading.value = true;
+ await axios.post('ClaimRmas', formData);
+ await arrayData.refresh();
+ isLoading.value = false;
+ input.value.$el.focus();
+
+ newRma.value = {
+ code: '',
+ created: new Date(),
+ };
}
-const confirmShown = ref(false);
-const rmaId = ref(null);
function confirm(id) {
- confirmShown.value = true;
- rmaId.value = id;
-}
-
-function remove() {
- const id = rmaId.value;
- axios
- .delete(`ClaimRmas/${id}`)
- .then(() => {
- confirmShown.value = false;
-
- quasar.notify({
- type: 'positive',
- message: 'Entry deleted',
- icon: 'check',
- });
+ quasar
+ .dialog({
+ component: VnConfirm,
})
- .then(() => card.value.refresh());
+ .onOk(() => remove(id));
}
-function hide() {
- rmaId.value = null;
+async function remove(id) {
+ await axios.delete(`ClaimRmas/${id}`);
+ await arrayData.refresh();
+ quasar.notify({
+ type: 'positive',
+ message: t('globals.rowRemoved'),
+ icon: 'check',
+ });
}
@@ -73,34 +64,74 @@ function hide() {
- {{ rmas.length }} {{ t('claim.rmaList.records') }}
+
+ {{ arrayData.totalRows }} {{ t('claim.rmaList.records') }}
+
-
-
+
-
+
- {{ t('claim.rmaList.code') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{
+ t('claim.rmaList.code')
+ }}
{{ row.code }}
-
+
{{ t('globals.remove') }}
@@ -111,20 +142,6 @@ function hide() {
-
-
-
-
-
- {{ t('globals.confirmRemove') }}
-
-
-
-
-
-
-
-
diff --git a/src/pages/Customer/CustomerCreate.vue b/src/pages/Customer/CustomerCreate.vue
index 52a9ccbc5c..f58a230d91 100644
--- a/src/pages/Customer/CustomerCreate.vue
+++ b/src/pages/Customer/CustomerCreate.vue
@@ -1,13 +1,16 @@
@@ -20,7 +23,7 @@ watch(() => customer.name, () => {
label="Your name *"
hint="Name and surname"
lazy-rules
- :rules="[val => val && val.length > 0 || 'Please type something']"
+ :rules="[(val) => (val && val.length > 0) || 'Please type something']"
/>
customer.name, () => {
label="Your age *"
lazy-rules
:rules="[
- val => val !== null && val !== '' || 'Please type your age',
- val => val > 0 && val < 100 || 'Please type a real age'
+ (val) => (val !== null && val !== '') || 'Please type your age',
+ (val) => (val > 0 && val < 100) || 'Please type a real age',
]"
/>
diff --git a/src/pages/Customer/CustomerFilter.vue b/src/pages/Customer/CustomerFilter.vue
new file mode 100644
index 0000000000..0e9c5be83b
--- /dev/null
+++ b/src/pages/Customer/CustomerFilter.vue
@@ -0,0 +1,200 @@
+
+
+
+ (provinces = data)" auto-load />
+ (zones = data)" auto-load />
+ (workers = data)"
+ auto-load
+ />
+
+
+
+ {{ t(`params.${tag.label}`) }}:
+ {{ formatFn(tag.value) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+en:
+ params:
+ search: Contains
+ fi: FI
+ name: Name
+ socialName: Social Name
+ salesPersonFk: Salesperson
+ provinceFk: Province
+ city: City
+ phone: Phone
+ email: Email
+ zoneFk: Zone
+ postcode: Postcode
+es:
+ params:
+ search: Contiene
+ fi: NIF
+ name: Nombre
+ socialName: Razón Social
+ salesPersonFk: Comercial
+ provinceFk: Provincia
+ city: Ciudad
+ phone: Teléfono
+ email: Email
+ zoneFk: Zona
+ postcode: CP
+ FI: NIF
+ Name: Nombre
+ Social Name: Razón social
+ Salesperson: Comercial
+ Province: Provincia
+ City: Ciudad
+ More options: Más opciones
+ Phone: Teléfono
+ Email: Email
+ Zone: Zona
+ Postcode: Código postal
+
diff --git a/src/pages/Customer/CustomerList.vue b/src/pages/Customer/CustomerList.vue
index c4d54a3557..7457319628 100644
--- a/src/pages/Customer/CustomerList.vue
+++ b/src/pages/Customer/CustomerList.vue
@@ -1,14 +1,23 @@
+
+
+
+
+
+
-
+
-
+
{{ row.name }}
#{{ row.id }}
+
- {{ t('customer.list.email') }}
+
+ {{ t('customer.list.email') }}
+
{{ row.email }}
- {{ t('customer.list.phone') }}
+
+ {{ t('customer.list.phone') }}
+
{{ row.phone }}
@@ -69,11 +97,27 @@ function viewSummary(id) {
-->
-
- {{ t('components.smartCard.openCard') }}
+
+
+ {{ t('components.smartCard.openCard') }}
+
-
- {{ t('components.smartCard.openSummary') }}
+
+
+ {{ t('components.smartCard.openSummary') }}
+
-
+
+
+
+ {{ entity.client.name }}
+ {{ entity.client.name }}
+
+
+
-
- {{ t('ticket.card.ticketId') }}
- #{{ ticket.id }}
-
-
+
{{ t('ticket.card.state') }}
-
- {{ ticket.ticketState.state.name }}
+
+ {{ entity.ticketState.state.name }}
+
+
+
+
+ {{ t('ticket.card.shipped') }}
+
+ {{ toDate(entity.shipped) }}
+
+
+
+
+
+ {{ t('ticket.card.customerId') }}
+
+
+
+ {{ entity.clientFk }}
+
+
+
+
+
+
+
+
+ {{ t('ticket.card.salesPerson') }}
+
+
+ {{ entity.client.salesPersonUser.name }}
-
- {{ t('ticket.card.customerId') }}
-
- {{ ticket.clientFk }}
-
-
-
+
+
+ {{ t('ticket.card.warehouse') }}
-
-
- {{ t('ticket.card.salesPerson') }}
- {{ ticket.client.salesPersonUser.name }}
+ {{ entity.warehouse.name }}
-
-
- {{ t('ticket.card.warehouse') }}
- {{ ticket.warehouse.name }}
-
-
- {{ t('ticket.card.shipped') }}
- {{ toDate(ticket.shipped) }}
-
-
-
+
{{ t('ticket.card.agency') }}
- {{ ticket.agencyMode.name }}
+ {{ entity.agencyMode.name }}
@@ -101,7 +127,7 @@ function stateColor(state) {
size="md"
icon="vn:client"
color="primary"
- :to="{ name: 'CustomerCard', params: { id: ticket.clientFk } }"
+ :to="{ name: 'CustomerCard', params: { id: entity.clientFk } }"
>
{{ t('ticket.card.customerCard') }}
diff --git a/src/pages/Ticket/Card/TicketSummary.vue b/src/pages/Ticket/Card/TicketSummary.vue
index f2cdb4c7a9..111a1e957b 100644
--- a/src/pages/Ticket/Card/TicketSummary.vue
+++ b/src/pages/Ticket/Card/TicketSummary.vue
@@ -29,6 +29,7 @@ const entityId = computed(() => $props.id || route.params.id);
const ticket = ref();
const salesLines = ref(null);
const editableStates = ref([]);
+
async function fetch() {
const { data } = await axios.get(`Tickets/${entityId.value}/summary`);
if (data) {
diff --git a/src/pages/Ticket/TicketFilter.vue b/src/pages/Ticket/TicketFilter.vue
new file mode 100644
index 0000000000..9bbc6b7b32
--- /dev/null
+++ b/src/pages/Ticket/TicketFilter.vue
@@ -0,0 +1,325 @@
+
+
+
+ (provinces = data)" auto-load />
+ (states = data)" auto-load />
+ (agencies = data)" auto-load />
+ (warehouses = data)" auto-load />
+ (workers = data)"
+ auto-load
+ />
+
+
+
+ {{ t(`params.${tag.label}`) }}:
+ {{ formatFn(tag.value) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+en:
+ params:
+ search: Contains
+ clientFk: Customer
+ orderFK: Order
+ dateFrom: From
+ dateTo: To
+ salesPersonFk: Salesperson
+ stateFk: State
+ refFk: Invoice Ref.
+ myTeam: My team
+ pending: Pending
+ hasInvoice: Invoiced
+ hasRoute: Routed
+ provinceFk: Province
+ agencyModeFk: Agency
+ warehouseFk: Warehouse
+es:
+ params:
+ search: Contiene
+ clientFk: Cliente
+ orderFK: Pedido
+ dateFrom: Desde
+ dateTo: Hasta
+ salesPersonFk: Comercial
+ stateFk: Estado
+ refFk: Ref. Factura
+ myTeam: Mi equipo
+ pending: Pendiente
+ hasInvoice: Facturado
+ hasRoute: Enrutado
+ Customer ID: ID Cliente
+ Order ID: ID Pedido
+ From: Desde
+ To: Hasta
+ Salesperson: Comercial
+ State: Estado
+ Invoice Ref.: Ref. Factura
+ My team: Mi equipo
+ Pending: Pendiente
+ With problems: Con problemas
+ Invoiced: Facturado
+ Routed: Enrutado
+ More options: Más opciones
+ Province: Provincia
+ Agency: Agencia
+ Warehouse: Almacén
+ Yes: Si
+ No: No
+
diff --git a/src/pages/Ticket/TicketList.vue b/src/pages/Ticket/TicketList.vue
index d93a1bc950..0f9cfdd4f7 100644
--- a/src/pages/Ticket/TicketList.vue
+++ b/src/pages/Ticket/TicketList.vue
@@ -1,14 +1,24 @@
+
+
+
+
+
+
-
+
-
+
{{ row.name }}
#{{ row.id }}
- {{ t('ticket.list.nickname') }}
+
+ {{ t('ticket.list.nickname') }}
+
{{ row.nickname }}
- {{ t('ticket.list.state') }}
+
+ {{ t('ticket.list.state') }}
+
-
- {{ row.ticketState.state.name }}
-
+
+ {{ row.state }}
+
- {{ t('ticket.list.shipped') }}
- {{ toDate(row.shipped) }}
+
+ {{ t('ticket.list.shipped') }}
+
+
+ {{ toDate(row.shipped) }}
+
- {{ t('ticket.list.landed') }}
- {{ toDate(row.landed) }}
+
+ {{ t('Zone') }}
+
+
+ {{ row.zoneName }}
+
-
- {{ t('ticket.list.salesPerson') }}
- {{ row.client.salesPersonUser.name }}
+
+
+ {{ t('ticket.list.salesPerson') }}
+
+
+ {{ row.salesPerson }}
+
- {{ t('ticket.list.total') }}
- {{ toCurrency(row.totalWithVat) }}
+
+ {{ t('ticket.list.total') }}
+
+
+ {{ toCurrency(row.totalWithVat) }}
+
-
- {{ t('components.smartCard.openCard') }}
+
+
+ {{ t('components.smartCard.openCard') }}
+
-
- {{ t('components.smartCard.openSummary') }}
+
+
+ {{ t('components.smartCard.openSummary') }}
+
@@ -120,3 +191,10 @@ function viewSummary(id) {
+
+
+es:
+ Search ticket: Buscar ticket
+ You can search by ticket id or alias: Puedes buscar por id o alias del ticket
+ Zone: Zona
+
diff --git a/src/pages/Ticket/TicketMain.vue b/src/pages/Ticket/TicketMain.vue
index fd50f15216..e4350a6e79 100644
--- a/src/pages/Ticket/TicketMain.vue
+++ b/src/pages/Ticket/TicketMain.vue
@@ -1,12 +1,12 @@
-
+
diff --git a/src/router/modules/claim.js b/src/router/modules/claim.js
index 1c1cfb50ef..597d3e61bb 100644
--- a/src/router/modules/claim.js
+++ b/src/router/modules/claim.js
@@ -11,7 +11,7 @@ export default {
redirect: { name: 'ClaimMain' },
menus: {
main: ['ClaimList', 'ClaimRmaList'],
- card: ['ClaimBasicData', 'ClaimRma'],
+ card: ['ClaimBasicData', 'ClaimRma', 'ClaimPhotos'],
},
children: [
{
@@ -76,6 +76,15 @@ export default {
},
component: () => import('src/pages/Claim/Card/ClaimRma.vue'),
},
+ {
+ name: 'ClaimPhotos',
+ path: 'photos',
+ meta: {
+ title: 'photos',
+ icon: 'image',
+ },
+ component: () => import('src/pages/Claim/Card/ClaimPhoto.vue'),
+ },
],
},
],
diff --git a/src/router/modules/customer.js b/src/router/modules/customer.js
index 1c2d421b64..7b48413f2f 100644
--- a/src/router/modules/customer.js
+++ b/src/router/modules/customer.js
@@ -27,7 +27,7 @@ export default {
title: 'list',
icon: 'view_list',
},
- component: () => import('src/pages/Customer/CustomerList.vue'),
+ component: () => import('src/pages/Customer/CustomerList.vue')
},
{
path: 'create',
diff --git a/src/stores/useArrayDataStore.js b/src/stores/useArrayDataStore.js
new file mode 100644
index 0000000000..9d904d7579
--- /dev/null
+++ b/src/stores/useArrayDataStore.js
@@ -0,0 +1,33 @@
+import { ref } from 'vue';
+import { defineStore } from 'pinia';
+
+export const useArrayDataStore = defineStore('arrayDataStore', () => {
+ const state = ref({});
+
+ function get(key) {
+ return state.value[key];
+ }
+
+ function set(key) {
+ state.value[key] = {
+ filter: {},
+ userFilter: {},
+ userParams: {},
+ url: '',
+ limit: 10,
+ skip: 0,
+ order: '',
+ data: ref(),
+ };
+ }
+
+ function clear(key) {
+ delete state.value[key];
+ }
+
+ return {
+ get,
+ set,
+ clear,
+ };
+});
diff --git a/src/stores/useStateStore.js b/src/stores/useStateStore.js
new file mode 100644
index 0000000000..8704c46e48
--- /dev/null
+++ b/src/stores/useStateStore.js
@@ -0,0 +1,43 @@
+import { ref } from 'vue';
+import { defineStore } from 'pinia';
+
+export const useStateStore = defineStore('stateStore', () => {
+ const isMounted = ref(false);
+ const leftDrawer = ref(false);
+ const rightDrawer = ref(false);
+
+ function toggleLeftDrawer() {
+ leftDrawer.value = !leftDrawer.value;
+ }
+
+ function toggleRightDrawer() {
+ rightDrawer.value = !rightDrawer.value;
+ }
+
+ function setMounted() {
+ isMounted.value = true;
+ }
+
+ function isHeaderMounted() {
+ return isMounted.value;
+ }
+
+ function isLeftDrawerShown() {
+ return leftDrawer.value;
+ }
+
+ function isRightDrawerShown() {
+ return rightDrawer.value;
+ }
+
+ return {
+ leftDrawer,
+ rightDrawer,
+ setMounted,
+ isHeaderMounted,
+ toggleLeftDrawer,
+ toggleRightDrawer,
+ isLeftDrawerShown,
+ isRightDrawerShown,
+ };
+});
diff --git a/test/cypress/fixtures/image.jpg b/test/cypress/fixtures/image.jpg
new file mode 100644
index 0000000000..83052dea69
Binary files /dev/null and b/test/cypress/fixtures/image.jpg differ
diff --git a/test/cypress/integration/claimPhoto.spec.js b/test/cypress/integration/claimPhoto.spec.js
new file mode 100755
index 0000000000..e5ea2ce258
--- /dev/null
+++ b/test/cypress/integration/claimPhoto.spec.js
@@ -0,0 +1,55 @@
+///
+describe('ClaimPhoto', () => {
+ beforeEach(() => {
+ const claimId = 1;
+ cy.login('developer');
+ cy.visit(`/#/claim/${claimId}/photos`);
+ });
+
+ it('should add new file', () => {
+ cy.get('label > .q-btn').click();
+ cy.get('label > .q-btn input').selectFile('test/cypress/fixtures/image.jpg', {
+ force: true,
+ });
+ cy.get('.q-notification__message').should('have.text', 'Data saved');
+ });
+
+ it('should add new file with drag and drop', () => {
+ cy.get('.container').selectFile('test/cypress/fixtures/image.jpg', {
+ action: 'drag-drop',
+ });
+ cy.get('.q-notification__message').should('have.text', 'Data saved');
+ });
+
+ it('should open first image dialog change to second and close', () => {
+ cy.get(
+ ':nth-child(1) > .q-card > .q-img > .q-img__container > .q-img__image'
+ ).click();
+ cy.get('.q-carousel__slide > .q-img > .q-img__container > .q-img__image').should(
+ 'be.visible'
+ );
+
+ cy.get('.q-carousel__control > .q-btn > .q-btn__content > .q-icon').click();
+
+ cy.get(
+ '.q-dialog__inner > .q-toolbar > .q-btn > .q-btn__content > .q-icon'
+ ).click();
+ cy.get('.q-carousel__slide > .q-img > .q-img__container > .q-img__image').should(
+ 'not.be.visible'
+ );
+ });
+
+ it('should remove third and fourth file', () => {
+ cy.get(
+ '.multimediaParent > :nth-child(3) > .q-btn > .q-btn__content > .q-icon'
+ ).click();
+ cy.get('.q-btn--standard > .q-btn__content > .block').click();
+ cy.get('.q-notification__message').should('have.text', 'Data deleted');
+
+ cy.get(
+ '.multimediaParent > :nth-child(3) > .q-btn > .q-btn__content > .q-icon'
+ ).click();
+ cy.get('.q-btn--standard > .q-btn__content > .block').click();
+ cy.get('.q-notification__message').should('have.text', 'Data deleted');
+ });
+});
diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js
index 4ab3ae23f2..a3a61c4232 100755
--- a/test/cypress/support/commands.js
+++ b/test/cypress/support/commands.js
@@ -28,7 +28,7 @@
// Imports Quasar Cypress AE predefined commands
// import { registerCommands } from '@quasar/quasar-app-extension-testing-e2e-cypress';
Cypress.Commands.add('login', (user) => {
- cy.visit('/#/login');
+ //cy.visit('/#/login');
cy.request({
method: 'POST',
url: '/api/accounts/login',
diff --git a/test/vitest/__tests__/components/Paginate.spec.js b/test/vitest/__tests__/components/Paginate.spec.js
index dd6f31478b..5a6b087128 100644
--- a/test/vitest/__tests__/components/Paginate.spec.js
+++ b/test/vitest/__tests__/components/Paginate.spec.js
@@ -4,82 +4,66 @@ import Paginate from 'components/PaginateData.vue';
describe('Paginate', () => {
const expectedUrl = '/api/customers';
+
let vm;
beforeAll(() => {
const options = {
attrs: {
url: expectedUrl,
- sortBy: 'id DESC',
- rowsPerPage: 3,
+ dataKey: 'CustomerList',
+ order: 'id DESC',
+ limit: 3,
},
};
vm = createWrapper(Paginate, options).vm;
-
- vi.spyOn(axios, 'get').mockResolvedValue({
- data: [
- { id: 1, name: 'Tony Stark' },
- { id: 2, name: 'Jessica Jones' },
- { id: 3, name: 'Bruce Wayne' },
- ],
- });
});
afterEach(() => {
- vm.rows = [];
+ vm.store.data = [];
+ vm.store.skip = 0;
vm.pagination.page = 1;
vm.hasMoreData = true;
});
describe('paginate()', () => {
it('should call to the paginate() method and set the data on the rows property', async () => {
- const expectedOptions = {
- params: {
- filter: {
- order: 'id DESC',
- limit: 3,
- skip: 0,
- },
- },
- };
+ vi.spyOn(vm.arrayData, 'loadMore');
+ vm.store.data = [
+ { id: 1, name: 'Tony Stark' },
+ { id: 2, name: 'Jessica Jones' },
+ { id: 3, name: 'Bruce Wayne' },
+ ];
await vm.paginate();
- expect(axios.get).toHaveBeenCalledWith(expectedUrl, expectedOptions);
- expect(vm.rows.length).toEqual(3);
+ expect(vm.arrayData.loadMore).toHaveBeenCalledWith();
+ expect(vm.store.data.length).toEqual(3);
});
it('should call to the paginate() method and then call it again to paginate', async () => {
- const expectedOptions = {
- params: {
- filter: {
- order: 'id DESC',
- limit: 3,
- skip: 0,
- },
- },
- };
+ vi.spyOn(axios, 'get').mockResolvedValue({
+ data: [
+ { id: 1, name: 'Tony Stark' },
+ { id: 2, name: 'Jessica Jones' },
+ { id: 3, name: 'Bruce Wayne' },
+ ],
+ });
+ vm.arrayData.hasMoreData.value = true;
+ vm.store.data = [
+ { id: 1, name: 'Tony Stark' },
+ { id: 2, name: 'Jessica Jones' },
+ { id: 3, name: 'Bruce Wayne' },
+ ];
await vm.paginate();
- expect(axios.get).toHaveBeenCalledWith(expectedUrl, expectedOptions);
- expect(vm.rows.length).toEqual(3);
-
- const expectedOptionsPaginated = {
- params: {
- filter: {
- order: 'id DESC',
- limit: 3,
- skip: 3,
- },
- },
- };
-
- vm.pagination.page = 2;
+ expect(vm.store.skip).toEqual(3);
+ expect(vm.store.data.length).toEqual(6);
await vm.paginate();
- expect(axios.get).toHaveBeenCalledWith(expectedUrl, expectedOptionsPaginated);
- expect(vm.rows.length).toEqual(6);
+ expect(vm.store.skip).toEqual(6);
+ expect(vm.store.data.length).toEqual(9);
});
});
@@ -95,16 +79,15 @@ describe('Paginate', () => {
});
it('should increment the pagination and then call to the done() callback', async () => {
- vm.rows = [
- { id: 1, name: 'Tony Stark' },
- { id: 2, name: 'Jessica Jones' },
- { id: 3, name: 'Bruce Wayne' },
- ];
-
expect(vm.pagination.page).toEqual(1);
const index = 1;
const done = vi.fn();
+ vm.store.data = [
+ { id: 1, name: 'Tony Stark' },
+ { id: 2, name: 'Jessica Jones' },
+ { id: 3, name: 'Bruce Wayne' },
+ ];
await vm.onLoad(index, done);
@@ -120,7 +103,7 @@ describe('Paginate', () => {
],
});
- vm.rows = [
+ vm.store.data = [
{ id: 1, name: 'Tony Stark' },
{ id: 2, name: 'Jessica Jones' },
{ id: 3, name: 'Bruce Wayne' },
diff --git a/test/vitest/__tests__/pages/Claims/ClaimDescriptorMenu.spec.js b/test/vitest/__tests__/pages/Claims/ClaimDescriptorMenu.spec.js
index 3a2ec46d7d..a1c3a38edd 100644
--- a/test/vitest/__tests__/pages/Claims/ClaimDescriptorMenu.spec.js
+++ b/test/vitest/__tests__/pages/Claims/ClaimDescriptorMenu.spec.js
@@ -25,7 +25,9 @@ describe('ClaimDescriptorMenu', () => {
await vm.deleteClaim();
- expect(vm.quasar.notify).toHaveBeenCalledWith(expect.objectContaining({ type: 'positive' }));
+ expect(vm.quasar.notify).toHaveBeenCalledWith(
+ expect.objectContaining({ type: 'positive' })
+ );
});
});
});
diff --git a/test/vitest/__tests__/pages/Claims/ClaimPhoto.spec.js b/test/vitest/__tests__/pages/Claims/ClaimPhoto.spec.js
new file mode 100644
index 0000000000..21c7865eb6
--- /dev/null
+++ b/test/vitest/__tests__/pages/Claims/ClaimPhoto.spec.js
@@ -0,0 +1,113 @@
+import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest';
+import { createWrapper, axios } from 'app/test/vitest/helper';
+import ClaimPhoto from 'pages/Claim/Card/ClaimPhoto.vue';
+
+describe('ClaimPhoto', () => {
+ let vm;
+
+ const claimMock = {
+ claimDms: [
+ {
+ dmsFk: 1,
+ dms: {
+ contentType: 'contentType',
+ },
+ },
+ ],
+ client: {
+ id: '1',
+ },
+ };
+ beforeAll(() => {
+ vm = createWrapper(ClaimPhoto, {
+ global: {
+ stubs: ['FetchData', 'TeleportSlot', 'vue-i18n'],
+ mocks: {
+ fetch: vi.fn(),
+ },
+ },
+ }).vm;
+ });
+
+ afterEach(() => {
+ vi.clearAllMocks();
+ });
+
+ describe('deleteDms()', () => {
+ it('should delete dms and call quasar notify', async () => {
+ vi.spyOn(axios, 'post').mockResolvedValue({ data: true });
+ vi.spyOn(vm.quasar, 'notify');
+
+ await vm.deleteDms(0);
+
+ expect(axios.post).toHaveBeenCalledWith(
+ `ClaimDms/${claimMock.claimDms[0].dmsFk}/removeFile`
+ );
+ expect(vm.quasar.notify).toHaveBeenCalledWith(
+ expect.objectContaining({ type: 'positive' })
+ );
+ expect(vm.claimDms).toEqual([]);
+ });
+ });
+
+ describe('viewDeleteDms()', () => {
+ it('should call quasar dialog', async () => {
+ vi.spyOn(vm.quasar, 'dialog');
+
+ await vm.viewDeleteDms(1);
+
+ expect(vm.quasar.dialog).toHaveBeenCalledWith(
+ expect.objectContaining({
+ componentProps: {
+ message: 'This file will be deleted',
+ icon: 'delete',
+ },
+ })
+ );
+ });
+ });
+
+ describe('setClaimDms()', () => {
+ it('should assign claimDms and client from data', async () => {
+ await vm.setClaimDms(claimMock);
+
+ expect(vm.claimDms).toEqual([
+ {
+ dmsFk: 1,
+ dms: {
+ contentType: 'contentType',
+ },
+ isVideo: false,
+ url: '/api/Claims/1/downloadFile?access_token=',
+ },
+ ]);
+
+ expect(vm.client).toEqual(claimMock.client);
+ });
+ });
+
+ describe('create()', () => {
+ it('should upload file and call quasar notify', async () => {
+ const files = [{ name: 'firstFile' }];
+
+ vi.spyOn(axios, 'post').mockResolvedValue({ data: true });
+ vi.spyOn(vm.quasar, 'notify');
+ vi.spyOn(vm.claimDmsRef, 'fetch');
+
+ await vm.create(files);
+
+ expect(axios.post).toHaveBeenCalledWith(
+ 'claims/1/uploadFile',
+ new FormData(),
+ expect.objectContaining({
+ params: expect.objectContaining({ hasFile: false }),
+ })
+ );
+ expect(vm.quasar.notify).toHaveBeenCalledWith(
+ expect.objectContaining({ type: 'positive' })
+ );
+
+ expect(vm.claimDmsRef.fetch).toHaveBeenCalledOnce();
+ });
+ });
+});
diff --git a/test/vitest/helper.js b/test/vitest/helper.js
index 13987080d0..8a6fb14159 100644
--- a/test/vitest/helper.js
+++ b/test/vitest/helper.js
@@ -1,4 +1,4 @@
-import { installQuasar } from '@quasar/quasar-app-extension-testing-unit-vitest';
+import { installQuasarPlugin } from '@quasar/quasar-app-extension-testing-unit-vitest';
import { mount, flushPromises } from '@vue/test-utils';
import { createTestingPinia } from '@pinia/testing';
import { vi } from 'vitest';
@@ -6,27 +6,60 @@ import { i18n } from 'src/boot/i18n';
import { Notify, Dialog } from 'quasar';
import axios from 'axios';
-installQuasar({
+installQuasarPlugin({
plugins: {
Notify,
Dialog,
},
});
+const pinia = createTestingPinia({ createSpy: vi.fn, stubActions: false });
const mockPush = vi.fn();
+
vi.mock('vue-router', () => ({
useRouter: () => ({
push: mockPush,
- currentRoute: { value: 'myCurrentRoute' },
+ currentRoute: {
+ value: {
+ params: {
+ id: 1,
+ },
+ },
+ },
}),
useRoute: () => ({
matched: [],
+ query: {},
+ params: {},
}),
}));
-export function createWrapper(component, options) {
- const pinia = createTestingPinia({ createSpy: vi.fn, stubActions: false });
+class FormDataMock {
+ append() {
+ vi.fn();
+ }
+ delete() {
+ vi.fn();
+ }
+ get() {
+ vi.fn();
+ }
+ getAll() {
+ vi.fn();
+ }
+ has() {
+ vi.fn();
+ }
+ set() {
+ vi.fn();
+ }
+ forEach() {
+ vi.fn();
+ }
+}
+global.FormData = FormDataMock;
+export function createWrapper(component, options) {
const defaultOptions = {
global: {
plugins: [i18n, pinia],