Merge branch '6679-addCreateIcon' of https://gitea.verdnatura.es/verdnatura/salix-front into 6679-addCreateIcon
gitea/salix-front/pipeline/pr-dev This commit looks good Details

This commit is contained in:
Robert Ferrús 2024-04-10 14:42:48 +02:00
commit f59ecbf94e
21 changed files with 336 additions and 131 deletions

View File

@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added ### Added
### Fixed
- (General) => Se vuelven a mostrar los parámetros en la url al aplicar un filtro
## [2414.01] - 2024-04-04 ## [2414.01] - 2024-04-04
### Added ### Added

View File

@ -101,16 +101,16 @@ onMounted(async () => {
}); });
onBeforeRouteLeave((to, from, next) => { onBeforeRouteLeave((to, from, next) => {
if (!hasChanges.value) next(); if (hasChanges.value)
quasar.dialog({
quasar.dialog({ component: VnConfirm,
component: VnConfirm, componentProps: {
componentProps: { title: t('Unsaved changes will be lost'),
title: t('Unsaved changes will be lost'), message: t('Are you sure exit without saving?'),
message: t('Are you sure exit without saving?'), promise: () => next(),
promise: () => next(), },
}, });
}); else next();
}); });
onUnmounted(() => { onUnmounted(() => {
@ -132,12 +132,12 @@ const formUrl = computed(() => $props.url);
const defaultButtons = computed(() => ({ const defaultButtons = computed(() => ({
save: { save: {
color: 'primary', color: 'primary',
icon: 'restart_alt', icon: 'save',
label: 'globals.save', label: 'globals.save',
}, },
reset: { reset: {
color: 'primary', color: 'primary',
icon: 'save', icon: 'restart_alt',
label: 'globals.reset', label: 'globals.reset',
}, },
...$props.defaultButtons, ...$props.defaultButtons,

View File

@ -5,7 +5,7 @@ import { useCapitalize } from 'src/composables/useCapitalize';
import VnInput from 'src/components/common/VnInput.vue'; import VnInput from 'src/components/common/VnInput.vue';
const props = defineProps({ const props = defineProps({
modelValue: { type: String, default: '' }, modelValue: { type: [String, Number], default: '' },
}); });
const { t } = useI18n(); const { t } = useI18n();

View File

@ -198,11 +198,13 @@ function addDefaultData(data) {
en: en:
contentTypesInfo: Allowed file types {allowedContentTypes} contentTypesInfo: Allowed file types {allowedContentTypes}
EntryDmsDescription: Reference {reference} EntryDmsDescription: Reference {reference}
WorkersDescription: Working of employee id {reference}
SupplierDmsDescription: Reference {reference} SupplierDmsDescription: Reference {reference}
es: es:
Generate identifier for original file: Generar identificador para archivo original Generate identifier for original file: Generar identificador para archivo original
contentTypesInfo: Tipos de archivo permitidos {allowedContentTypes} contentTypesInfo: Tipos de archivo permitidos {allowedContentTypes}
EntryDmsDescription: Referencia {reference} EntryDmsDescription: Referencia {reference}
WorkersDescription: Laboral del empleado {reference}
SupplierDmsDescription: Referencia {reference} SupplierDmsDescription: Referencia {reference}
</i18n> </i18n>

View File

@ -5,9 +5,11 @@ import { useRoute } from 'vue-router';
import { useQuasar, QCheckbox, QBtn, QInput } from 'quasar'; import { useQuasar, QCheckbox, QBtn, QInput } from 'quasar';
import axios from 'axios'; import axios from 'axios';
import FetchData from 'components/FetchData.vue'; import VnPaginate from 'components/ui/VnPaginate.vue';
import VnDms from 'src/components/common/VnDms.vue'; import VnDms from 'src/components/common/VnDms.vue';
import VnConfirm from 'components/ui/VnConfirm.vue'; import VnConfirm from 'components/ui/VnConfirm.vue';
import VnInputDate from 'components/common/VnInputDate.vue';
import VnUserLink from '../ui/VnUserLink.vue';
import { downloadFile } from 'src/composables/downloadFile'; import { downloadFile } from 'src/composables/downloadFile';
const route = useRoute(); const route = useRoute();
@ -26,6 +28,15 @@ const $props = defineProps({
type: String, type: String,
default: null, default: null,
}, },
deleteModel: {
type: String,
default: null,
},
downloadModel: {
type: String,
required: false,
default: null,
},
defaultDmsCode: { defaultDmsCode: {
type: String, type: String,
required: true, required: true,
@ -74,7 +85,7 @@ const dmsFilter = {
], ],
}, },
}, },
order: ['dmsFk DESC'], where: { [$props.filter]: route.params.id },
}; };
const columns = computed(() => [ const columns = computed(() => [
@ -94,12 +105,12 @@ const columns = computed(() => [
props: (prop) => ({ props: (prop) => ({
readonly: true, readonly: true,
borderless: true, borderless: true,
'model-value': prop.row.dmsType.name, 'model-value': prop.row.dmsType?.name,
}), }),
}, },
{ {
align: 'left', align: 'left',
field: 'order', field: 'hardCopyNumber',
label: t('globals.order'), label: t('globals.order'),
name: 'order', name: 'order',
component: 'span', component: 'span',
@ -117,6 +128,7 @@ const columns = computed(() => [
label: t('globals.description'), label: t('globals.description'),
name: 'description', name: 'description',
component: 'span', component: 'span',
props: (prop) => ({ value: prop.value?.toUpperCase() }),
}, },
{ {
align: 'left', align: 'left',
@ -136,21 +148,53 @@ const columns = computed(() => [
name: 'file', name: 'file',
component: 'span', component: 'span',
}, },
{
align: 'left',
field: 'worker',
label: t('globals.worker'),
name: 'worker',
component: VnUserLink,
props: (prop) => ({
name: prop.row.worker?.user?.name.toLowerCase(),
workerId: prop.row.worker?.id,
}),
},
{
align: 'left',
field: 'created',
label: t('globals.created'),
name: 'created',
component: VnInputDate,
props: (prop) => ({
disable: true,
'model-value': prop.row.created,
}),
},
{ {
field: 'options', field: 'options',
name: 'options', name: 'options',
components: [ components: [
{ {
component: QBtn, component: QBtn,
name: 'download',
isDocuware: true,
props: () => ({ props: () => ({
icon: 'cloud_download', icon: 'cloud_download',
flat: true, flat: true,
color: 'primary', color: 'primary',
}), }),
click: (prop) => downloadFile(prop.row.id), click: (prop) =>
downloadFile(
prop.row.id,
$props.downloadModel,
null,
prop.row.download
),
}, },
{ {
component: QBtn, component: QBtn,
name: 'edit',
external: false,
props: () => ({ props: () => ({
icon: 'edit', icon: 'edit',
flat: true, flat: true,
@ -160,6 +204,8 @@ const columns = computed(() => [
}, },
{ {
component: QBtn, component: QBtn,
name: 'delete',
external: false,
props: () => ({ props: () => ({
icon: 'delete', icon: 'delete',
flat: true, flat: true,
@ -167,12 +213,24 @@ const columns = computed(() => [
}), }),
click: (prop) => deleteDms(prop.row.id), click: (prop) => deleteDms(prop.row.id),
}, },
{
component: QBtn,
name: 'open',
external: true,
props: () => ({
icon: 'open_in_new',
flat: true,
color: 'primary',
}),
click: (prop) => open(prop.row.url),
},
], ],
}, },
]); ]);
function setData(data) { function setData(data) {
const newData = data.map((value) => value.dms); const newData = data.map((value) => value.dms || value);
newData.sort((a, b) => new Date(b.created) - new Date(a.created));
rows.value = newData; rows.value = newData;
} }
@ -186,7 +244,7 @@ function deleteDms(dmsFk) {
}, },
}) })
.onOk(async () => { .onOk(async () => {
await axios.post(`${$props.model}/${dmsFk}/removeFile`); await axios.post(`${$props.deleteModel ?? $props.model}/${dmsFk}/removeFile`);
const index = rows.value.findIndex((row) => row.id == dmsFk); const index = rows.value.findIndex((row) => row.id == dmsFk);
rows.value.splice(index, 1); rows.value.splice(index, 1);
}); });
@ -206,84 +264,106 @@ function parseDms(data) {
} }
return data; return data;
} }
async function open(url) {
window.open(url).focus();
}
function shouldRenderButton(button, isExternal = false) {
if (button.name == 'download') return true;
return button.external === isExternal;
}
</script> </script>
<template> <template>
<FetchData <VnPaginate
ref="dmsRef" ref="dmsRef"
:data-key="$props.model"
:url="$props.model" :url="$props.model"
:filter="dmsFilter" :filter="dmsFilter"
:where="{ [$props.filter]: route.params.id }" :order="['dmsFk DESC']"
:auto-load="true"
@on-fetch="setData" @on-fetch="setData"
auto-load
/>
<QTable
:columns="columns"
:rows="rows"
class="full-width q-mt-md"
hide-bottom
row-key="clientFk"
:grid="$q.screen.lt.sm"
> >
<template #body-cell="props"> <template #body>
<QTd :props="props"> <QTable
<QTr :props="props"> :columns="columns"
<component :rows="rows"
v-if="props.col.component" class="full-width q-mt-md"
:is="props.col.component" hide-bottom
v-bind="props.col.props && props.col.props(props)" row-key="clientFk"
> :grid="$q.screen.lt.sm"
<span >
v-if="props.col.component == 'span'" <template #body-cell="props">
style="white-space: wrap" <QTd :props="props">
>{{ props.value }}</span <QTr :props="props">
> <component
</component> v-if="props.col.component"
</QTr> :is="props.col.component"
v-bind="props.col.props && props.col.props(props)"
<div class="flex justify-center" v-if="props.col.name == 'options'"> >
<div v-for="button of props.col.components" :key="button.id"> <span
<component v-if="props.col.component == 'span'"
:is="button.component" style="white-space: wrap"
v-bind="button.props(props)" >{{ props.value }}</span
@click="button.click(props)"
/>
</div>
</div>
</QTd>
</template>
<template #item="props">
<div class="q-pa-xs col-xs-12 col-sm-6 grid-style-transition">
<QCard
bordered
flat
@keyup.ctrl.enter.stop="claimDevelopmentForm?.saveChanges()"
>
<QSeparator />
<QList dense>
<QItem v-for="col in props.cols" :key="col.name">
<div v-if="col.name != 'options'" class="row">
<span class="labelColor">{{ col.label }}:</span>
<span>{{ col.value }}</span>
</div>
<div v-if="col.name == 'options'" class="row">
<div
v-for="button of col.components"
:key="button.id"
class="row"
> >
<component </component>
:is="button.component" </QTr>
v-bind="button.props(col)"
@click="button.click(col)" <div class="row no-wrap" v-if="props.col.name == 'options'">
/> <div v-for="button of props.col.components" :key="button.id">
</div> <component
v-if="
shouldRenderButton(button, props.row.isDocuware)
"
:is="button.component"
v-bind="button.props(props)"
@click="button.click(props)"
/>
</div> </div>
</QItem> </div>
</QList> </QTd>
</QCard> </template>
</div> <template #item="props">
<div class="q-pa-xs col-xs-12 col-sm-6 grid-style-transition">
<QCard
bordered
flat
@keyup.ctrl.enter.stop="claimDevelopmentForm?.saveChanges()"
>
<QSeparator />
<QList dense>
<QItem v-for="col in props.cols" :key="col.name">
<div v-if="col.name != 'options'" class="row">
<span class="labelColor">{{ col.label }}:</span>
<span>{{ col.value }}</span>
</div>
<div v-if="col.name == 'options'" class="row">
<div
v-for="button of col.components"
:key="button.id"
class="row"
>
<component
v-if="
shouldRenderButton(
button.name,
props.row.isDocuware
)
"
:is="button.component"
v-bind="button.props(col)"
@click="button.click(col)"
/>
</div>
</div>
</QItem>
</QList>
</QCard>
</div>
</template>
</QTable>
</template> </template>
</QTable> </VnPaginate>
<QDialog v-model="formDialog.show"> <QDialog v-model="formDialog.show">
<VnDms <VnDms
:model="updateModel ?? model" :model="updateModel ?? model"

View File

@ -1030,7 +1030,7 @@ en:
ticketCreated: Created ticketCreated: Created
created: Created created: Created
isChargedToMana: Charged to mana isChargedToMana: Charged to mana
hasToPickUp: Has to pick Up pickup: Type of pickup
dmsFk: Document ID dmsFk: Document ID
text: Description text: Description
claimStateFk: Claim State claimStateFk: Claim State
@ -1069,7 +1069,7 @@ es:
ticketCreated: Creado ticketCreated: Creado
created: Creado created: Creado
isChargedToMana: Cargado a maná isChargedToMana: Cargado a maná
hasToPickUp: Se debe recoger pickup: Se debe recoger
dmsFk: ID documento dmsFk: ID documento
text: Descripción text: Descripción
claimStateFk: Estado de la reclamación claimStateFk: Estado de la reclamación

View File

@ -110,7 +110,7 @@ async function paginate() {
if (!arrayData.hasMoreData.value) { if (!arrayData.hasMoreData.value) {
if (store.userParamsChanged) arrayData.hasMoreData.value = true; if (store.userParamsChanged) arrayData.hasMoreData.value = true;
store.userParamsChanged = false; store.userParamsChanged = false;
isLoading.value = false; endPagination();
return; return;
} }
@ -120,12 +120,14 @@ async function paginate() {
pagination.value.sortBy = sortBy; pagination.value.sortBy = sortBy;
pagination.value.descending = descending; pagination.value.descending = descending;
isLoading.value = false; endPagination();
}
function endPagination() {
isLoading.value = false;
emit('onFetch', store.data); emit('onFetch', store.data);
emit('onPaginate'); emit('onPaginate');
} }
async function onLoad(index, done) { async function onLoad(index, done) {
if (!store.data) { if (!store.data) {
return done(); return done();
@ -188,6 +190,12 @@ async function onLoad(index, done) {
<QSpinner color="orange" size="md" /> <QSpinner color="orange" size="md" />
</div> </div>
</QInfiniteScroll> </QInfiniteScroll>
<div
v-if="!isLoading && arrayData.hasMoreData"
class="w-full flex justify-center q-mt-md"
>
<QBtn color="primary" :label="t('Load more data')" @click="paginate()" />
</div>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -204,4 +212,5 @@ async function onLoad(index, done) {
es: es:
No data to display: Sin datos que mostrar No data to display: Sin datos que mostrar
No results found: No se han encontrado resultados No results found: No se han encontrado resultados
Load more data: Cargar más resultados
</i18n> </i18n>

View File

@ -76,7 +76,7 @@ const removeNode = (node) => {
notify(t('department.departmentRemoved'), 'positive'); notify(t('department.departmentRemoved'), 'positive');
await fetchNodeLeaves(parentFk); await fetchNodeLeaves(parentFk);
} catch (err) { } catch (err) {
console.log('Error removing department'); console.error('Error removing department');
} }
}); });
}; };

View File

@ -1,11 +1,11 @@
import { useSession } from 'src/composables/useSession'; import { useSession } from 'src/composables/useSession';
import { getUrl } from './getUrl'; import { getUrl } from './getUrl';
const {getTokenMultimedia} = useSession(); const { getTokenMultimedia } = useSession();
const token = getTokenMultimedia(); const token = getTokenMultimedia();
export async function downloadFile(dmsId) { export async function downloadFile(id, model = 'dms', urlPath = '/downloadFile', url) {
let appUrl = await getUrl('', 'lilium'); let appUrl = await getUrl('', 'lilium');
appUrl = appUrl.replace('/#/', ''); appUrl = appUrl.replace('/#/', '');
window.open(`${appUrl}/api/dms/${dmsId}/downloadFile?access_token=${token}`); window.open(url ?? `${appUrl}/api/${model}/${id}${urlPath}?access_token=${token}`);
} }

View File

@ -1,5 +1,5 @@
import { onMounted, ref, computed } from 'vue'; import { onMounted, ref, computed } from 'vue';
import { useRouter, useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import axios from 'axios'; import axios from 'axios';
import { useArrayDataStore } from 'stores/useArrayDataStore'; import { useArrayDataStore } from 'stores/useArrayDataStore';
import { buildFilter } from 'filters/filterPanel'; import { buildFilter } from 'filters/filterPanel';
@ -15,7 +15,6 @@ export function useArrayData(key, userOptions) {
const store = arrayDataStore.get(key); const store = arrayDataStore.get(key);
const hasMoreData = ref(false); const hasMoreData = ref(false);
const router = useRouter();
const route = useRoute(); const route = useRoute();
let canceller = null; let canceller = null;
@ -98,14 +97,14 @@ export function useArrayData(key, userOptions) {
const { limit } = filter; const { limit } = filter;
hasMoreData.value = response.data.length === limit; hasMoreData.value = response.data.length >= limit;
if (append) { if (append) {
if (!store.data) store.data = []; if (!store.data) store.data = [];
for (const row of response.data) store.data.push(row); for (const row of response.data) store.data.push(row);
} else { } else {
store.data = response.data; store.data = response.data;
if (!document.querySelectorAll('[role="dialog"]')) if (!document.querySelectorAll('[role="dialog"]').length)
updateRouter && updateStateParams(); updateRouter && updateStateParams();
} }
@ -188,11 +187,15 @@ export function useArrayData(key, userOptions) {
if (store.userParams && Object.keys(store.userParams).length !== 0) if (store.userParams && Object.keys(store.userParams).length !== 0)
query.params = JSON.stringify(store.userParams); query.params = JSON.stringify(store.userParams);
if (router) const url = new URL(window.location.href);
router.replace({ const { hash: currentHash } = url;
path: route.path, const [currentRoute] = currentHash.split('?');
query: query,
}); const params = new URLSearchParams();
for (const param in query) params.append(param, query[param]);
url.hash = currentRoute + '?' + params.toString();
window.history.pushState({}, '', url.hash);
} }
const totalRows = computed(() => (store.data && store.data.length) || 0); const totalRows = computed(() => (store.data && store.data.length) || 0);

View File

@ -91,6 +91,8 @@ export default {
log: 'Logs', log: 'Logs',
parkingList: 'Parkings list', parkingList: 'Parkings list',
}, },
created: 'Created',
worker: 'Worker',
}, },
errors: { errors: {
statusUnauthorized: 'Access denied', statusUnauthorized: 'Access denied',
@ -544,6 +546,7 @@ export default {
assignedTo: 'Assigned', assignedTo: 'Assigned',
attendedBy: 'Attended by', attendedBy: 'Attended by',
created: 'Created', created: 'Created',
pickup: 'Pickup',
state: 'State', state: 'State',
details: 'Details', details: 'Details',
item: 'Item', item: 'Item',
@ -565,13 +568,19 @@ export default {
responsible: 'Responsible', responsible: 'Responsible',
worker: 'Worker', worker: 'Worker',
redelivery: 'Redelivery', redelivery: 'Redelivery',
null: 'No',
agency: 'Agency',
delivery: 'Delivery',
}, },
basicData: { basicData: {
customer: 'Customer', customer: 'Customer',
assignedTo: 'Assigned', assignedTo: 'Assigned',
created: 'Created', created: 'Created',
state: 'State', state: 'State',
picked: 'Picked', pickup: 'Pickup',
null: 'No',
agency: 'Agency',
delivery: 'Delivery',
}, },
photo: { photo: {
fileDescription: 'Claim id {claimId} from client {clientName} id {clientId}', fileDescription: 'Claim id {claimId} from client {clientName} id {clientId}',
@ -857,6 +866,7 @@ export default {
basicData: 'Basic data', basicData: 'Basic data',
notes: 'Notes', notes: 'Notes',
pda: 'PDA', pda: 'PDA',
dms: 'My documentation',
notifications: 'Notifications', notifications: 'Notifications',
pbx: 'Private Branch Exchange', pbx: 'Private Branch Exchange',
log: 'Log', log: 'Log',

View File

@ -91,6 +91,8 @@ export default {
log: 'Historial', log: 'Historial',
parkingList: 'Listado de parkings', parkingList: 'Listado de parkings',
}, },
created: 'Fecha creación',
worker: 'Trabajador',
}, },
errors: { errors: {
statusUnauthorized: 'Acceso denegado', statusUnauthorized: 'Acceso denegado',
@ -543,6 +545,7 @@ export default {
assignedTo: 'Asignada a', assignedTo: 'Asignada a',
attendedBy: 'Atendida por', attendedBy: 'Atendida por',
created: 'Creada', created: 'Creada',
pickup: 'Recogida',
state: 'Estado', state: 'Estado',
details: 'Detalles', details: 'Detalles',
item: 'Artículo', item: 'Artículo',
@ -564,13 +567,19 @@ export default {
responsible: 'Responsable', responsible: 'Responsable',
worker: 'Trabajador', worker: 'Trabajador',
redelivery: 'Devolución', redelivery: 'Devolución',
null: 'No',
agency: 'Agencia',
delivery: 'Reparto',
}, },
basicData: { basicData: {
customer: 'Cliente', customer: 'Cliente',
assignedTo: 'Asignada a', assignedTo: 'Asignada a',
created: 'Creada', created: 'Creada',
state: 'Estado', state: 'Estado',
picked: 'Recogida', pickup: 'Recogida',
null: 'No',
agency: 'Agencia',
delivery: 'Reparto',
}, },
photo: { photo: {
fileDescription: fileDescription:
@ -856,6 +865,7 @@ export default {
basicData: 'Datos básicos', basicData: 'Datos básicos',
notes: 'Notas', notes: 'Notas',
pda: 'PDA', pda: 'PDA',
dms: 'Mi documentación',
notifications: 'Notificaciones', notifications: 'Notificaciones',
pbx: 'Centralita', pbx: 'Centralita',
log: 'Historial', log: 'Historial',

View File

@ -9,6 +9,7 @@ import VnRow from 'components/ui/VnRow.vue';
import VnInput from 'src/components/common/VnInput.vue'; import VnInput from 'src/components/common/VnInput.vue';
import VnInputDate from 'components/common/VnInputDate.vue'; import VnInputDate from 'components/common/VnInputDate.vue';
import axios from 'axios';
import { useSession } from 'src/composables/useSession'; import { useSession } from 'src/composables/useSession';
const route = useRoute(); const route = useRoute();
@ -24,7 +25,7 @@ const claimFilter = {
'workerFk', 'workerFk',
'claimStateFk', 'claimStateFk',
'packages', 'packages',
'hasToPickUp', 'pickup',
], ],
include: [ include: [
{ {
@ -50,6 +51,20 @@ function setClaimStates(data) {
claimStates.value = data; claimStates.value = data;
claimStatesCopy.value = data; claimStatesCopy.value = data;
} }
let optionsList;
async function getEnumValues() {
optionsList = [{ id: null, description: t('claim.basicData.null') }];
const { data } = await axios.get(`Applications/get-enum-values`, {
params: {
schema: 'vn',
table: 'claim',
column: 'pickup',
},
});
for (let value of data)
optionsList.push({ id: value, description: t(`claim.basicData.${value}`) });
}
getEnumValues();
const workerFilter = { const workerFilter = {
options: workers, options: workers,
@ -168,13 +183,19 @@ const statesFilter = {
type="number" type="number"
/> />
</div> </div>
</VnRow>
<VnRow class="row q-gutter-md q-mb-md">
<div class="col"> <div class="col">
<QCheckbox <QSelect
v-model="data.hasToPickUp" v-model="data.pickup"
:label="t('claim.basicData.picked')" :options="optionsList"
/> option-value="id"
option-label="description"
emit-value
:label="t('claim.basicData.pickup')"
map-options
use-input
:input-debounce="0"
>
</QSelect>
</div> </div>
</VnRow> </VnRow>
</template> </template>

View File

@ -220,10 +220,9 @@ function openDialog(dmsId) {
/> />
</template> </template>
</VnLv> </VnLv>
<QCheckbox <VnLv
:label="t('claim.basicData.picked')" :label="t('claim.summary.pickup')"
v-model="claim.hasToPickUp" :value="t(`claim.summary.${claim.pickup}`)"
:disable="true"
/> />
</QCard> </QCard>
<QCard class="vn-three"> <QCard class="vn-three">

View File

@ -63,7 +63,7 @@ const removeDepartment = () => {
router.push({ name: 'WorkerDepartment' }); router.push({ name: 'WorkerDepartment' });
notify('department.departmentRemoved', 'positive'); notify('department.departmentRemoved', 'positive');
} catch (err) { } catch (err) {
console.log('Error removing department'); console.error('Error removing department');
} }
}); });
}; };

View File

@ -32,6 +32,13 @@ const invoiceInFormRef = ref();
const expensesRef = ref(); const expensesRef = ref();
const newExpenseRef = ref(); const newExpenseRef = ref();
defineProps({
actionIcon: {
type: String,
default: 'add',
},
});
const columns = computed(() => [ const columns = computed(() => [
{ {
name: 'expense', name: 'expense',
@ -207,17 +214,16 @@ async function addExpense() {
@click.stop="value = null" @click.stop="value = null"
class="cursor-pointer" class="cursor-pointer"
/> />
<QBtn <QIcon
padding="xs" @click.stop.prevent="newExpenseRef.show()"
round :name="actionIcon"
flat size="xs"
icon="add_circle" class="default-icon"
@click.stop="newExpenseRef.show()"
> >
<QTooltip> <QTooltip>
{{ t('Create expense') }} {{ t('Create expense') }}
</QTooltip> </QTooltip>
</QBtn> </QIcon>
</template> </template>
</VnSelectFilter> </VnSelectFilter>
</QTd> </QTd>
@ -470,6 +476,11 @@ async function addExpense() {
.q-item { .q-item {
min-height: 0; min-height: 0;
} }
.default-icon {
cursor: pointer;
border-radius: 50px;
background-color: $primary;
}
</style> </style>
<i18n> <i18n>
es: es:

View File

@ -0,0 +1,15 @@
<script setup>
import VnDmsList from 'src/components/common/VnDmsList.vue';
import { useRoute } from 'vue-router';
const route = useRoute();
</script>
<template>
<VnDmsList
:model="`WorkerDms/${route.params.id}/filter`"
update-model="Workers"
delete-model="WorkerDms"
download-model="WorkerDms"
default-dms-code="hhrrData"
filter="worker"
/>
</template>

View File

@ -19,6 +19,7 @@ export default {
'WorkerNotificationsManager', 'WorkerNotificationsManager',
'WorkerPBX', 'WorkerPBX',
'WorkerLog', 'WorkerLog',
'WorkerDms',
], ],
departmentCard: ['BasicData'], departmentCard: ['BasicData'],
}, },
@ -127,6 +128,15 @@ export default {
}, },
component: () => import('src/pages/Worker/Card/WorkerPBX.vue'), component: () => import('src/pages/Worker/Card/WorkerPBX.vue'),
}, },
{
name: 'WorkerDms',
path: 'dms',
meta: {
title: 'dms',
icon: 'cloud_upload',
},
component: () => import('src/pages/Worker/Card/WorkerDms.vue'),
},
{ {
name: 'WorkerLog', name: 'WorkerLog',
path: 'log', path: 'log',

View File

@ -36,7 +36,7 @@ describe('VnSearchBar', () => {
const checkCardListAndUrl = (expectedLength) => { const checkCardListAndUrl = (expectedLength) => {
cy.get(cardList).then(($cardList) => { cy.get(cardList).then(($cardList) => {
expect($cardList.find('.q-card').length).to.equal(expectedLength); expect($cardList.find('.q-card').length).to.equal(expectedLength);
cy.url().then((currentUrl) => expect(currentUrl).to.equal(url)); cy.url().then((currentUrl) => expect(currentUrl).to.contain(url));
}); });
}; };
}); });

View File

@ -38,10 +38,10 @@ describe('VnLog', () => {
action: 'update', action: 'update',
changedModel: 'Claim', changedModel: 'Claim',
oldInstance: { oldInstance: {
hasToPickUp: false, pickup: null,
}, },
newInstance: { newInstance: {
hasToPickUp: true, pickup: 'agency',
}, },
creationDate: '2023-09-18T12:25:34.000Z', creationDate: '2023-09-18T12:25:34.000Z',
changedModelId: '1', changedModelId: '1',

View File

@ -0,0 +1,31 @@
import { describe, expect, it, beforeAll } from 'vitest';
import { axios } from 'app/test/vitest/helper';
import { useArrayData } from 'composables/useArrayData';
describe('useArrayData', () => {
let arrayData;
beforeAll(() => {
axios.get.mockResolvedValue({ data: [] });
arrayData = useArrayData('InvoiceIn', { url: 'invoice-in/list' });
Object.defineProperty(window.location, 'href', {
writable: true,
value: 'localhost:9000/invoice-in/list',
});
// Mock the window.history.pushState method within useArrayData
window.history.pushState = (data, title, url) => (window.location.href = url);
// Mock the URL constructor within useArrayData
global.URL = class URL {
constructor(url) {
this.hash = url.split('localhost:9000/')[1];
}
};
});
it('should add the params to the url', async () => {
arrayData.store.userParams = { supplierFk: 2 };
arrayData.updateStateParams();
expect(window.location.href).contain('params=%7B%22supplierFk%22%3A2%7D');
});
});