diff --git a/CHANGELOG.md b/CHANGELOG.md index 243d67a34..3316aa441 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2352.01] - 2023-12-28 + +### Added +- (carros) => Se añade contador de carros. #6545 +- (Reclamaciones) => Se añade la sección para hacer acciones sobre una reclamación. #5654 +### Changed +### Fixed +- (Reclamaciones) => Se corrige el color de la barra según el tema y el evento de actualziar cantidades #6334 + + ## [2253.01] - 2023-01-05 ### Added diff --git a/package.json b/package.json index 799401c08..583233204 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "salix-front", - "version": "23.48.01", + "version": "23.52.01", "description": "Salix frontend", "productName": "Salix", "author": "Verdnatura", @@ -53,4 +53,4 @@ "vite": "^4.3.5", "vitest": "^0.31.1" } -} \ No newline at end of file +} diff --git a/quasar.config.js b/quasar.config.js index cbcbae4dc..3a7dc1f1e 100644 --- a/quasar.config.js +++ b/quasar.config.js @@ -66,7 +66,9 @@ module.exports = configure(function (/* ctx */) { // publicPath: '/', // analyze: true, // env: {}, - // rawDefine: {} + rawDefine: { + 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) + }, // ignorePublicFolder: true, // minify: false, // polyfillModulePreload: true, @@ -89,11 +91,12 @@ module.exports = configure(function (/* ctx */) { vitePlugins: [ [ - VueI18nPlugin, + VueI18nPlugin({ + runtimeOnly: false + }), { // if you want to use Vue I18n Legacy API, you need to set `compositionOnly: false` // compositionOnly: false, - // you need to set i18n resource including paths ! include: path.resolve(__dirname, './src/i18n/**'), }, diff --git a/src/components/CrudModel.vue b/src/components/CrudModel.vue index 96d52b98c..a5156dc79 100644 --- a/src/components/CrudModel.vue +++ b/src/components/CrudModel.vue @@ -269,7 +269,7 @@ watch(formUrl, async () => { - + - - + + {{ t('globals.collapseMenu') }} - + - + diff --git a/src/components/ui/CardDescriptor.vue b/src/components/ui/CardDescriptor.vue index 2e706a56c..2c1518b73 100644 --- a/src/components/ui/CardDescriptor.vue +++ b/src/components/ui/CardDescriptor.vue @@ -1,9 +1,10 @@ + + + + diff --git a/src/components/ui/VnPaginate.vue b/src/components/ui/VnPaginate.vue index d21d073f2..c75761462 100644 --- a/src/components/ui/VnPaginate.vue +++ b/src/components/ui/VnPaginate.vue @@ -50,6 +50,10 @@ const props = defineProps({ type: Boolean, default: true, }, + exprBuilder: { + type: Function, + default: null, + }, }); const emit = defineEmits(['onFetch', 'onPaginate']); @@ -68,6 +72,7 @@ const arrayData = useArrayData(props.dataKey, { limit: props.limit, order: props.order, userParams: props.userParams, + exprBuilder: props.exprBuilder, }); const store = arrayData.store; diff --git a/src/composables/useArrayData.js b/src/composables/useArrayData.js index 9aff0eaa8..6fcca4722 100644 --- a/src/composables/useArrayData.js +++ b/src/composables/useArrayData.js @@ -2,6 +2,7 @@ import { onMounted, ref, computed } from 'vue'; import { useRouter, useRoute } from 'vue-router'; import axios from 'axios'; import { useArrayDataStore } from 'stores/useArrayDataStore'; +import { buildFilter } from 'filters/filterPanel'; const arrayDataStore = useArrayDataStore(); @@ -29,6 +30,10 @@ export function useArrayData(key, userOptions) { } }); + if (key && userOptions) { + setOptions(); + } + function setOptions() { const allowedOptions = [ 'url', @@ -39,10 +44,11 @@ export function useArrayData(key, userOptions) { 'skip', 'userParams', 'userFilter', + 'exprBuilder', ]; if (typeof userOptions === 'object') { for (const option in userOptions) { - const isEmpty = userOptions[option] == null || userOptions[option] == ''; + const isEmpty = userOptions[option] == null || userOptions[option] === ''; if (isEmpty || !allowedOptions.includes(option)) continue; if (Object.prototype.hasOwnProperty.call(store, option)) { @@ -64,16 +70,27 @@ export function useArrayData(key, userOptions) { skip: store.skip, }; - Object.assign(filter, store.userFilter); - Object.assign(store.filter, filter); + let exprFilter; + let userParams = { ...store.userParams }; + if (store?.exprBuilder) { + const where = buildFilter(userParams, (param, value) => { + const res = store.exprBuilder(param, value); + if (res) delete userParams[param]; + return res; + }); + exprFilter = where ? { where } : null; + } + Object.assign(filter, store.userFilter, exprFilter); + Object.assign(store.filter, filter); const params = { filter: JSON.stringify(store.filter), }; - Object.assign(params, store.userParams); + Object.assign(params, userParams); store.isLoading = true; + const response = await axios.get(store.url, { signal: canceller.signal, params, @@ -97,6 +114,7 @@ export function useArrayData(key, userOptions) { store.isLoading = false; canceller = null; + return response; } function destroy() { @@ -121,9 +139,30 @@ export function useArrayData(key, userOptions) { async function addFilter({ filter, params }) { if (filter) store.userFilter = Object.assign(store.userFilter, filter); - if (params) store.userParams = Object.assign(store.userParams, params); + + let userParams = Object.assign({}, store.userParams, params); + userParams = sanitizerParams(userParams, store?.exprBuilder); + + store.userParams = userParams; await fetch({ append: false }); + return { filter, params }; + } + + function sanitizerParams(params) { + for (const param in params) { + if (params[param] === '' || params[param] === null) { + delete store.userParams[param]; + delete params[param]; + if (store.filter?.where) { + delete store.filter.where[Object.keys(store?.exprBuilder(param))[0]]; + if (Object.keys(store.filter.where).length === 0) { + delete store.filter.where; + } + } + } + } + return params; } async function loadMore() { @@ -147,10 +186,11 @@ export function useArrayData(key, userOptions) { if (store.userParams && Object.keys(store.userParams).length !== 0) query.params = JSON.stringify(store.userParams); - router.replace({ - path: route.path, - query: query, - }); + if (router) + router.replace({ + path: route.path, + query: query, + }); } const totalRows = computed(() => (store.data && store.data.length) || 0); diff --git a/src/css/app.scss b/src/css/app.scss index 0f04c9ad8..99170202d 100644 --- a/src/css/app.scss +++ b/src/css/app.scss @@ -45,3 +45,9 @@ body.body--dark { .bg-vn-dark { background-color: var(--vn-dark); } + +.vn-card { + background-color: var(--vn-gray); + color: var(--vn-text); + border-radius: 8px; +} diff --git a/src/filters/filterPanel.js b/src/filters/filterPanel.js new file mode 100644 index 000000000..ee91e6749 --- /dev/null +++ b/src/filters/filterPanel.js @@ -0,0 +1,94 @@ +/** + * Passes a loopback fields filter to an object. + * + * @param {Object} fields The fields object or array + * @return {Object} The fields as object + */ +function fieldsToObject(fields) { + let fieldsObj = {}; + + if (Array.isArray(fields)) { + for (let field of fields) fieldsObj[field] = true; + } else if (typeof fields == 'object') { + for (let field in fields) { + if (fields[field]) fieldsObj[field] = true; + } + } + + return fieldsObj; +} + +/** + * Merges two loopback fields filters. + * + * @param {Object|Array} src The source fields + * @param {Object|Array} dst The destination fields + * @return {Array} The merged fields as an array + */ +function mergeFields(src, dst) { + let fields = {}; + Object.assign(fields, fieldsToObject(src), fieldsToObject(dst)); + return Object.keys(fields); +} + +/** + * Merges two loopback where filters. + * + * @param {Object|Array} src The source where + * @param {Object|Array} dst The destination where + * @return {Array} The merged wheres + */ +function mergeWhere(src, dst) { + let and = []; + if (src) and.push(src); + if (dst) and.push(dst); + return simplifyOperation(and, 'and'); +} + +/** + * Merges two loopback filters returning the merged filter. + * + * @param {Object} src The source filter + * @param {Object} dst The destination filter + * @return {Object} The result filter + */ +function mergeFilters(src, dst) { + let res = Object.assign({}, dst); + + if (!src) return res; + + if (src.fields) res.fields = mergeFields(src.fields, res.fields); + if (src.where) res.where = mergeWhere(res.where, src.where); + if (src.include) res.include = src.include; + if (src.order) res.order = src.order; + if (src.limit) res.limit = src.limit; + if (src.offset) res.offset = src.offset; + if (src.skip) res.skip = src.skip; + + return res; +} + +function simplifyOperation(operation, operator) { + switch (operation.length) { + case 0: + return undefined; + case 1: + return operation[0]; + default: + return { [operator]: operation }; + } +} + +function buildFilter(params, builderFunc) { + let and = []; + + for (let param in params) { + let value = params[param]; + if (value == null) continue; + let expr = builderFunc(param, value); + if (expr) and.push(expr); + } + return simplifyOperation(and, 'and'); +} + +export { fieldsToObject, mergeFields, mergeWhere, mergeFilters, buildFilter }; diff --git a/src/i18n/en/index.js b/src/i18n/en/index.js index 948332d46..ea80c7918 100644 --- a/src/i18n/en/index.js +++ b/src/i18n/en/index.js @@ -36,6 +36,7 @@ export default { summary: { basicData: 'Basic data', }, + microsip: 'Open in MicroSIP', noSelectedRows: `You don't have any line selected`, }, errors: { @@ -274,6 +275,7 @@ export default { development: 'Development', log: 'Audit logs', notes: 'Notes', + action: 'Action', }, list: { customer: 'Customer', @@ -448,6 +450,7 @@ export default { typesList: 'Types List', typeCreate: 'Create type', typeEdit: 'Edit type', + wagonCounter: 'Trolley counter', }, type: { name: 'Name', diff --git a/src/i18n/es/index.js b/src/i18n/es/index.js index 9b452ab22..b18dee96e 100644 --- a/src/i18n/es/index.js +++ b/src/i18n/es/index.js @@ -37,6 +37,7 @@ export default { basicData: 'Datos básicos', }, noSelectedRows: `No tienes ninguna línea seleccionada`, + microsip: 'Abrir en MicroSIP', }, errors: { statusUnauthorized: 'Acceso denegado', @@ -273,6 +274,7 @@ export default { photos: 'Fotos', log: 'Registros de auditoría', notes: 'Notas', + action: 'Acción', }, list: { customer: 'Cliente', @@ -448,6 +450,7 @@ export default { typesList: 'Listado tipos', typeCreate: 'Crear tipo', typeEdit: 'Editar tipo', + wagonCounter: 'Contador de carros', }, type: { name: 'Nombre', diff --git a/src/pages/Claim/Card/ClaimAction.vue b/src/pages/Claim/Card/ClaimAction.vue new file mode 100644 index 000000000..44575f1d6 --- /dev/null +++ b/src/pages/Claim/Card/ClaimAction.vue @@ -0,0 +1,518 @@ + + + (claim = data)" + auto-load + /> + (resolvedStateId = data.id)" + auto-load + :where="{ code: 'resolved' }" + /> + (destinationTypes = data)" + /> + + + + + + {{ t('globals.collapseMenu') }} + + + + + + + + {{ `${t('Total claimed')}: ${toCurrency(totalClaimed)}` }} + + + + + + {{ t('claim.summary.actions') }} + + save({ responsibility: value })" + label-always + color="primary" + markers + :marker-labels="marker_labels" + :min="DEFAULT_MIN_RESPONSABILITY" + :max="DEFAULT_MAX_RESPONSABILITY" + /> + + + + + save({ isChargedToMana: value })" + /> + {{ t('mana') }} + + + + + + + + + + {{ value }} + + + + + + + updateDestination(value, row)" + /> + + + + + {{ toCurrency(value) }} + + + + + {{ toCurrency(value) }} + + + + + + + + + + + + + + + + + {{ column.label }} + + + + + {{ column.value.description }} + + + {{ column.value }} + + + + + + + + + + + + + + + + + + + + + + {{ t('dialog title') }} + + + + + + + + + + + + + + + + + +en: + mana: Is paid with mana + dialog title: Change destination to all selected rows + confirmGreuges: Do you want to insert complaints? + confirmGreugesMessage: Insert complaints into the client's record + +es: + mana: Cargado al maná + Delivered: Descripción + Quantity: Cantidad + Claimed: Rec + Description: Descripción + Price: Precio + Discount: Dto. + Destination: Destino + Landed: F.entrega + Remove line: Eliminar línea + Total claimed: Total reclamado + Regularize: Regularizar + Change destination: Cambiar destino + Import claim: Importar reclamación + dialog title: Cambiar destino en todas las filas seleccionadas + Remove: Eliminar + dialogGreuge title: Insertar greuges en la ficha del cliente + ClaimGreugeDescription: Id reclamación + Id item: Id artículo + confirmGreuges: ¿Desea insertar greuges? + confirmGreugesMessage: Insertar greuges en la ficha del cliente + diff --git a/src/pages/Claim/Card/ClaimCard.vue b/src/pages/Claim/Card/ClaimCard.vue index 03b9889f0..a8c832967 100644 --- a/src/pages/Claim/Card/ClaimCard.vue +++ b/src/pages/Claim/Card/ClaimCard.vue @@ -22,11 +22,6 @@ const $props = defineProps({ const entityId = computed(() => { return $props.id || route.params.id; }); - -let salixUrl; -onMounted(async () => { - salixUrl = await getUrl(`claim/${entityId.value}`); -}); @@ -42,18 +37,6 @@ onMounted(async () => { - - - - - {{ t('Action') }} - - diff --git a/src/pages/Claim/Card/ClaimDescriptor.vue b/src/pages/Claim/Card/ClaimDescriptor.vue index dafdfacdd..85ae9f7e1 100644 --- a/src/pages/Claim/Card/ClaimDescriptor.vue +++ b/src/pages/Claim/Card/ClaimDescriptor.vue @@ -63,13 +63,18 @@ const filter = { ], }; +const STATE_COLOR = { + pending: 'positive', + managed: 'warning', + resolved: 'negative', +}; + function stateColor(code) { - if (code === 'pending') return 'positive'; - if (code === 'managed') return 'warning'; - if (code === 'resolved') return 'negative'; + return STATE_COLOR[code]; } const data = ref(useCardDescription()); const setData = (entity) => { + if (!entity) return; data.value = useCardDescription(entity.client.name, entity.id); state.set('ClaimDescriptor', entity); }; @@ -84,6 +89,7 @@ const setData = (entity) => { :title="data.title" :subtitle="data.subtitle" @on-fetch="setData" + data-key="claimData" > @@ -121,16 +127,16 @@ const setData = (entity) => { - {{ entity.client.salesPersonUser.name }} - + {{ entity.client?.salesPersonUser?.name }} + - + diff --git a/src/pages/Claim/Card/ClaimDevelopment.vue b/src/pages/Claim/Card/ClaimDevelopment.vue index 09422f7a1..0ab3c6c90 100644 --- a/src/pages/Claim/Card/ClaimDevelopment.vue +++ b/src/pages/Claim/Card/ClaimDevelopment.vue @@ -7,6 +7,7 @@ import FetchData from 'components/FetchData.vue'; import VnSelectFilter from 'components/common/VnSelectFilter.vue'; import { getUrl } from 'composables/getUrl'; import { tMobile } from 'composables/tMobile'; +import router from 'src/router'; const route = useRoute(); @@ -102,10 +103,6 @@ const columns = computed(() => [ tabIndex: 5, }, ]); - -function goToAction() { - location.href = `${salixUrl}/action`; -} @@ -175,6 +172,7 @@ function goToAction() { :option-label="col.optionLabel" :autofocus="col.tabIndex == 1" input-debounce="0" + hide-selected > @@ -213,6 +211,7 @@ function goToAction() { dense input-debounce="0" :autofocus="col.tabIndex == 1" + hide-selected /> diff --git a/src/pages/Claim/Card/ClaimLines.vue b/src/pages/Claim/Card/ClaimLines.vue index c03291b85..fa7fb123f 100644 --- a/src/pages/Claim/Card/ClaimLines.vue +++ b/src/pages/Claim/Card/ClaimLines.vue @@ -46,7 +46,7 @@ async function onFetchClaim(data) { const amount = ref(0); const amountClaimed = ref(0); async function onFetch(rows) { - if (!rows || rows.length) return; + if (!rows || !rows.length) return; amount.value = rows.reduce( (acumulator, { sale }) => acumulator + sale.price * sale.quantity, 0 @@ -155,7 +155,7 @@ function showImportDialog() { - + {{ t('Amount') }} diff --git a/src/pages/Claim/Card/ClaimPhoto.vue b/src/pages/Claim/Card/ClaimPhoto.vue index 483dbffc1..6ac116ce0 100644 --- a/src/pages/Claim/Card/ClaimPhoto.vue +++ b/src/pages/Claim/Card/ClaimPhoto.vue @@ -26,6 +26,7 @@ const client = ref({}); const inputFile = ref(); const files = ref({}); +const spinnerRef = ref(); const claimDmsRef = ref(); const dmsType = ref({}); const config = ref({}); @@ -118,11 +119,11 @@ async function create() { clientId: client.value.id, }).toUpperCase(), }; - + spinnerRef.value.show(); await axios.post(query, formData, { params: dms, }); - + spinnerRef.value.hide(); quasar.notify({ message: t('globals.dataSaved'), type: 'positive', @@ -234,7 +235,9 @@ function onDrag() { - + + + diff --git a/src/pages/Claim/Card/ClaimSummary.vue b/src/pages/Claim/Card/ClaimSummary.vue index dc5ec9544..64d7b721b 100644 --- a/src/pages/Claim/Card/ClaimSummary.vue +++ b/src/pages/Claim/Card/ClaimSummary.vue @@ -85,10 +85,15 @@ const detailsColumns = ref([ }, ]); +const STATE_COLOR = { + pending: 'positive', + + managed: 'warning', + + resolved: 'negative', +}; function stateColor(code) { - if (code === 'pending') return 'green'; - if (code === 'managed') return 'orange'; - if (code === 'resolved') return 'red'; + return STATE_COLOR[code]; } const developmentColumns = ref([ diff --git a/src/pages/Claim/ClaimFilter.vue b/src/pages/Claim/ClaimFilter.vue index 5918712fd..ac8f4f0db 100644 --- a/src/pages/Claim/ClaimFilter.vue +++ b/src/pages/Claim/ClaimFilter.vue @@ -3,6 +3,7 @@ import { ref } from 'vue'; import { useI18n } from 'vue-i18n'; import FetchData from 'components/FetchData.vue'; import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; +import VnSelectFilter from 'components/common/VnSelectFilter.vue'; const { t } = useI18n(); const props = defineProps({ @@ -60,7 +61,7 @@ const states = ref(); - - - - (data.value = useCardDescription(entity.name, entity :subtitle="data.subtitle" @on-fetch="setData" :summary="$props.summary" + data-key="customerData" > diff --git a/src/pages/Customer/Card/CustomerSummary.vue b/src/pages/Customer/Card/CustomerSummary.vue index 081bdd157..6693274ac 100644 --- a/src/pages/Customer/Card/CustomerSummary.vue +++ b/src/pages/Customer/Card/CustomerSummary.vue @@ -6,6 +6,7 @@ import { toCurrency, toPercentage, toDate } from 'src/filters'; import CardSummary from 'components/ui/CardSummary.vue'; import { getUrl } from 'src/composables/getUrl'; import VnLv from 'src/components/ui/VnLv.vue'; +import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue'; const route = useRoute(); const { t } = useI18n(); @@ -68,8 +69,18 @@ const creditWarning = computed(() => { - - + + + {{ t('customer.summary.phone') }} + + + + + + {{ t('customer.summary.mobile') }} + + + - - @@ -124,7 +126,7 @@ const zones = ref(); - - + + + {{ t('customer.list.phone') }} + + + (data.value = useCardDescription(entity.ref, entity. :title="data.title" :subtitle="data.subtitle" @on-fetch="setData" + data-key="invoiceOutData" > diff --git a/src/pages/Ticket/Card/TicketDescriptor.vue b/src/pages/Ticket/Card/TicketDescriptor.vue index 641ffee0c..d2a407874 100644 --- a/src/pages/Ticket/Card/TicketDescriptor.vue +++ b/src/pages/Ticket/Card/TicketDescriptor.vue @@ -81,6 +81,7 @@ const setData = (entity) => :filter="filter" :title="data.title" :subtitle="data.subtitle" + data-key="ticketData" @on-fetch="setData" > diff --git a/src/pages/Ticket/Card/TicketSummary.vue b/src/pages/Ticket/Card/TicketSummary.vue index ce46d1d47..5c4c79a4f 100644 --- a/src/pages/Ticket/Card/TicketSummary.vue +++ b/src/pages/Ticket/Card/TicketSummary.vue @@ -10,6 +10,7 @@ import FetchedTags from 'components/ui/FetchedTags.vue'; import InvoiceOutDescriptorProxy from 'pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue'; import WorkerDescriptorProxy from 'pages/Worker/Card/WorkerDescriptorProxy.vue'; import VnLv from 'src/components/ui/VnLv.vue'; +import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue'; import { getUrl } from 'src/composables/getUrl'; onUpdated(() => summaryRef.value.fetch()); @@ -172,7 +173,7 @@ async function changeState(value) { :label="t('ticket.summary.agency')" :value="ticket.agencyMode.name" /> - + - + {{ dashIfEmpty(ticket.refFk) }} - - - - + + + {{ t('ticket.summary.consigneePhone') }} + + + + + + {{ t('ticket.summary.consigneeMobile') }} + + + + + + {{ t('ticket.summary.clientPhone') }} + + + + + + {{ t('ticket.summary.clientMobile') }} + + + - + diff --git a/src/pages/Wagon/WagonCounter.vue b/src/pages/Wagon/WagonCounter.vue new file mode 100644 index 000000000..bd5d2ca67 --- /dev/null +++ b/src/pages/Wagon/WagonCounter.vue @@ -0,0 +1,154 @@ + + + + + + + {{ props.title }} + + + + {{ props.count }} + + + + {{ t('Add 30') }} + + + {{ t('Add 10') }} + + + + + {{ t('Subtract 1') }} + + + {{ t('Flush') }} + + + + + + + + + +es: + Subtract 1: Quitar 1 + Add 30: Añadir 30 + Add 10: Añadir 10 + Flush: Vaciar + Are you sure?: ¿Estás seguro? + It will set to 0: Se pondrá a 0 + The counter will be reset to zero: Se pondrá el contador a cero + diff --git a/src/pages/Worker/Card/WorkerDescriptor.vue b/src/pages/Worker/Card/WorkerDescriptor.vue index a4dd8b55a..f089c0022 100644 --- a/src/pages/Worker/Card/WorkerDescriptor.vue +++ b/src/pages/Worker/Card/WorkerDescriptor.vue @@ -5,7 +5,9 @@ import { useI18n } from 'vue-i18n'; import { useSession } from 'src/composables/useSession'; import CardDescriptor from 'src/components/ui/CardDescriptor.vue'; import VnLv from 'src/components/ui/VnLv.vue'; +import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue'; import useCardDescription from 'src/composables/useCardDescription'; + const $props = defineProps({ id: { type: Number, @@ -51,19 +53,22 @@ const filter = { ], }; -const sip = computed(() => worker.value.sip && worker.value.sip.extension); +const sip = computed(() => worker.value?.sip && worker.value.sip.extension); function getWorkerAvatar() { const token = getToken(); return `/api/Images/user/160x160/${entityId.value}/download?access_token=${token}`; } const data = ref(useCardDescription()); -const setData = (entity) => - (data.value = useCardDescription(entity.user.nickname, entity.id)); +const setData = (entity) => { + if (!entity) return; + data.value = useCardDescription(entity.user.nickname, entity.id); +}; - - + + - - + + + {{ t('worker.card.phone') }} + + + + + + {{ t('worker.summary.sipExtension') }} + + + diff --git a/src/pages/Worker/Card/WorkerSummary.vue b/src/pages/Worker/Card/WorkerSummary.vue index 7c8accc5d..970a0dee4 100644 --- a/src/pages/Worker/Card/WorkerSummary.vue +++ b/src/pages/Worker/Card/WorkerSummary.vue @@ -7,6 +7,7 @@ import { getUrl } from 'src/composables/getUrl'; import VnLv from 'src/components/ui/VnLv.vue'; import WorkerDescriptorProxy from './WorkerDescriptorProxy.vue'; import { dashIfEmpty } from 'src/filters'; +import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue'; const route = useRoute(); const { t } = useI18n(); @@ -91,15 +92,24 @@ const filter = { - - - + + + {{ t('worker.summary.phoneExtension') }} + + + + + + {{ t('worker.summary.entPhone') }} + + + + + + {{ t('worker.summary.personalPhone') }} + + + @@ -109,10 +119,12 @@ const filter = { - + + + {{ t('worker.summary.sipExtension') }} + + + diff --git a/src/router/modules/claim.js b/src/router/modules/claim.js index 9df1dd64e..1dfd75cff 100644 --- a/src/router/modules/claim.js +++ b/src/router/modules/claim.js @@ -19,6 +19,7 @@ export default { 'ClaimLog', 'ClaimNotes', 'ClaimDevelopment', + 'ClaimAction', ], }, children: [ @@ -130,6 +131,15 @@ export default { }, component: () => import('src/pages/Claim/Card/ClaimNotes.vue'), }, + { + name: 'ClaimAction', + path: 'action', + meta: { + title: 'action', + icon: 'vn:actions', + }, + component: () => import('src/pages/Claim/Card/ClaimAction.vue'), + }, ], }, ], diff --git a/src/router/modules/wagon.js b/src/router/modules/wagon.js index 3fb808778..238e482dd 100644 --- a/src/router/modules/wagon.js +++ b/src/router/modules/wagon.js @@ -10,7 +10,7 @@ export default { component: RouterView, redirect: { name: 'WagonMain' }, menus: { - main: ['WagonList', 'WagonTypeList'], + main: ['WagonList', 'WagonTypeList', 'WagonCounter'], card: [], }, children: [ @@ -47,6 +47,15 @@ export default { }, component: () => import('src/pages/Wagon/WagonCreate.vue'), }, + { + path: 'counter', + name: 'WagonCounter', + meta: { + title: 'wagonCounter', + icon: 'add_circle', + }, + component: () => import('src/pages/Wagon/WagonCounter.vue'), + }, ], }, { diff --git a/src/stores/useArrayDataStore.js b/src/stores/useArrayDataStore.js index f9a32a6fa..223406a33 100644 --- a/src/stores/useArrayDataStore.js +++ b/src/stores/useArrayDataStore.js @@ -18,7 +18,8 @@ export const useArrayDataStore = defineStore('arrayDataStore', () => { skip: 0, order: '', data: ref(), - isLoading: false + isLoading: false, + exprBuilder: null, }; } diff --git a/test/cypress/integration/claimAction.spec.js b/test/cypress/integration/claimAction.spec.js new file mode 100644 index 000000000..f181722fa --- /dev/null +++ b/test/cypress/integration/claimAction.spec.js @@ -0,0 +1,45 @@ +/// +describe('ClaimAction', () => { + const claimId = 2; + + const firstRow = 'tbody > :nth-child(1)'; + const destinationRow = '.q-item__section > .q-field'; + + beforeEach(() => { + cy.viewport(1920, 1080); + cy.login('developer'); + cy.visit(`/#/claim/${claimId}/action`); + }); + + it('should import claim', () => { + cy.get('[title="Import claim"]').click(); + }); + + it('should change destination', () => { + const rowData = [true, null, null, 'Bueno']; + cy.fillRow(firstRow, rowData); + }); + + it('should change destination from other button', () => { + const rowData = [true]; + + cy.fillRow(firstRow, rowData); + cy.get('[title="Change destination"]').click(); + cy.selectOption(destinationRow, 'Confeccion'); + cy.get('.q-card > .q-card__actions > .q-btn--standard').click(); + }); + + it('should regularize', () => { + cy.get('[title="Regularize"]').click(); + cy.clickConfirm(); + }); + + it('should remove the line', () => { + cy.fillRow(firstRow, [true]); + cy.removeCard(); + cy.clickConfirm(); + + cy.reload(); + cy.get(firstRow).should('not.exist'); + }); +}); diff --git a/test/cypress/integration/claimNotes.spec.js b/test/cypress/integration/claimNotes.spec.js index 5b52dd339..0a0f28fe7 100644 --- a/test/cypress/integration/claimNotes.spec.js +++ b/test/cypress/integration/claimNotes.spec.js @@ -7,7 +7,7 @@ describe('ClaimNotes', () => { it('should add a new note', () => { const message = 'This is a new message.'; - cy.get('.q-page-sticky button').click(); + cy.get('.q-page-sticky > div > button').click(); cy.get('.q-dialog .q-card__section:nth-child(2)').type(message); cy.get('.q-card__actions button:nth-child(2)').click(); cy.get('.q-card .q-card__section:nth-child(2)') diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js index a67df121e..d361eee1a 100755 --- a/test/cypress/support/commands.js +++ b/test/cypress/support/commands.js @@ -88,7 +88,8 @@ Cypress.Commands.add('addCard', () => { cy.get('.q-page-sticky > div > .q-btn').click(); }); Cypress.Commands.add('clickConfirm', () => { - cy.get('.q-btn--unelevated > .q-btn__content > .block').click(); + cy.waitForElement('.q-dialog__inner > .q-card'); + cy.get('.q-card__actions > .q-btn--unelevated > .q-btn__content > .block').click(); }); Cypress.Commands.add('notificationHas', (selector, text) => {
+ {{ t('claim.summary.actions') }} +
{{ props.title }}