0
0
Fork 0

feat(claimLog): added claim log section

Refs: #5340
This commit is contained in:
Joan Sanchez 2023-03-06 14:29:21 +01:00
parent 818356465b
commit 34e5814b06
16 changed files with 816 additions and 581 deletions

View File

@ -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>

View File

@ -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%;

View File

@ -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);

View File

@ -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',

View File

@ -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',

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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;
} }

View File

@ -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

View File

@ -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;
} }

View File

@ -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

View File

@ -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

View File

@ -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