forked from verdnatura/salix-front
parent
818356465b
commit
34e5814b06
|
@ -48,24 +48,13 @@ onMounted(() => stateStore.setMounted());
|
||||||
<div id="searchbar"></div>
|
<div id="searchbar"></div>
|
||||||
<q-space></q-space>
|
<q-space></q-space>
|
||||||
<div class="q-pl-sm q-gutter-sm row items-center no-wrap">
|
<div class="q-pl-sm q-gutter-sm row items-center no-wrap">
|
||||||
<div id="header-actions"></div>
|
<div id="actions-prepend"></div>
|
||||||
<q-btn id="pinnedModules" icon="apps" flat dense rounded>
|
<q-btn id="pinnedModules" icon="apps" flat dense rounded>
|
||||||
<q-tooltip bottom>
|
<q-tooltip bottom>
|
||||||
{{ t('globals.pinnedModules') }}
|
{{ t('globals.pinnedModules') }}
|
||||||
</q-tooltip>
|
</q-tooltip>
|
||||||
<PinnedModules />
|
<PinnedModules />
|
||||||
</q-btn>
|
</q-btn>
|
||||||
<q-btn
|
|
||||||
flat
|
|
||||||
@click="stateStore.toggleRightDrawer()"
|
|
||||||
round
|
|
||||||
dense
|
|
||||||
icon="menu"
|
|
||||||
>
|
|
||||||
<q-tooltip bottom anchor="bottom right">
|
|
||||||
{{ t('globals.collapseMenu') }}
|
|
||||||
</q-tooltip>
|
|
||||||
</q-btn>
|
|
||||||
<q-btn rounded dense flat no-wrap id="user">
|
<q-btn rounded dense flat no-wrap id="user">
|
||||||
<q-avatar size="lg">
|
<q-avatar size="lg">
|
||||||
<q-img
|
<q-img
|
||||||
|
@ -79,6 +68,7 @@ onMounted(() => stateStore.setMounted());
|
||||||
</q-tooltip>
|
</q-tooltip>
|
||||||
<UserPanel />
|
<UserPanel />
|
||||||
</q-btn>
|
</q-btn>
|
||||||
|
<div id="actions-append"></div>
|
||||||
</div>
|
</div>
|
||||||
</q-toolbar>
|
</q-toolbar>
|
||||||
</q-header>
|
</q-header>
|
||||||
|
|
|
@ -86,6 +86,7 @@ async function paginate() {
|
||||||
|
|
||||||
if (!props.url) return;
|
if (!props.url) return;
|
||||||
|
|
||||||
|
isLoading.value = true;
|
||||||
await arrayData.loadMore();
|
await arrayData.loadMore();
|
||||||
|
|
||||||
if (!arrayData.hasMoreData.value) {
|
if (!arrayData.hasMoreData.value) {
|
||||||
|
@ -121,7 +122,7 @@ async function onLoad(...params) {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="column items-center">
|
<div>
|
||||||
<div
|
<div
|
||||||
v-if="store.data && store.data.length === 0 && !isLoading"
|
v-if="store.data && store.data.length === 0 && !isLoading"
|
||||||
class="info-row q-pa-md text-center"
|
class="info-row q-pa-md text-center"
|
||||||
|
@ -150,27 +151,18 @@ async function onLoad(...params) {
|
||||||
</q-card>
|
</q-card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<q-infinite-scroll
|
<q-infinite-scroll v-if="store.data" @load="onLoad" :offset="offset">
|
||||||
v-if="store.data"
|
|
||||||
@load="onLoad"
|
|
||||||
:offset="offset"
|
|
||||||
class="column items-center"
|
|
||||||
>
|
|
||||||
<div v-if="store" class="card-list q-gutter-y-md">
|
|
||||||
<slot name="body" :rows="store.data"></slot>
|
<slot name="body" :rows="store.data"></slot>
|
||||||
<div v-if="isLoading" class="info-row q-pa-md text-center">
|
<div v-if="isLoading" class="info-row q-pa-md text-center">
|
||||||
<q-spinner color="orange" size="md" />
|
<q-spinner color="orange" size="md" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</q-infinite-scroll>
|
</q-infinite-scroll>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.card-list {
|
// .q-infinite-scroll {
|
||||||
width: 100%;
|
// width: 100%;
|
||||||
max-width: 60em;
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
.info-row {
|
.info-row {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ export function useArrayData(key, userOptions) {
|
||||||
Object.assign(store.filter, filter);
|
Object.assign(store.filter, filter);
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
filter: JSON.stringify(filter),
|
filter: JSON.stringify(store.filter),
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.assign(params, store.userParams);
|
Object.assign(params, store.userParams);
|
||||||
|
|
|
@ -242,6 +242,7 @@ export default {
|
||||||
basicData: 'Basic Data',
|
basicData: 'Basic Data',
|
||||||
rma: 'RMA',
|
rma: 'RMA',
|
||||||
photos: 'Photos',
|
photos: 'Photos',
|
||||||
|
log: 'Audit logs',
|
||||||
},
|
},
|
||||||
list: {
|
list: {
|
||||||
customer: 'Customer',
|
customer: 'Customer',
|
||||||
|
|
|
@ -241,6 +241,7 @@ export default {
|
||||||
basicData: 'Datos básicos',
|
basicData: 'Datos básicos',
|
||||||
rma: 'RMA',
|
rma: 'RMA',
|
||||||
photos: 'Fotos',
|
photos: 'Fotos',
|
||||||
|
log: 'Registros de auditoría',
|
||||||
},
|
},
|
||||||
list: {
|
list: {
|
||||||
customer: 'Cliente',
|
customer: 'Cliente',
|
||||||
|
|
|
@ -2,26 +2,13 @@
|
||||||
import { useQuasar } from 'quasar';
|
import { useQuasar } from 'quasar';
|
||||||
import Navbar from 'src/components/NavBar.vue';
|
import Navbar from 'src/components/NavBar.vue';
|
||||||
|
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
|
||||||
|
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
const stateStore = useStateStore();
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<q-layout view="hHh LpR fFf">
|
<q-layout view="hHh LpR fFf">
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<router-view></router-view>
|
<router-view></router-view>
|
||||||
<q-drawer
|
|
||||||
v-model="stateStore.rightDrawer"
|
|
||||||
side="right"
|
|
||||||
:width="256"
|
|
||||||
:persistent="false"
|
|
||||||
>
|
|
||||||
<q-scroll-area class="fit text-grey-8">
|
|
||||||
<div id="rightPanel"></div>
|
|
||||||
</q-scroll-area>
|
|
||||||
</q-drawer>
|
|
||||||
<q-footer v-if="quasar.platform.is.mobile"></q-footer>
|
<q-footer v-if="quasar.platform.is.mobile"></q-footer>
|
||||||
</q-layout>
|
</q-layout>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -81,22 +81,47 @@ const statesFilter = {
|
||||||
/>
|
/>
|
||||||
<fetch-data url="ClaimStates" @on-fetch="setClaimStates" auto-load />
|
<fetch-data url="ClaimStates" @on-fetch="setClaimStates" auto-load />
|
||||||
|
|
||||||
<div class="container">
|
<div class="column items-center">
|
||||||
<q-card>
|
<q-card>
|
||||||
<form-model :url="`Claims/${route.params.id}`" :filter="claimFilter" model="claim">
|
<form-model
|
||||||
|
:url="`Claims/${route.params.id}`"
|
||||||
|
:filter="claimFilter"
|
||||||
|
model="claim"
|
||||||
|
>
|
||||||
<template #form="{ data, validate, filter }">
|
<template #form="{ data, validate, filter }">
|
||||||
<div class="row q-gutter-md q-mb-md">
|
<div class="row q-gutter-md q-mb-md">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<q-input v-model="data.client.name" :label="t('claim.basicData.customer')" disable />
|
<q-input
|
||||||
|
v-model="data.client.name"
|
||||||
|
:label="t('claim.basicData.customer')"
|
||||||
|
disable
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<q-input v-model="data.created" mask="####-##-##" fill-mask="_" autofocus>
|
<q-input
|
||||||
|
v-model="data.created"
|
||||||
|
mask="####-##-##"
|
||||||
|
fill-mask="_"
|
||||||
|
autofocus
|
||||||
|
>
|
||||||
<template #append>
|
<template #append>
|
||||||
<q-icon name="event" class="cursor-pointer">
|
<q-icon name="event" class="cursor-pointer">
|
||||||
<q-popup-proxy cover transition-show="scale" transition-hide="scale">
|
<q-popup-proxy
|
||||||
<q-date v-model="data.created" mask="YYYY-MM-DD">
|
cover
|
||||||
|
transition-show="scale"
|
||||||
|
transition-hide="scale"
|
||||||
|
>
|
||||||
|
<q-date
|
||||||
|
v-model="data.created"
|
||||||
|
mask="YYYY-MM-DD"
|
||||||
|
>
|
||||||
<div class="row items-center justify-end">
|
<div class="row items-center justify-end">
|
||||||
<q-btn v-close-popup label="Close" color="primary" flat />
|
<q-btn
|
||||||
|
v-close-popup
|
||||||
|
label="Close"
|
||||||
|
color="primary"
|
||||||
|
flat
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</q-date>
|
</q-date>
|
||||||
</q-popup-proxy>
|
</q-popup-proxy>
|
||||||
|
@ -116,7 +141,9 @@ const statesFilter = {
|
||||||
:label="t('claim.basicData.assignedTo')"
|
:label="t('claim.basicData.assignedTo')"
|
||||||
map-options
|
map-options
|
||||||
use-input
|
use-input
|
||||||
@filter="(value, update) => filter(value, update, workerFilter)"
|
@filter="
|
||||||
|
(value, update) => filter(value, update, workerFilter)
|
||||||
|
"
|
||||||
:rules="validate('claim.claimStateFk')"
|
:rules="validate('claim.claimStateFk')"
|
||||||
:input-debounce="0"
|
:input-debounce="0"
|
||||||
>
|
>
|
||||||
|
@ -141,7 +168,9 @@ const statesFilter = {
|
||||||
:label="t('claim.basicData.state')"
|
:label="t('claim.basicData.state')"
|
||||||
map-options
|
map-options
|
||||||
use-input
|
use-input
|
||||||
@filter="(value, update) => filter(value, update, statesFilter)"
|
@filter="
|
||||||
|
(value, update) => filter(value, update, statesFilter)
|
||||||
|
"
|
||||||
:rules="validate('claim.claimStateFk')"
|
:rules="validate('claim.claimStateFk')"
|
||||||
:input-debounce="0"
|
:input-debounce="0"
|
||||||
>
|
>
|
||||||
|
@ -166,7 +195,10 @@ const statesFilter = {
|
||||||
</div>
|
</div>
|
||||||
<div class="row q-gutter-md q-mb-md">
|
<div class="row q-gutter-md q-mb-md">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<q-checkbox v-model="data.hasToPickUp" :label="t('claim.basicData.picked')" />
|
<q-checkbox
|
||||||
|
v-model="data.hasToPickUp"
|
||||||
|
:label="t('claim.basicData.picked')"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -176,12 +208,8 @@ const statesFilter = {
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.container {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.q-card {
|
.q-card {
|
||||||
width: 800px;
|
width: 100%;
|
||||||
|
max-width: 60em;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,120 +1,190 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useQuasar } from 'quasar';
|
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { useSession } from 'src/composables/useSession';
|
import { useSession } from 'src/composables/useSession';
|
||||||
import FetchData from 'components/FetchData.vue';
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
|
import TeleportSlot from 'components/ui/TeleportSlot.vue';
|
||||||
|
import Paginate from 'src/components/PaginateData.vue';
|
||||||
|
import ClaimLogFilter from './ClaimLogFilter.vue';
|
||||||
|
|
||||||
import { toDate } from 'src/filters';
|
import { toDate } from 'src/filters';
|
||||||
|
|
||||||
// const quasar = useQuasar();
|
const stateStore = useStateStore();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const session = useSession();
|
const session = useSession();
|
||||||
const token = session.getToken();
|
const token = session.getToken();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const filter = {
|
const columns = [
|
||||||
include: [
|
|
||||||
{
|
{
|
||||||
relation: 'user',
|
name: 'property',
|
||||||
scope: {
|
label: 'Property',
|
||||||
fields: ['name'],
|
field: (row) => t(`properties.${row.property}`),
|
||||||
include: { relation: 'worker', scope: { fields: ['id'] } },
|
align: 'left',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'before',
|
||||||
|
label: 'Before',
|
||||||
|
field: (row) => formatValue(row.before),
|
||||||
},
|
},
|
||||||
],
|
{
|
||||||
where: {
|
name: 'after',
|
||||||
originFk: route.params.id,
|
label: 'After',
|
||||||
|
field: (row) => formatValue(row.after),
|
||||||
},
|
},
|
||||||
};
|
];
|
||||||
|
|
||||||
const logs = ref();
|
function formatValue(value) {
|
||||||
function onFetch(data) {
|
if (typeof value === 'boolean') {
|
||||||
//rows.value = data;
|
return value ? t('Yes') : t('No');
|
||||||
logs.value = [];
|
|
||||||
for (const row of data) {
|
|
||||||
const changes = [];
|
|
||||||
const oldInstance = row.oldInstance;
|
|
||||||
const newInstance = row.newInstance;
|
|
||||||
for (const property in oldInstance) {
|
|
||||||
let oldValue = oldInstance[property];
|
|
||||||
let newValue = newInstance[property];
|
|
||||||
|
|
||||||
// if (isNaN(oldValue) && !isNaN(Date.parse(oldValue))) {
|
|
||||||
// oldValue = toDate(oldValue);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (isNaN(newValue) && !isNaN(Date.parse(newValue))) {
|
|
||||||
// newValue = toDate(newValue);
|
|
||||||
// }
|
|
||||||
|
|
||||||
const change = {
|
|
||||||
property: property,
|
|
||||||
value: `${oldValue} -> ${newValue}`,
|
|
||||||
};
|
|
||||||
|
|
||||||
changes.push(change);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
logs.value.push({
|
if (isNaN(value) && !isNaN(Date.parse(value))) {
|
||||||
model: row.changedModel,
|
return toDate(value);
|
||||||
created: row.creationDate,
|
|
||||||
userFk: row.userFk,
|
|
||||||
changes: changes,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (value === undefined) {
|
||||||
|
return t('Nothing');
|
||||||
|
}
|
||||||
|
|
||||||
|
return `"${value}"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function actionColor(action) {
|
||||||
|
if (action === 'insert') return 'positive';
|
||||||
|
if (action === 'update') return 'positive';
|
||||||
|
if (action === 'delete') return 'negative';
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<fetch-data url="ClaimLogs" :filter="filter" @on-fetch="onFetch" auto-load />
|
<div class="column items-center">
|
||||||
|
<q-timeline class="q-pa-md">
|
||||||
<div class="q-px-lg">
|
<q-timeline-entry heading tag="h4"> {{ t('Audit logs') }} </q-timeline-entry>
|
||||||
<q-timeline>
|
<Paginate
|
||||||
<q-timeline-entry heading> Logs </q-timeline-entry>
|
data-key="ClaimLogs"
|
||||||
<template v-for="log of logs" :key="log.id">
|
:url="`Claims/${route.params.id}/logs`"
|
||||||
|
order="id DESC"
|
||||||
|
:offset="100"
|
||||||
|
:limit="5"
|
||||||
|
auto-load
|
||||||
|
>
|
||||||
|
<template #body="{ rows }">
|
||||||
|
<template v-for="log of rows" :key="log.id">
|
||||||
<q-timeline-entry
|
<q-timeline-entry
|
||||||
:title="t(`models.${log.model}`)"
|
|
||||||
:subtitle="toDate(log.created)"
|
|
||||||
:avatar="`/api/Images/user/160x160/${log.userFk}/download?access_token=${token}`"
|
:avatar="`/api/Images/user/160x160/${log.userFk}/download?access_token=${token}`"
|
||||||
>
|
>
|
||||||
<q-list
|
<template #subtitle>
|
||||||
v-for="change of log.changes"
|
{{ log.userName }} -
|
||||||
:key="change.property"
|
{{
|
||||||
|
toDate(log.created, {
|
||||||
|
dateStyle: 'medium',
|
||||||
|
timeStyle: 'short',
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
</template>
|
||||||
|
<template #title>
|
||||||
|
<q-chip :color="actionColor(log.action)">
|
||||||
|
{{ t(`actions.${log.action}`) }}
|
||||||
|
</q-chip>
|
||||||
|
{{ t(`models.${log.model}`) }}
|
||||||
|
</template>
|
||||||
|
<q-table
|
||||||
|
:rows="log.changes"
|
||||||
|
:columns="columns"
|
||||||
|
row-key="property"
|
||||||
|
hide-pagination
|
||||||
dense
|
dense
|
||||||
style="width: 500px"
|
flat
|
||||||
>
|
>
|
||||||
<q-item>
|
<template #header="props">
|
||||||
<q-item-section>
|
<q-tr :props="props">
|
||||||
<q-item-label caption>
|
<q-th
|
||||||
{{ t(`properties.${change.property}`) }}
|
v-for="col in props.cols"
|
||||||
</q-item-label>
|
:key="col.name"
|
||||||
</q-item-section>
|
:props="props"
|
||||||
<q-item-section>
|
>
|
||||||
<q-item-label>{{ change.value }}</q-item-label>
|
{{ t(col.label) }}
|
||||||
</q-item-section>
|
</q-th>
|
||||||
</q-item>
|
</q-tr>
|
||||||
</q-list>
|
</template>
|
||||||
<!-- <div v-for="change of log.changes" :key="change.property">
|
</q-table>
|
||||||
{{ change.property }}: {{ change.value }}
|
|
||||||
</div> -->
|
|
||||||
</q-timeline-entry>
|
</q-timeline-entry>
|
||||||
</template>
|
</template>
|
||||||
|
</template>
|
||||||
|
</Paginate>
|
||||||
</q-timeline>
|
</q-timeline>
|
||||||
</div>
|
</div>
|
||||||
|
<TeleportSlot to="#actions-append">
|
||||||
|
<div class="row q-gutter-x-sm">
|
||||||
|
<q-btn flat @click="stateStore.toggleRightDrawer()" round dense icon="menu">
|
||||||
|
<q-tooltip bottom anchor="bottom right">
|
||||||
|
{{ t('globals.collapseMenu') }}
|
||||||
|
</q-tooltip>
|
||||||
|
</q-btn>
|
||||||
|
</div>
|
||||||
|
</TeleportSlot>
|
||||||
|
<q-drawer v-model="stateStore.rightDrawer" show-if-above side="right" :width="300">
|
||||||
|
<q-scroll-area class="fit text-grey-8">
|
||||||
|
<ClaimLogFilter data-key="ClaimLogs" />
|
||||||
|
</q-scroll-area>
|
||||||
|
</q-drawer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.q-timeline {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 80em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
<i18n>
|
<i18n>
|
||||||
en:
|
en:
|
||||||
|
actions:
|
||||||
|
insert: Creates
|
||||||
|
update: Updates
|
||||||
|
delete: Deletes
|
||||||
models:
|
models:
|
||||||
Claim: Claim
|
Claim: Claim
|
||||||
|
ClaimDms: Document
|
||||||
|
ClaimBeginning: Claimed Sales
|
||||||
|
ClaimObservation: Observation
|
||||||
properties:
|
properties:
|
||||||
id: ID
|
id: ID
|
||||||
|
claimFk: Claim ID
|
||||||
|
saleFk: Sale ID
|
||||||
|
quantity: Quantity
|
||||||
observation: Observation
|
observation: Observation
|
||||||
|
ticketCreated: Created
|
||||||
|
created: Created
|
||||||
|
isChargedToMana: Charged to mana
|
||||||
|
hasToPickUp: Has to pick Up
|
||||||
|
dmsFk: Document ID
|
||||||
|
text: Description
|
||||||
es:
|
es:
|
||||||
|
Audit logs: Registros de auditoría
|
||||||
|
Property: Propiedad
|
||||||
|
Before: Antes
|
||||||
|
After: Después
|
||||||
|
Yes: Si
|
||||||
|
Nothing: Nada
|
||||||
|
actions:
|
||||||
|
insert: Crea
|
||||||
|
update: Actualiza
|
||||||
|
delete: Elimina
|
||||||
models:
|
models:
|
||||||
Claim: Reclamación
|
Claim: Reclamación
|
||||||
|
ClaimDms: Documento
|
||||||
|
ClaimBeginning: Línea reclamada
|
||||||
|
ClaimObservation: Observación
|
||||||
properties:
|
properties:
|
||||||
id: ID
|
id: ID
|
||||||
|
claimFk: ID reclamación
|
||||||
|
saleFk: ID linea de venta
|
||||||
|
quantity: Cantidad
|
||||||
observation: Observación
|
observation: Observación
|
||||||
|
ticketCreated: Creado
|
||||||
|
created: Creado
|
||||||
|
isChargedToMana: Cargado a maná
|
||||||
|
hasToPickUp: Se debe recoger
|
||||||
|
dmsFk: ID documento
|
||||||
|
text: Descripción
|
||||||
</i18n>
|
</i18n>
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import FetchData from 'components/FetchData.vue';
|
||||||
|
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
const props = defineProps({
|
||||||
|
dataKey: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const workers = ref();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<fetch-data
|
||||||
|
url="Workers/activeWithInheritedRole"
|
||||||
|
:filter="{ where: { role: 'salesPerson' } }"
|
||||||
|
@on-fetch="(data) => (workers = data)"
|
||||||
|
auto-load
|
||||||
|
/>
|
||||||
|
<VnFilterPanel :data-key="props.dataKey" :search-button="true">
|
||||||
|
<template #tags="{ tag, formatFn }">
|
||||||
|
<div class="q-gutter-x-xs">
|
||||||
|
<strong>{{ t(`params.${tag.label}`) }}: </strong>
|
||||||
|
<span>{{ formatFn(tag.value) }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #body="{ params, searchFn }">
|
||||||
|
<q-date
|
||||||
|
v-model="params.created"
|
||||||
|
@update:model-value="searchFn()"
|
||||||
|
dense
|
||||||
|
flat
|
||||||
|
minimal
|
||||||
|
>
|
||||||
|
</q-date>
|
||||||
|
<q-list dense>
|
||||||
|
<q-separator />
|
||||||
|
<q-item>
|
||||||
|
<q-item-section v-if="!workers">
|
||||||
|
<q-skeleton type="QInput" class="full-width" />
|
||||||
|
</q-item-section>
|
||||||
|
<q-item-section v-if="workers">
|
||||||
|
<q-select
|
||||||
|
:label="t('User')"
|
||||||
|
v-model="params.userFk"
|
||||||
|
@update:model-value="searchFn()"
|
||||||
|
:options="workers"
|
||||||
|
option-value="id"
|
||||||
|
option-label="name"
|
||||||
|
emit-value
|
||||||
|
map-options
|
||||||
|
use-input
|
||||||
|
:input-debounce="0"
|
||||||
|
/>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</q-list>
|
||||||
|
</template>
|
||||||
|
</VnFilterPanel>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<i18n>
|
||||||
|
en:
|
||||||
|
params:
|
||||||
|
search: Contains
|
||||||
|
userFk: User
|
||||||
|
created: Created
|
||||||
|
es:
|
||||||
|
params:
|
||||||
|
search: Contiene
|
||||||
|
userFk: Usuario
|
||||||
|
created: Creada
|
||||||
|
User: Usuario
|
||||||
|
</i18n>
|
|
@ -239,7 +239,7 @@ function onDrag() {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<teleport-slot v-if="!quasar.platform.is.mobile" to="#header-actions">
|
<teleport-slot v-if="!quasar.platform.is.mobile" to="#actions-prepend">
|
||||||
<div class="row q-gutter-x-sm">
|
<div class="row q-gutter-x-sm">
|
||||||
<label for="fileInput">
|
<label for="fileInput">
|
||||||
<q-btn
|
<q-btn
|
||||||
|
|
|
@ -84,6 +84,8 @@ async function remove(id) {
|
||||||
@on-fetch="onFetch"
|
@on-fetch="onFetch"
|
||||||
auto-load
|
auto-load
|
||||||
/>
|
/>
|
||||||
|
<div class="column items-center">
|
||||||
|
<div class="list">
|
||||||
<paginate data-key="ClaimRma" url="ClaimRmas">
|
<paginate data-key="ClaimRma" url="ClaimRmas">
|
||||||
<template #body="{ rows }">
|
<template #body="{ rows }">
|
||||||
<q-card class="card">
|
<q-card class="card">
|
||||||
|
@ -134,8 +136,9 @@ async function remove(id) {
|
||||||
</q-card>
|
</q-card>
|
||||||
</template>
|
</template>
|
||||||
</paginate>
|
</paginate>
|
||||||
|
</div>
|
||||||
<teleport-slot v-if="!quasar.platform.is.mobile" to="#header-actions">
|
</div>
|
||||||
|
<teleport-slot v-if="!quasar.platform.is.mobile" to="#actions-prepend">
|
||||||
<div class="row q-gutter-x-sm">
|
<div class="row q-gutter-x-sm">
|
||||||
<q-btn @click="addRow()" icon="add" color="primary" dense rounded>
|
<q-btn @click="addRow()" icon="add" color="primary" dense rounded>
|
||||||
<q-tooltip bottom> {{ t('globals.add') }} </q-tooltip>
|
<q-tooltip bottom> {{ t('globals.add') }} </q-tooltip>
|
||||||
|
@ -152,6 +155,10 @@ async function remove(id) {
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
.list {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 60em;
|
||||||
|
}
|
||||||
.q-toolbar {
|
.q-toolbar {
|
||||||
background-color: $grey-9;
|
background-color: $grey-9;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted, onUnmounted } from 'vue';
|
|
||||||
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';
|
||||||
|
@ -17,9 +16,6 @@ const router = useRouter();
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
onMounted(() => (stateStore.rightDrawer = true));
|
|
||||||
onUnmounted(() => (stateStore.rightDrawer = false));
|
|
||||||
|
|
||||||
function stateColor(code) {
|
function stateColor(code) {
|
||||||
if (code === 'pending') return 'green';
|
if (code === 'pending') return 'green';
|
||||||
if (code === 'managed') return 'orange';
|
if (code === 'managed') return 'orange';
|
||||||
|
@ -48,13 +44,25 @@ function viewSummary(id) {
|
||||||
:info="t('You can search by claim id or customer name')"
|
:info="t('You can search by claim id or customer name')"
|
||||||
/>
|
/>
|
||||||
</teleport-slot>
|
</teleport-slot>
|
||||||
<teleport-slot to="#rightPanel">
|
<teleport-slot to="#actions-append">
|
||||||
<ClaimFilter data-key="ClaimList" />
|
<div class="row q-gutter-x-sm">
|
||||||
|
<q-btn flat @click="stateStore.toggleRightDrawer()" round dense icon="menu">
|
||||||
|
<q-tooltip bottom anchor="bottom right">
|
||||||
|
{{ t('globals.collapseMenu') }}
|
||||||
|
</q-tooltip>
|
||||||
|
</q-btn>
|
||||||
|
</div>
|
||||||
</teleport-slot>
|
</teleport-slot>
|
||||||
<q-page class="q-pa-md">
|
<q-drawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
|
||||||
|
<q-scroll-area class="fit text-grey-8">
|
||||||
|
<ClaimFilter data-key="ClaimList" />
|
||||||
|
</q-scroll-area>
|
||||||
|
</q-drawer>
|
||||||
|
<q-page class="column items-center q-pa-md">
|
||||||
|
<div class="card-list">
|
||||||
<paginate data-key="ClaimList" url="Claims/filter" order="id DESC" auto-load>
|
<paginate data-key="ClaimList" url="Claims/filter" order="id DESC" auto-load>
|
||||||
<template #body="{ rows }">
|
<template #body="{ rows }">
|
||||||
<q-card class="card" v-for="row of rows" :key="row.id">
|
<q-card class="card q-mb-md" v-for="row of rows" :key="row.id">
|
||||||
<q-item
|
<q-item
|
||||||
class="q-pa-none items-start cursor-pointer q-hoverable"
|
class="q-pa-none items-start cursor-pointer q-hoverable"
|
||||||
v-ripple
|
v-ripple
|
||||||
|
@ -71,13 +79,17 @@ function viewSummary(id) {
|
||||||
<q-item-label caption>
|
<q-item-label caption>
|
||||||
{{ t('claim.list.customer') }}
|
{{ t('claim.list.customer') }}
|
||||||
</q-item-label>
|
</q-item-label>
|
||||||
<q-item-label>{{ row.clientName }}</q-item-label>
|
<q-item-label>
|
||||||
|
{{ row.clientName }}
|
||||||
|
</q-item-label>
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
<q-item-section>
|
<q-item-section>
|
||||||
<q-item-label caption>
|
<q-item-label caption>
|
||||||
{{ t('claim.list.assignedTo') }}
|
{{ t('claim.list.assignedTo') }}
|
||||||
</q-item-label>
|
</q-item-label>
|
||||||
<q-item-label>{{ row.workerName }}</q-item-label>
|
<q-item-label>
|
||||||
|
{{ row.workerName }}
|
||||||
|
</q-item-label>
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
<q-item class="q-pa-none">
|
<q-item class="q-pa-none">
|
||||||
|
@ -163,9 +175,17 @@ function viewSummary(id) {
|
||||||
</q-card>
|
</q-card>
|
||||||
</template>
|
</template>
|
||||||
</paginate>
|
</paginate>
|
||||||
|
</div>
|
||||||
</q-page>
|
</q-page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.card-list {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 60em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
es:
|
es:
|
||||||
Search claim: Buscar reclamación
|
Search claim: Buscar reclamación
|
||||||
|
|
|
@ -58,7 +58,7 @@ const filterOptions = {
|
||||||
@on-fetch="(data) => (businessTypes = data)"
|
@on-fetch="(data) => (businessTypes = data)"
|
||||||
auto-load
|
auto-load
|
||||||
/>
|
/>
|
||||||
<div class="container">
|
<div class="column items-center">
|
||||||
<q-card>
|
<q-card>
|
||||||
<form-model :url="`Clients/${route.params.id}`" model="customer">
|
<form-model :url="`Clients/${route.params.id}`" model="customer">
|
||||||
<template #form="{ data, validate, filter }">
|
<template #form="{ data, validate, filter }">
|
||||||
|
@ -172,11 +172,6 @@ const filterOptions = {
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.container {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.q-card {
|
.q-card {
|
||||||
width: 800px;
|
width: 800px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted, onUnmounted } from 'vue';
|
|
||||||
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';
|
||||||
|
@ -15,9 +14,6 @@ const router = useRouter();
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
onMounted(() => (stateStore.rightDrawer = true));
|
|
||||||
onUnmounted(() => (stateStore.rightDrawer = false));
|
|
||||||
|
|
||||||
function navigate(id) {
|
function navigate(id) {
|
||||||
router.push({ path: `/customer/${id}` });
|
router.push({ path: `/customer/${id}` });
|
||||||
}
|
}
|
||||||
|
@ -40,13 +36,30 @@ function viewSummary(id) {
|
||||||
:info="t('You can search by customer id or name')"
|
:info="t('You can search by customer id or name')"
|
||||||
/>
|
/>
|
||||||
</teleport-slot>
|
</teleport-slot>
|
||||||
<teleport-slot to="#rightPanel">
|
<teleport-slot to="#actions-append">
|
||||||
<CustomerFilter data-key="CustomerList" />
|
<div class="row q-gutter-x-sm">
|
||||||
|
<q-btn flat @click="stateStore.toggleRightDrawer()" round dense icon="menu">
|
||||||
|
<q-tooltip bottom anchor="bottom right">
|
||||||
|
{{ t('globals.collapseMenu') }}
|
||||||
|
</q-tooltip>
|
||||||
|
</q-btn>
|
||||||
|
</div>
|
||||||
</teleport-slot>
|
</teleport-slot>
|
||||||
<q-page class="q-pa-md">
|
<q-drawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
|
||||||
<paginate data-key="CustomerList" url="/Clients/filter" order="id DESC" auto-load>
|
<q-scroll-area class="fit text-grey-8">
|
||||||
|
<CustomerFilter data-key="CustomerList" />
|
||||||
|
</q-scroll-area>
|
||||||
|
</q-drawer>
|
||||||
|
<q-page class="column items-center q-pa-md">
|
||||||
|
<div class="card-list">
|
||||||
|
<paginate
|
||||||
|
data-key="CustomerList"
|
||||||
|
url="/Clients/filter"
|
||||||
|
order="id DESC"
|
||||||
|
auto-load
|
||||||
|
>
|
||||||
<template #body="{ rows }">
|
<template #body="{ rows }">
|
||||||
<q-card class="card" v-for="row of rows" :key="row.id">
|
<q-card class="card q-mb-md" v-for="row of rows" :key="row.id">
|
||||||
<q-item
|
<q-item
|
||||||
class="q-pa-none items-start cursor-pointer q-hoverable"
|
class="q-pa-none items-start cursor-pointer q-hoverable"
|
||||||
v-ripple
|
v-ripple
|
||||||
|
@ -127,9 +140,17 @@ function viewSummary(id) {
|
||||||
</q-card>
|
</q-card>
|
||||||
</template>
|
</template>
|
||||||
</paginate>
|
</paginate>
|
||||||
|
</div>
|
||||||
</q-page>
|
</q-page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.card-list {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 60em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
es:
|
es:
|
||||||
Search customer: Buscar cliente
|
Search customer: Buscar cliente
|
||||||
|
|
|
@ -41,10 +41,22 @@ function viewSummary(id) {
|
||||||
:info="t('You can search by invoice reference')"
|
:info="t('You can search by invoice reference')"
|
||||||
/>
|
/>
|
||||||
</teleport-slot>
|
</teleport-slot>
|
||||||
<teleport-slot to="#rightPanel">
|
<teleport-slot to="#actions-append">
|
||||||
<InvoiceOutFilter data-key="InvoiceOutList" />
|
<div class="row q-gutter-x-sm">
|
||||||
|
<q-btn flat @click="stateStore.toggleRightDrawer()" round dense icon="menu">
|
||||||
|
<q-tooltip bottom anchor="bottom right">
|
||||||
|
{{ t('globals.collapseMenu') }}
|
||||||
|
</q-tooltip>
|
||||||
|
</q-btn>
|
||||||
|
</div>
|
||||||
</teleport-slot>
|
</teleport-slot>
|
||||||
<q-page class="q-pa-md">
|
<q-drawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
|
||||||
|
<q-scroll-area class="fit text-grey-8">
|
||||||
|
<InvoiceOutFilter data-key="InvoiceOutList" />
|
||||||
|
</q-scroll-area>
|
||||||
|
</q-drawer>
|
||||||
|
<q-page class="column items-center q-pa-md">
|
||||||
|
<div class="card-list">
|
||||||
<paginate
|
<paginate
|
||||||
data-key="InvoiceOutList"
|
data-key="InvoiceOutList"
|
||||||
url="InvoiceOuts/filter"
|
url="InvoiceOuts/filter"
|
||||||
|
@ -52,7 +64,7 @@ function viewSummary(id) {
|
||||||
auto-load
|
auto-load
|
||||||
>
|
>
|
||||||
<template #body="{ rows }">
|
<template #body="{ rows }">
|
||||||
<q-card class="card" v-for="row of rows" :key="row.id">
|
<q-card class="card q-mb-md" v-for="row of rows" :key="row.id">
|
||||||
<q-item
|
<q-item
|
||||||
class="q-pa-none items-start cursor-pointer q-hoverable"
|
class="q-pa-none items-start cursor-pointer q-hoverable"
|
||||||
v-ripple
|
v-ripple
|
||||||
|
@ -103,7 +115,9 @@ function viewSummary(id) {
|
||||||
<q-item-label caption>
|
<q-item-label caption>
|
||||||
{{ t('invoiceOut.list.company') }}
|
{{ t('invoiceOut.list.company') }}
|
||||||
</q-item-label>
|
</q-item-label>
|
||||||
<q-item-label>{{ row.companyCode }}</q-item-label>
|
<q-item-label>{{
|
||||||
|
row.companyCode
|
||||||
|
}}</q-item-label>
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
<q-item-section>
|
<q-item-section>
|
||||||
<q-item-label caption>
|
<q-item-label caption>
|
||||||
|
@ -145,9 +159,17 @@ function viewSummary(id) {
|
||||||
</q-card>
|
</q-card>
|
||||||
</template>
|
</template>
|
||||||
</paginate>
|
</paginate>
|
||||||
|
</div>
|
||||||
</q-page>
|
</q-page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.card-list {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 60em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
es:
|
es:
|
||||||
Search invoice: Buscar factura emitida
|
Search invoice: Buscar factura emitida
|
||||||
|
|
|
@ -78,10 +78,22 @@ function viewSummary(id) {
|
||||||
:info="t('You can search by ticket id or alias')"
|
:info="t('You can search by ticket id or alias')"
|
||||||
/>
|
/>
|
||||||
</teleport-slot>
|
</teleport-slot>
|
||||||
<teleport-slot to="#rightPanel">
|
<teleport-slot to="#actions-append">
|
||||||
<TicketFilter data-key="TicketList" />
|
<div class="row q-gutter-x-sm">
|
||||||
|
<q-btn flat @click="stateStore.toggleRightDrawer()" round dense icon="menu">
|
||||||
|
<q-tooltip bottom anchor="bottom right">
|
||||||
|
{{ t('globals.collapseMenu') }}
|
||||||
|
</q-tooltip>
|
||||||
|
</q-btn>
|
||||||
|
</div>
|
||||||
</teleport-slot>
|
</teleport-slot>
|
||||||
<q-page class="q-pa-md">
|
<q-drawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
|
||||||
|
<q-scroll-area class="fit text-grey-8">
|
||||||
|
<TicketFilter data-key="TicketList" />
|
||||||
|
</q-scroll-area>
|
||||||
|
</q-drawer>
|
||||||
|
<q-page class="column items-center q-pa-md">
|
||||||
|
<div class="card-list">
|
||||||
<paginate
|
<paginate
|
||||||
data-key="TicketList"
|
data-key="TicketList"
|
||||||
url="Tickets/filter"
|
url="Tickets/filter"
|
||||||
|
@ -90,7 +102,7 @@ function viewSummary(id) {
|
||||||
auto-load
|
auto-load
|
||||||
>
|
>
|
||||||
<template #body="{ rows }">
|
<template #body="{ rows }">
|
||||||
<q-card class="card" v-for="row of rows" :key="row.id">
|
<q-card class="card q-mb-md" v-for="row of rows" :key="row.id">
|
||||||
<q-item
|
<q-item
|
||||||
class="q-pa-none items-start cursor-pointer q-hoverable"
|
class="q-pa-none items-start cursor-pointer q-hoverable"
|
||||||
v-ripple
|
v-ripple
|
||||||
|
@ -105,7 +117,9 @@ function viewSummary(id) {
|
||||||
<q-item-label caption>
|
<q-item-label caption>
|
||||||
{{ t('ticket.list.nickname') }}
|
{{ t('ticket.list.nickname') }}
|
||||||
</q-item-label>
|
</q-item-label>
|
||||||
<q-item-label>{{ row.nickname }}</q-item-label>
|
<q-item-label>{{
|
||||||
|
row.nickname
|
||||||
|
}}</q-item-label>
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
<q-item-section>
|
<q-item-section>
|
||||||
<q-item-label caption>
|
<q-item-label caption>
|
||||||
|
@ -189,9 +203,17 @@ function viewSummary(id) {
|
||||||
</q-card>
|
</q-card>
|
||||||
</template>
|
</template>
|
||||||
</paginate>
|
</paginate>
|
||||||
|
</div>
|
||||||
</q-page>
|
</q-page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.card-list {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 60em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
es:
|
es:
|
||||||
Search ticket: Buscar ticket
|
Search ticket: Buscar ticket
|
||||||
|
|
Loading…
Reference in New Issue