4799 - Print composable
gitea/salix-front/pipeline/head There was a failure building this commit Details

This commit is contained in:
Joan Sanchez 2022-11-17 08:04:12 +01:00
parent 68cc6c9ca7
commit 066fe1df06
32 changed files with 432 additions and 86 deletions

View File

@ -5,6 +5,7 @@
"src/*": ["src/*"], "src/*": ["src/*"],
"app/*": ["*"], "app/*": ["*"],
"components/*": ["src/components/*"], "components/*": ["src/components/*"],
"composables/*": ["src/composables/*"],
"layouts/*": ["src/layouts/*"], "layouts/*": ["src/layouts/*"],
"pages/*": ["src/pages/*"], "pages/*": ["src/pages/*"],
"assets/*": ["src/assets/*"], "assets/*": ["src/assets/*"],

View File

@ -9,8 +9,8 @@
// https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js // https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js
const ESLintPlugin = require('eslint-webpack-plugin'); const ESLintPlugin = require('eslint-webpack-plugin');
const { configure } = require('quasar/wrappers'); const { configure } = require('quasar/wrappers');
const path = require('path');
module.exports = configure(function (ctx) { module.exports = configure(function (ctx) {
return { return {
@ -68,15 +68,23 @@ module.exports = configure(function (ctx) {
chainWebpack(chain) { chainWebpack(chain) {
chain.module chain.module
.rule("i18n") .rule('i18n')
.resourceQuery(/blockType=i18n/) .resourceQuery(/blockType=i18n/)
.type('javascript/auto') .type('javascript/auto')
.use("i18n") .use('i18n')
.loader("@intlify/vue-i18n-loader") .loader('@intlify/vue-i18n-loader')
.end(); .end();
chain.plugin('eslint-webpack-plugin') chain.plugin('eslint-webpack-plugin').use(ESLintPlugin, [{ extensions: ['js', 'vue'] }]);
.use(ESLintPlugin, [{ extensions: ['js', 'vue'] }]); },
extendWebpack(cfg) {
cfg.resolve.alias = {
...cfg.resolve.alias, // This adds the existing alias
// Add your own alias like this
composables: path.resolve(__dirname, './src/composables'),
filters: path.resolve(__dirname, './src/filters'),
};
}, },
}, },
@ -91,7 +99,7 @@ module.exports = configure(function (ctx) {
target: 'http://0.0.0.0:3000', target: 'http://0.0.0.0:3000',
logLevel: 'debug', logLevel: 'debug',
changeOrigin: true, changeOrigin: true,
secure: false secure: false,
}, },
}, },
}, },
@ -100,9 +108,9 @@ module.exports = configure(function (ctx) {
framework: { framework: {
config: { config: {
brand: { brand: {
primary: 'orange' primary: 'orange',
}, },
dark: 'auto' dark: 'auto',
}, },
lang: 'es', lang: 'es',

View File

@ -6,7 +6,7 @@ import axios from 'axios';
import { useState } from 'src/composables/useState'; import { useState } from 'src/composables/useState';
import { useValidator } from 'src/composables/useValidator'; import { useValidator } from 'src/composables/useValidator';
import SkeletonForm from 'src/components/SkeletonForm.vue'; import SkeletonForm from 'components/ui/SkeletonForm.vue';
const quasar = useQuasar(); const quasar = useQuasar();
const { t } = useI18n(); const { t } = useI18n();

View File

@ -2,7 +2,7 @@
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useState } from 'src/composables/useState'; import { useState } from 'src/composables/useState';
import { useSession } from 'src/composables/useSession'; import { useSession } from 'src/composables/useSession';
import UserPanel from 'src/components/UserPanel.vue'; import UserPanel from 'components/UserPanel.vue';
import FavoriteModules from './FavoriteModules.vue'; import FavoriteModules from './FavoriteModules.vue';
const { t } = useI18n(); const { t } = useI18n();

View File

@ -0,0 +1,72 @@
<script setup>
import { ref } from 'vue';
import { useDialogPluginComponent } from 'quasar';
import { useI18n } from 'vue-i18n';
const $props = defineProps({
address: {
type: String,
default: '',
},
send: {
type: Function,
required: true,
},
});
defineEmits(['confirm', ...useDialogPluginComponent.emits]);
const { dialogRef, onDialogOK } = useDialogPluginComponent();
const { t } = useI18n();
const address = ref($props.address);
const isLoading = ref(false);
async function confirm() {
isLoading.value = true;
await $props.send(address.value);
isLoading.value = false;
onDialogOK();
}
</script>
<template>
<q-dialog ref="dialogRef" persistent>
<q-card class="q-pa-sm">
<q-card-section class="row items-center q-pb-none">
<span class="text-h6 text-grey">{{ t('sendEmailNotification') }}</span>
<q-space />
<q-btn icon="close" flat round dense v-close-popup />
</q-card-section>
<q-card-section class="row items-center">
{{ t('notifyAddress') }}
</q-card-section>
<q-card-section class="q-pt-none">
<q-input dense v-model="address" rounded outlined autofocus />
</q-card-section>
<q-card-actions align="right">
<q-btn :label="t('globals.cancel')" color="primary" flat v-close-popup />
<q-btn :label="t('globals.confirm')" color="primary" :loading="isLoading" @click="confirm" />
</q-card-actions>
</q-card>
</q-dialog>
</template>
<style lang="scss" scoped>
.q-card {
min-width: 350px;
}
</style>
<i18n>
{
"en": {
"sendEmailNotification": "Send email notification",
"notifyAddress": "The notification will be sent to the following address"
},
"es": {
"sendEmailNotification": "Enviar notificación por correo",
"notifyAddress": "La notificación se enviará a la siguiente dirección"
}
}
</i18n>

View File

@ -98,9 +98,5 @@ const { t } = useI18n();
justify-content: space-between; justify-content: space-between;
align-items: stretch; align-items: stretch;
} }
#descriptor-skeleton .q-card__actions {
justify-content: space-between;
}
} }
</style> </style>

View File

@ -0,0 +1,24 @@
<template>
<div id="descriptor-skeleton">
<div class="col q-pl-sm q-pa-sm">
<q-skeleton type="text" square height="45px" />
<q-skeleton type="text" square height="18px" />
<q-skeleton type="text" square height="18px" />
<q-skeleton type="text" square height="18px" />
</div>
<q-card-actions>
<q-skeleton size="40px" />
<q-skeleton size="40px" />
<q-skeleton size="40px" />
<q-skeleton size="40px" />
<q-skeleton size="40px" />
</q-card-actions>
</div>
</template>
<style lang="scss" scoped>
#descriptor-skeleton .q-card__actions {
justify-content: space-between;
}
</style>

View File

@ -0,0 +1,36 @@
import { useSession } from './useSession';
import axios from 'axios';
import { useQuasar } from 'quasar';
export function usePrintService() {
const quasar = useQuasar();
const { getToken } = useSession();
function sendEmail(path, params) {
return axios.post(path, params).then(() =>
quasar.notify({
message: 'Notification sent',
type: 'positive',
icon: 'check',
})
);
}
function openReport(path, params) {
params = Object.assign(
{
access_token: getToken(),
},
params
);
const query = new URLSearchParams(params).toString();
window.open(`api/${path}?${query}`);
}
return {
sendEmail,
openReport,
};
}

View File

@ -13,12 +13,14 @@ export default {
darkMode: 'Dark mode', darkMode: 'Dark mode',
logOut: 'Log out', logOut: 'Log out',
dataSaved: 'Data saved', dataSaved: 'Data saved',
dataDeleted: 'Data deleted',
add: 'Add', add: 'Add',
create: 'Create', create: 'Create',
save: 'Save', save: 'Save',
remove: 'Remove', remove: 'Remove',
reset: 'Reset', reset: 'Reset',
cancel: 'Cancel', cancel: 'Cancel',
confirm: 'Confirm',
yes: 'Yes', yes: 'Yes',
no: 'No', no: 'No',
noChanges: 'No changes to save', noChanges: 'No changes to save',
@ -26,10 +28,10 @@ export default {
confirmRemove: 'You are about to delete this row. Are you sure?', confirmRemove: 'You are about to delete this row. Are you sure?',
rowAdded: 'Row added', rowAdded: 'Row added',
rowRemoved: 'Row removed', rowRemoved: 'Row removed',
pleaseWait: 'Please wait...' pleaseWait: 'Please wait...',
}, },
moduleIndex: { moduleIndex: {
allModules: 'All modules' allModules: 'All modules',
}, },
errors: { errors: {
statusUnauthorized: 'Access denied', statusUnauthorized: 'Access denied',
@ -45,12 +47,12 @@ export default {
keepLogin: 'Keep me logged in', keepLogin: 'Keep me logged in',
loginSuccess: 'You have successfully logged in', loginSuccess: 'You have successfully logged in',
loginError: 'Invalid username or password', loginError: 'Invalid username or password',
fieldRequired: 'This field is required' fieldRequired: 'This field is required',
}, },
dashboard: { dashboard: {
pageTitles: { pageTitles: {
dashboard: 'Dashboard', dashboard: 'Dashboard',
} },
}, },
customer: { customer: {
pageTitles: { pageTitles: {
@ -58,13 +60,13 @@ export default {
list: 'List', list: 'List',
createCustomer: 'Create customer', createCustomer: 'Create customer',
summary: 'Summary', summary: 'Summary',
basicData: 'Basic Data' basicData: 'Basic Data',
}, },
list: { list: {
phone: 'Phone', phone: 'Phone',
email: 'Email', email: 'Email',
customerOrders: 'Display customer orders', customerOrders: 'Display customer orders',
moreOptions: 'More options' moreOptions: 'More options',
}, },
card: { card: {
customerList: 'Customer list', customerList: 'Customer list',
@ -78,7 +80,7 @@ export default {
isFrozen: 'Customer is frozen', isFrozen: 'Customer is frozen',
hasDebt: 'Customer has debt', hasDebt: 'Customer has debt',
notChecked: 'Customer not checked', notChecked: 'Customer not checked',
noWebAccess: 'Web access is disabled' noWebAccess: 'Web access is disabled',
}, },
summary: { summary: {
basicData: 'Basic data', basicData: 'Basic data',
@ -145,8 +147,8 @@ export default {
phone: 'Phone', phone: 'Phone',
mobile: 'Mobile', mobile: 'Mobile',
salesPerson: 'Sales person', salesPerson: 'Sales person',
contactChannel: 'Contact channel' contactChannel: 'Contact channel',
} },
}, },
ticket: { ticket: {
pageTitles: { pageTitles: {
@ -155,7 +157,7 @@ export default {
createTicket: 'Create ticket', createTicket: 'Create ticket',
summary: 'Summary', summary: 'Summary',
basicData: 'Basic Data', basicData: 'Basic Data',
boxing: 'Boxing' boxing: 'Boxing',
}, },
list: { list: {
nickname: 'Nickname', nickname: 'Nickname',
@ -163,7 +165,7 @@ export default {
shipped: 'Shipped', shipped: 'Shipped',
landed: 'Landed', landed: 'Landed',
salesPerson: 'Sales person', salesPerson: 'Sales person',
total: 'Total' total: 'Total',
}, },
card: { card: {
ticketId: 'Ticket ID', ticketId: 'Ticket ID',
@ -173,7 +175,7 @@ export default {
agency: 'Agency', agency: 'Agency',
shipped: 'Shipped', shipped: 'Shipped',
warehouse: 'Warehouse', warehouse: 'Warehouse',
customerCard: 'Customer card' customerCard: 'Customer card',
}, },
boxing: { boxing: {
expedition: 'Expedition', expedition: 'Expedition',
@ -182,8 +184,8 @@ export default {
worker: 'Worker', worker: 'Worker',
selectTime: 'Select time:', selectTime: 'Select time:',
selectVideo: 'Select video:', selectVideo: 'Select video:',
notFound: 'No videos available' notFound: 'No videos available',
} },
}, },
claim: { claim: {
pageTitles: { pageTitles: {
@ -193,21 +195,21 @@ export default {
rmaList: 'RMA', rmaList: 'RMA',
summary: 'Summary', summary: 'Summary',
basicData: 'Basic Data', basicData: 'Basic Data',
rma: 'RMA' rma: 'RMA',
}, },
list: { list: {
customer: 'Customer', customer: 'Customer',
assignedTo: 'Assigned', assignedTo: 'Assigned',
created: 'Created', created: 'Created',
state: 'State' state: 'State',
}, },
rmaList: { rmaList: {
code: 'Code', code: 'Code',
records: 'records' records: 'records',
}, },
rma: { rma: {
user: 'User', user: 'User',
created: 'Created' created: 'Created',
}, },
card: { card: {
claimId: 'Claim ID', claimId: 'Claim ID',
@ -216,7 +218,7 @@ export default {
state: 'State', state: 'State',
ticketId: 'Ticket ID', ticketId: 'Ticket ID',
customerSummary: 'Customer summary', customerSummary: 'Customer summary',
claimedTicket: 'Claimed ticket' claimedTicket: 'Claimed ticket',
}, },
summary: { summary: {
customer: 'Customer', customer: 'Customer',
@ -236,7 +238,7 @@ export default {
actions: 'Actions', actions: 'Actions',
responsibility: 'Responsibility', responsibility: 'Responsibility',
company: 'Company', company: 'Company',
person: 'Employee/Customer' person: 'Employee/Customer',
}, },
basicData: { basicData: {
customer: 'Customer', customer: 'Customer',
@ -245,7 +247,7 @@ export default {
state: 'State', state: 'State',
packages: 'Packages', packages: 'Packages',
picked: 'Picked', picked: 'Picked',
returnOfMaterial: 'Return of material authorization (RMA)' returnOfMaterial: 'Return of material authorization (RMA)',
}, },
}, },
components: { components: {
@ -258,12 +260,12 @@ export default {
noData: 'No data to display', noData: 'No data to display',
openCard: 'View card', openCard: 'View card',
openSummary: 'Open summary', openSummary: 'Open summary',
viewDescription: 'View description' viewDescription: 'View description',
}, },
cardDescriptor: { cardDescriptor: {
mainList: 'Main list', mainList: 'Main list',
summary: 'Summary', summary: 'Summary',
moreOptions: 'More options' moreOptions: 'More options',
} },
}, },
}; };

View File

@ -13,12 +13,14 @@ export default {
darkMode: 'Modo oscuro', darkMode: 'Modo oscuro',
logOut: 'Cerrar sesión', logOut: 'Cerrar sesión',
dataSaved: 'Datos guardados', dataSaved: 'Datos guardados',
dataDeleted: 'Data deleted',
add: 'Añadir', add: 'Añadir',
create: 'Crear', create: 'Crear',
save: 'Guardar', save: 'Guardar',
remove: 'Eliminar', remove: 'Eliminar',
reset: 'Restaurar', reset: 'Restaurar',
cancel: 'Cancelar', cancel: 'Cancelar',
confirm: 'Confirmar',
yes: 'Si', yes: 'Si',
no: 'No', no: 'No',
noChanges: 'Sin cambios que guardar', noChanges: 'Sin cambios que guardar',
@ -26,10 +28,10 @@ export default {
confirmRemove: 'Vas a eliminar este registro. ¿Continuar?', confirmRemove: 'Vas a eliminar este registro. ¿Continuar?',
rowAdded: 'Fila añadida', rowAdded: 'Fila añadida',
rowRemoved: 'Fila eliminada', rowRemoved: 'Fila eliminada',
pleaseWait: 'Por favor, espera...' pleaseWait: 'Por favor, espera...',
}, },
moduleIndex: { moduleIndex: {
allModules: 'Todos los módulos' allModules: 'Todos los módulos',
}, },
errors: { errors: {
statusUnauthorized: 'Acceso denegado', statusUnauthorized: 'Acceso denegado',
@ -45,12 +47,12 @@ export default {
keepLogin: 'Mantener sesión iniciada', keepLogin: 'Mantener sesión iniciada',
loginSuccess: 'Inicio de sesión correcto', loginSuccess: 'Inicio de sesión correcto',
loginError: 'Nombre de usuario o contraseña incorrectos', loginError: 'Nombre de usuario o contraseña incorrectos',
fieldRequired: 'Este campo es obligatorio' fieldRequired: 'Este campo es obligatorio',
}, },
dashboard: { dashboard: {
pageTitles: { pageTitles: {
dashboard: 'Tablón', dashboard: 'Tablón',
} },
}, },
customer: { customer: {
pageTitles: { pageTitles: {
@ -58,13 +60,13 @@ export default {
list: 'Listado', list: 'Listado',
createCustomer: 'Crear cliente', createCustomer: 'Crear cliente',
summary: 'Resumen', summary: 'Resumen',
basicData: 'Datos básicos' basicData: 'Datos básicos',
}, },
list: { list: {
phone: 'Teléfono', phone: 'Teléfono',
email: 'Email', email: 'Email',
customerOrders: 'Mostrar órdenes del cliente', customerOrders: 'Mostrar órdenes del cliente',
moreOptions: 'Más opciones' moreOptions: 'Más opciones',
}, },
card: { card: {
customerId: 'ID cliente', customerId: 'ID cliente',
@ -77,7 +79,7 @@ export default {
isFrozen: 'El cliente está congelado', isFrozen: 'El cliente está congelado',
hasDebt: 'El cliente tiene riesgo', hasDebt: 'El cliente tiene riesgo',
notChecked: 'El cliente no está comprobado', notChecked: 'El cliente no está comprobado',
noWebAccess: 'El acceso web está desactivado' noWebAccess: 'El acceso web está desactivado',
}, },
summary: { summary: {
basicData: 'Datos básicos', basicData: 'Datos básicos',
@ -144,8 +146,8 @@ export default {
phone: 'Teléfono', phone: 'Teléfono',
mobile: 'Móvil', mobile: 'Móvil',
salesPerson: 'Comercial', salesPerson: 'Comercial',
contactChannel: 'Canal de contacto' contactChannel: 'Canal de contacto',
} },
}, },
ticket: { ticket: {
pageTitles: { pageTitles: {
@ -154,7 +156,7 @@ export default {
createTicket: 'Crear ticket', createTicket: 'Crear ticket',
summary: 'Resumen', summary: 'Resumen',
basicData: 'Datos básicos', basicData: 'Datos básicos',
boxing: 'Encajado' boxing: 'Encajado',
}, },
list: { list: {
nickname: 'Alias', nickname: 'Alias',
@ -162,7 +164,7 @@ export default {
shipped: 'Enviado', shipped: 'Enviado',
landed: 'Entregado', landed: 'Entregado',
salesPerson: 'Comercial', salesPerson: 'Comercial',
total: 'Total' total: 'Total',
}, },
card: { card: {
ticketId: 'ID ticket', ticketId: 'ID ticket',
@ -172,7 +174,7 @@ export default {
agency: 'Agencia', agency: 'Agencia',
shipped: 'Enviado', shipped: 'Enviado',
warehouse: 'Almacén', warehouse: 'Almacén',
customerCard: 'Ficha del cliente' customerCard: 'Ficha del cliente',
}, },
boxing: { boxing: {
expedition: 'Expedición', expedition: 'Expedición',
@ -181,8 +183,8 @@ export default {
worker: 'Trabajador', worker: 'Trabajador',
selectTime: 'Seleccionar hora:', selectTime: 'Seleccionar hora:',
selectVideo: 'Seleccionar vídeo:', selectVideo: 'Seleccionar vídeo:',
notFound: 'No hay vídeos disponibles' notFound: 'No hay vídeos disponibles',
} },
}, },
claim: { claim: {
pageTitles: { pageTitles: {
@ -192,21 +194,21 @@ export default {
rmaList: 'RMA', rmaList: 'RMA',
summary: 'Resumen', summary: 'Resumen',
basicData: 'Datos básicos', basicData: 'Datos básicos',
rma: 'RMA' rma: 'RMA',
}, },
list: { list: {
customer: 'Cliente', customer: 'Cliente',
assignedTo: 'Asignada a', assignedTo: 'Asignada a',
created: 'Creada', created: 'Creada',
state: 'Estado' state: 'Estado',
}, },
rmaList: { rmaList: {
code: 'Código', code: 'Código',
records: 'registros' records: 'registros',
}, },
rma: { rma: {
user: 'Usuario', user: 'Usuario',
created: 'Creado' created: 'Creado',
}, },
card: { card: {
claimId: 'ID reclamación', claimId: 'ID reclamación',
@ -215,7 +217,7 @@ export default {
state: 'Estado', state: 'Estado',
ticketId: 'ID ticket', ticketId: 'ID ticket',
customerSummary: 'Resumen del cliente', customerSummary: 'Resumen del cliente',
claimedTicket: 'Ticket reclamado' claimedTicket: 'Ticket reclamado',
}, },
summary: { summary: {
customer: 'Cliente', customer: 'Cliente',
@ -235,7 +237,7 @@ export default {
actions: 'Acciones', actions: 'Acciones',
responsibility: 'Responsabilidad', responsibility: 'Responsabilidad',
company: 'Empresa', company: 'Empresa',
person: 'Comercial/Cliente' person: 'Comercial/Cliente',
}, },
basicData: { basicData: {
customer: 'Cliente', customer: 'Cliente',
@ -244,8 +246,8 @@ export default {
state: 'Estado', state: 'Estado',
packages: 'Bultos', packages: 'Bultos',
picked: 'Recogida', picked: 'Recogida',
returnOfMaterial: 'Autorización de retorno de materiales (RMA)' returnOfMaterial: 'Autorización de retorno de materiales (RMA)',
} },
}, },
components: { components: {
topbar: {}, topbar: {},
@ -257,12 +259,12 @@ export default {
noData: 'Sin datos que mostrar', noData: 'Sin datos que mostrar',
openCard: 'Ver ficha', openCard: 'Ver ficha',
openSummary: 'Abrir detalles', openSummary: 'Abrir detalles',
viewDescription: 'Ver descripción' viewDescription: 'Ver descripción',
}, },
cardDescriptor: { cardDescriptor: {
mainList: 'Listado principal', mainList: 'Listado principal',
summary: 'Resumen', summary: 'Resumen',
moreOptions: 'Más opciones', moreOptions: 'Más opciones',
} },
}, },
}; };

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import Navbar from 'src/components/Navbar.vue'; import Navbar from 'components/Navbar.vue';
</script> </script>
<template> <template>

View File

@ -4,8 +4,8 @@ import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useSession } from 'src/composables/useSession'; import { useSession } from 'src/composables/useSession';
import FetchData from 'src/components/FetchData.vue'; import FetchData from 'components/FetchData.vue';
import FormModel from 'src/components/FormModel.vue'; import FormModel from 'components/FormModel.vue';
const route = useRoute(); const route = useRoute();
const { t } = useI18n(); const { t } = useI18n();

View File

@ -1,6 +1,6 @@
<script setup> <script setup>
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useState } from 'src/composables/useState'; import { useState } from 'composables/useState';
import ClaimDescriptor from './ClaimDescriptor.vue'; import ClaimDescriptor from './ClaimDescriptor.vue';
const { t } = useI18n(); const { t } = useI18n();

View File

@ -4,8 +4,10 @@ import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { toDate } from 'src/filters'; import { toDate } from 'src/filters';
import axios from 'axios'; import axios from 'axios';
import CardDescriptor from 'src/components/ui/CardDescriptor.vue'; import TicketDescriptorPopover from 'pages/Ticket/Card/TicketDescriptorPopover.vue';
import TicketDescriptorPopover from 'src/pages/Ticket/Card/TicketDescriptorPopover.vue'; import ClaimDescriptorMenu from 'pages/Claim/Card/ClaimDescriptorMenu.vue';
import CardDescriptor from 'components/ui/CardDescriptor.vue';
import SkeletonDescriptor from 'components/ui/SkeletonDescriptor.vue';
const $props = defineProps({ const $props = defineProps({
id: { id: {
@ -57,7 +59,11 @@ function stateColor(code) {
</script> </script>
<template> <template>
<skeleton-descriptor v-if="!claim" />
<card-descriptor v-if="claim" module="Claim" :data="claim" :description="claim.client.name"> <card-descriptor v-if="claim" module="Claim" :data="claim" :description="claim.client.name">
<template #menu>
<claim-descriptor-menu v-if="claim" :claim="claim" />
</template>
<template #body> <template #body>
<q-list> <q-list>
<q-item> <q-item>

View File

@ -0,0 +1,132 @@
<script setup>
import axios from 'axios';
import { ref } from 'vue';
import { useQuasar } from 'quasar';
import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router';
import { usePrintService } from 'composables/usePrintService';
import SendEmailDialog from 'components/common/SendEmailDialog.vue';
const $props = defineProps({
claim: {
type: Object,
required: true,
},
});
const router = useRouter();
const quasar = useQuasar();
const { t } = useI18n();
const { openReport, sendEmail } = usePrintService();
const claim = ref($props.claim);
function openPickupOrder() {
const id = claim.value.id;
openReport(`Claims/${id}/claim-pickup-pdf`, {
recipientId: claim.value.clientFk,
});
}
function confirmPickupOrder() {
const customer = claim.value.client;
quasar.dialog({
component: SendEmailDialog,
componentProps: {
address: customer.email,
send: sendPickupOrder,
},
});
}
function sendPickupOrder(address) {
const id = claim.value.id;
const customer = claim.value.client;
return sendEmail(`Claims/${id}/claim-pickup-email`, {
recipientId: customer.id,
recipient: address,
});
}
const showConfirmDialog = ref(false);
async function deleteClaim() {
const id = claim.value.id;
await axios.delete(`Claims/${id}`);
quasar.notify({
message: t('globals.dataDeleted'),
type: 'positive',
icon: 'check',
});
await router.push({ name: 'ClaimList' });
}
</script>
<template>
<q-item v-ripple clickable>
<q-item-section avatar>
<q-icon name="summarize" />
</q-item-section>
<q-item-section>{{ t('pickupOrder') }}</q-item-section>
<q-item-section side>
<q-icon name="keyboard_arrow_right" />
</q-item-section>
<q-menu anchor="top end" self="top start" auto-close>
<q-list>
<q-item @click="openPickupOrder" v-ripple clickable>
<q-item-section avatar>
<q-icon name="picture_as_pdf" />
</q-item-section>
<q-item-section>{{ t('openPickupOrder') }}</q-item-section>
</q-item>
<q-item @click="confirmPickupOrder" v-ripple clickable>
<q-item-section avatar>
<q-icon name="send" />
</q-item-section>
<q-item-section>{{ t('sendPickupOrder') }}</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-item>
<q-separator />
<q-item @click="showConfirmDialog = true" v-ripple clickable>
<q-item-section avatar>
<q-icon name="delete" />
</q-item-section>
<q-item-section>{{ t('deleteClaim') }}</q-item-section>
</q-item>
<q-dialog v-model="showConfirmDialog">
<q-card class="q-pa-sm">
<q-card-section class="row items-center q-pb-none">
<span class="text-h6 text-grey">{{ t('confirmDeletion') }}</span>
<q-space />
<q-btn icon="close" flat round dense v-close-popup />
</q-card-section>
<q-card-section class="row items-center">{{ t('confirmDeletionMessage') }}</q-card-section>
<q-card-actions align="right">
<q-btn :label="t('globals.cancel')" color="primary" flat v-close-popup />
<q-btn :label="t('globals.confirm')" color="primary" @click="deleteClaim" />
</q-card-actions>
</q-card>
</q-dialog>
</template>
<i18n>
{
"en": {
"pickupOrder": "Pickup order",
"openPickupOrder": "Open pickup order",
"sendPickupOrder": "Send pickup order",
"deleteClaim": "Delete claim",
"confirmDeletion": "Confirm deletion",
"confirmDeletionMessage": "Are you sure you want to delete this claim?"
},
"es": {
"pickupOrder": "Orden de recogida",
"openPickupOrder": "Abrir orden de recogida",
"sendPickupOrder": "Enviar orden de recogida",
"deleteClaim": "Eliminar reclamación",
"confirmDeletion": "Confirmar eliminación",
"confirmDeletionMessage": "Seguro que quieres eliminar esta reclamación?"
}
}
</i18n>

View File

@ -4,8 +4,8 @@ import { useI18n } from 'vue-i18n';
import { useQuasar } from 'quasar'; import { useQuasar } from 'quasar';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import axios from 'axios'; import axios from 'axios';
import Paginate from 'src/components/Paginate.vue'; import Paginate from 'components/Paginate.vue';
import FetchData from 'src/components/FetchData.vue'; import FetchData from 'components/FetchData.vue';
import { toDate } from 'src/filters'; import { toDate } from 'src/filters';
const quasar = useQuasar(); const quasar = useQuasar();

View File

@ -4,7 +4,7 @@ import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import axios from 'axios'; import axios from 'axios';
import { toDate, toCurrency } from 'src/filters'; import { toDate, toCurrency } from 'src/filters';
import SkeletonSummary from 'src/components/SkeletonSummary'; import SkeletonSummary from 'components/ui/SkeletonSummary.vue';
onMounted(() => fetch()); onMounted(() => fetch());

View File

@ -2,7 +2,7 @@
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { useQuasar } from 'quasar'; import { useQuasar } from 'quasar';
import Paginate from 'src/components/Paginate.vue'; import Paginate from 'components/Paginate.vue';
import { toDate } from 'src/filters/index'; import { toDate } from 'src/filters/index';
import ClaimSummaryDialog from './Card/ClaimSummaryDialog.vue'; import ClaimSummaryDialog from './Card/ClaimSummaryDialog.vue';
import CustomerDescriptorPopover from 'src/pages/Customer/Card/CustomerDescriptorPopover.vue'; import CustomerDescriptorPopover from 'src/pages/Customer/Card/CustomerDescriptorPopover.vue';

View File

@ -1,6 +1,6 @@
<script setup> <script setup>
import { useState } from 'src/composables/useState'; import { useState } from 'src/composables/useState';
import LeftMenu from 'src/components/LeftMenu.vue'; import LeftMenu from 'components/LeftMenu.vue';
const state = useState(); const state = useState();
</script> </script>

View File

@ -3,7 +3,7 @@ import { ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useQuasar } from 'quasar'; import { useQuasar } from 'quasar';
import axios from 'axios'; import axios from 'axios';
import Paginate from 'src/components/Paginate.vue'; import Paginate from 'components/Paginate.vue';
const quasar = useQuasar(); const quasar = useQuasar();
const { t } = useI18n(); const { t } = useI18n();

View File

@ -0,0 +1,63 @@
import { jest, describe, expect, it, beforeAll } from '@jest/globals';
import { createWrapper, axios } from 'app/tests/jest/jestHelpers';
import ClaimDescriptorMenu from '../Card/ClaimDescriptorMenu.vue';
const mockPush = jest.fn();
jest.mock('vue-router', () => ({
useRouter: () => ({
push: mockPush,
currentRoute: {
value: {
params: {
id: 1,
},
},
},
}),
}));
describe('ClaimDescriptorMenu', () => {
let vm;
beforeAll(() => {
vm = createWrapper(ClaimDescriptorMenu).vm;
});
afterEach(() => {
jest.clearAllMocks();
});
describe('getVideoList()', () => {
it('should when response videoList use to list', async () => {
const expeditionId = 1;
const timed = {
min: 1,
max: 2,
};
const videoList = ['2022-01-01T01-01-00.mp4', '2022-02-02T02-02-00.mp4', '2022-03-03T03-03-00.mp4'];
jest.spyOn(axios, 'get').mockResolvedValue({ data: videoList });
jest.spyOn(vm.quasar, 'notify');
await vm.getVideoList(expeditionId, timed);
expect(vm.videoList.length).toEqual(videoList.length);
expect(vm.slide).toEqual(videoList.reverse()[0]);
});
it('should if not have video show notify', async () => {
const expeditionId = 1;
const timed = {
min: 1,
max: 2,
};
jest.spyOn(axios, 'get').mockResolvedValue({ data: [] });
jest.spyOn(vm.quasar, 'notify');
await vm.getVideoList(expeditionId, timed);
expect(vm.quasar.notify).toHaveBeenCalledWith(expect.objectContaining({ type: 'negative' }));
});
});
});

View File

@ -4,8 +4,8 @@ import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useSession } from 'src/composables/useSession'; import { useSession } from 'src/composables/useSession';
import FetchData from 'src/components/FetchData.vue'; import FetchData from 'components/FetchData.vue';
import FormModel from 'src/components/FormModel.vue'; import FormModel from 'components/FormModel.vue';
const route = useRoute(); const route = useRoute();
const { t } = useI18n(); const { t } = useI18n();

View File

@ -4,7 +4,8 @@ import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { toCurrency } from 'src/filters'; import { toCurrency } from 'src/filters';
import axios from 'axios'; import axios from 'axios';
import CardDescriptor from 'src/components/ui/CardDescriptor.vue'; import CardDescriptor from 'components/ui/CardDescriptor.vue';
import SkeletonDescriptor from 'components/ui/SkeletonDescriptor.vue';
const $props = defineProps({ const $props = defineProps({
id: { id: {
@ -34,6 +35,7 @@ async function fetch() {
</script> </script>
<template> <template>
<skeleton-descriptor v-if="!customer" />
<card-descriptor v-if="customer" module="Customer" :data="customer" :description="customer.name"> <card-descriptor v-if="customer" module="Customer" :data="customer" :description="customer.name">
<!-- <template #menu> <!-- <template #menu>
<q-item clickable v-ripple>Option 1</q-item> <q-item clickable v-ripple>Option 1</q-item>

View File

@ -4,7 +4,7 @@ import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import axios from 'axios'; import axios from 'axios';
import { toCurrency, toPercentage, toDate } from 'src/filters'; import { toCurrency, toPercentage, toDate } from 'src/filters';
import SkeletonSummary from 'src/components/SkeletonSummary'; import SkeletonSummary from 'components/ui/SkeletonSummary.vue';
onMounted(() => fetch()); onMounted(() => fetch());

View File

@ -2,7 +2,7 @@
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { useQuasar } from 'quasar'; import { useQuasar } from 'quasar';
import Paginate from 'src/components/Paginate.vue'; import Paginate from 'components/Paginate.vue';
import CustomerSummaryDialog from './Card/CustomerSummaryDialog.vue'; import CustomerSummaryDialog from './Card/CustomerSummaryDialog.vue';
const router = useRouter(); const router = useRouter();

View File

@ -1,6 +1,6 @@
<script setup> <script setup>
import { useState } from 'src/composables/useState'; import { useState } from 'src/composables/useState';
import LeftMenu from 'src/components/LeftMenu.vue'; import LeftMenu from 'components/LeftMenu.vue';
const state = useState(); const state = useState();
</script> </script>

View File

@ -1,8 +1,8 @@
<script setup> <script setup>
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useState } from 'src/composables/useState'; import { useState } from 'src/composables/useState';
import LeftMenu from 'src/components/LeftMenu.vue'; import LeftMenu from 'components/LeftMenu.vue';
import { useNavigation } from 'src/composables/useNavigation'; import { useNavigation } from 'composables/useNavigation';
const { t } = useI18n(); const { t } = useI18n();
const state = useState(); const state = useState();

View File

@ -4,8 +4,9 @@ import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { toDate } from 'src/filters'; import { toDate } from 'src/filters';
import axios from 'axios'; import axios from 'axios';
import CardDescriptor from 'src/components/ui/CardDescriptor.vue';
import CustomerDescriptorPopover from 'src/pages/Customer/Card/CustomerDescriptorPopover.vue'; import CustomerDescriptorPopover from 'src/pages/Customer/Card/CustomerDescriptorPopover.vue';
import CardDescriptor from 'components/ui/CardDescriptor.vue';
import SkeletonDescriptor from 'components/ui/SkeletonDescriptor.vue';
const $props = defineProps({ const $props = defineProps({
id: { id: {
@ -42,6 +43,7 @@ function stateColor(state) {
</script> </script>
<template> <template>
<skeleton-descriptor v-if="!ticket" />
<card-descriptor v-if="ticket" module="Ticket" :data="ticket" :description="ticket.client.name"> <card-descriptor v-if="ticket" module="Ticket" :data="ticket" :description="ticket.client.name">
<!-- <template #menu> <!-- <template #menu>
<q-item clickable v-ripple>Option 1</q-item> <q-item clickable v-ripple>Option 1</q-item>

View File

@ -2,7 +2,7 @@
import { ref } from 'vue'; import { ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import Paginate from 'src/components/Paginate.vue'; import Paginate from 'components/Paginate.vue';
import { toDate, toCurrency } from 'src/filters/index'; import { toDate, toCurrency } from 'src/filters/index';
// import TicketSummary from './Card/TicketSummary.vue'; // import TicketSummary from './Card/TicketSummary.vue';

View File

@ -1,6 +1,6 @@
<script setup> <script setup>
import { useState } from 'src/composables/useState'; import { useState } from 'src/composables/useState';
import LeftMenu from 'src/components/LeftMenu.vue'; import LeftMenu from 'components/LeftMenu.vue';
const state = useState(); const state = useState();
</script> </script>