Account list

This commit is contained in:
William Buezas 2024-05-28 17:30:39 -03:00
parent 4292804922
commit 062de82bca
5 changed files with 80 additions and 210 deletions

View File

@ -6,7 +6,6 @@ import FetchData from 'components/FetchData.vue';
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
import VnSelect from 'components/common/VnSelect.vue'; import VnSelect from 'components/common/VnSelect.vue';
import VnInput from 'src/components/common/VnInput.vue'; import VnInput from 'src/components/common/VnInput.vue';
import VnInputDate from 'components/common/VnInputDate.vue';
const { t } = useI18n(); const { t } = useI18n();
const props = defineProps({ const props = defineProps({
@ -16,22 +15,24 @@ const props = defineProps({
}, },
}); });
const workers = ref(); const rolesOptions = ref([]);
const states = ref();
</script> </script>
<template> <template>
<FetchData url="AccountStates" @on-fetch="(data) => (states = data)" auto-load />
<FetchData <FetchData
url="Workers/activeWithInheritedRole" url="VnRoles"
:filter="{ where: { role: 'salesPerson' } }" :filter="{ fields: ['id', 'name'], order: 'name ASC' }"
@on-fetch="(data) => (workers = data)" @on-fetch="(data) => (rolesOptions = data)"
auto-load auto-load
/> />
<VnFilterPanel :data-key="props.dataKey" :search-button="true"> <VnFilterPanel
:data-key="props.dataKey"
:search-button="true"
:hidden-tags="['search']"
>
<template #tags="{ tag, formatFn }"> <template #tags="{ tag, formatFn }">
<div class="q-gutter-x-xs"> <div class="q-gutter-x-xs">
<strong>{{ t(`params.${tag.label}`) }}: </strong> <strong>{{ t(`account.filterPanel.${tag.label}`) }}: </strong>
<span>{{ formatFn(tag.value) }}</span> <span>{{ formatFn(tag.value) }}</span>
</div> </div>
</template> </template>
@ -39,36 +40,30 @@ const states = ref();
<QItem class="q-my-sm"> <QItem class="q-my-sm">
<QItemSection> <QItemSection>
<VnInput <VnInput
:label="t('Customer ID')" :label="t('account.filterPanel.name')"
v-model="params.clientFk" v-model="params.name"
lazy-rules lazy-rules
is-outlined is-outlined
> />
<template #prepend>
<QIcon name="badge" size="xs"></QIcon> </template
></VnInput>
</QItemSection> </QItemSection>
</QItem> </QItem>
<QItem class="q-mb-sm"> <QItem class="q-my-sm">
<QItemSection> <QItemSection>
<VnInput <VnInput
:label="t('Client Name')" :label="t('account.filterPanel.nickname')"
v-model="params.clientName" v-model="params.nickname"
lazy-rules lazy-rules
is-outlined is-outlined
/> />
</QItemSection> </QItemSection>
</QItem> </QItem>
<QItem class="q-mb-sm"> <QItem class="q-mb-sm">
<QItemSection v-if="!workers"> <QItemSection>
<QSkeleton type="QInput" class="full-width" />
</QItemSection>
<QItemSection v-if="workers">
<VnSelect <VnSelect
:label="t('Salesperson')" :label="t('account.filterPanel.roleFk')"
v-model="params.salesPersonFk" v-model="params.roleFk"
@update:model-value="searchFn()" @update:model-value="searchFn()"
:options="workers" :options="rolesOptions"
option-value="id" option-value="id"
option-label="name" option-label="name"
emit-value emit-value
@ -82,144 +77,6 @@ const states = ref();
/> />
</QItemSection> </QItemSection>
</QItem> </QItem>
<QItem class="q-mb-sm">
<QItemSection v-if="!workers">
<QSkeleton type="QInput" class="full-width" />
</QItemSection>
<QItemSection v-if="workers">
<VnSelect
:label="t('Attender')"
v-model="params.attenderFk"
@update:model-value="searchFn()"
:options="workers"
option-value="id"
option-label="name"
emit-value
map-options
use-input
hide-selected
dense
outlined
rounded
:input-debounce="0"
/>
</QItemSection>
</QItem>
<QItem class="q-mb-sm">
<QItemSection v-if="!workers">
<QSkeleton type="QInput" class="full-width" />
</QItemSection>
<QItemSection v-if="workers">
<VnSelect
:label="t('Responsible')"
v-model="params.accountResponsibleFk"
@update:model-value="searchFn()"
:options="workers"
option-value="id"
option-label="name"
emit-value
map-options
use-input
hide-selected
dense
outlined
rounded
:input-debounce="0"
/>
</QItemSection>
</QItem>
<QItem class="q-mb-sm">
<QItemSection v-if="!states">
<QSkeleton type="QInput" class="full-width" />
</QItemSection>
<QItemSection v-if="states">
<VnSelect
:label="t('State')"
v-model="params.accountStateFk"
@update:model-value="searchFn()"
:options="states"
option-value="id"
option-label="description"
emit-value
map-options
hide-selected
dense
outlined
rounded
/>
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<QCheckbox
v-model="params.myTeam"
:label="t('myTeam')"
toggle-indeterminate
/>
</QItemSection>
</QItem>
<QSeparator />
<QExpansionItem :label="t('More options')" expand-separator>
<!-- <QItem>
<QItemSection>
<qSelect
:label="t('Item')"
v-model="params.itemFk"
:options="items"
:loading="loading"
@filter="filterFn"
@virtual-scroll="onScroll"
option-value="id"
option-label="name"
emit-value
map-options
/>
</QItemSection>
</QItem> -->
<QItem>
<QItemSection>
<VnInputDate
v-model="params.created"
:label="t('Created')"
is-outlined
/>
</QItemSection>
</QItem>
</QExpansionItem>
</template> </template>
</VnFilterPanel> </VnFilterPanel>
</template> </template>
<i18n>
en:
params:
search: Contains
clientFk: Customer
clientName: Customer
salesPersonFk: Salesperson
attenderFk: Attender
accountResponsibleFk: Responsible
accountStateFk: State
created: Created
myTeam: My team
es:
params:
search: Contiene
clientFk: Cliente
clientName: Cliente
salesPersonFk: Comercial
attenderFk: Asistente
accountResponsibleFk: Responsable
accountStateFk: Estado
created: Creada
Customer ID: ID cliente
Client Name: Nombre del cliente
Salesperson: Comercial
Attender: Asistente
Responsible: Responsable
State: Estado
Item: Artículo
Created: Creada
More options: Más opciones
myTeam: Mi equipo
</i18n>

View File

@ -1,34 +1,53 @@
<script setup> <script setup>
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { useStateStore } from 'stores/useStateStore';
import { toDate } from 'filters/index';
import VnPaginate from 'src/components/ui/VnPaginate.vue'; import VnPaginate from 'src/components/ui/VnPaginate.vue';
import VnSearchbar from 'components/ui/VnSearchbar.vue'; import VnSearchbar from 'components/ui/VnSearchbar.vue';
import AccountFilter from './AccountFilter.vue';
import VnLv from 'src/components/ui/VnLv.vue'; import VnLv from 'src/components/ui/VnLv.vue';
import CardList from 'src/components/ui/CardList.vue'; import CardList from 'src/components/ui/CardList.vue';
import VnUserLink from 'src/components/ui/VnUserLink.vue';
import AccountSummary from './Card/AccountSummary.vue'; import AccountSummary from './Card/AccountSummary.vue';
import AccountFilter from './AccountFilter.vue';
import { useSummaryDialog } from 'src/composables/useSummaryDialog'; import { useSummaryDialog } from 'src/composables/useSummaryDialog';
import { useStateStore } from 'stores/useStateStore';
const stateStore = useStateStore(); const stateStore = useStateStore();
const router = useRouter(); const router = useRouter();
const { t } = useI18n(); const { t } = useI18n();
const { viewSummary } = useSummaryDialog(); const { viewSummary } = useSummaryDialog();
const filter = { const filter = {
fields: ['id', 'nickname', 'name', 'role'], fields: ['id', 'nickname', 'name', 'role'],
include: { relation: 'role', scope: { fields: ['id', 'name'] } }, include: { relation: 'role', scope: { fields: ['id', 'name'] } },
}; };
function getApiUrl() { const exprBuilder = (param, value) => {
return new URL(window.location).origin; switch (param) {
} case 'search':
function navigate(event, id) { return /^\d+$/.test(value)
? { id: value }
: {
or: [
{ name: { like: `%${value}%` } },
{ nickname: { like: `%${value}%` } },
],
};
case 'name':
case 'nickname':
return { [param]: { like: `%${value}%` } };
case 'roleFk':
return { [param]: value };
}
};
const getApiUrl = () => new URL(window.location).origin;
const navigate = (event, id) => {
if (event.ctrlKey || event.metaKey) if (event.ctrlKey || event.metaKey)
return window.open(`${getApiUrl()}/#/account/${id}/summary`); return window.open(`${getApiUrl()}/#/account/${id}/summary`);
router.push({ path: `/account/${id}` }); router.push({ path: `/account/${id}` });
} };
</script> </script>
<template> <template>
@ -36,6 +55,8 @@ function navigate(event, id) {
<Teleport to="#searchbar"> <Teleport to="#searchbar">
<VnSearchbar <VnSearchbar
data-key="AccountList" data-key="AccountList"
url="VnUsers/preview"
:expr-builder="exprBuilder"
:label="t('account.search')" :label="t('account.search')"
:info="t('You can search by account id or customer name')" :info="t('You can search by account id or customer name')"
/> />
@ -58,7 +79,7 @@ function navigate(event, id) {
</template> </template>
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above> <QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
<QScrollArea class="fit text-grey-8"> <QScrollArea class="fit text-grey-8">
<!-- <AccountFilter data-key="AccountList" /> --> <AccountFilter data-key="AccountList" :expr-builder="exprBuilder" />
</QScrollArea> </QScrollArea>
</QDrawer> </QDrawer>
<QPage class="column items-center q-pa-md"> <QPage class="column items-center q-pa-md">
@ -71,11 +92,11 @@ function navigate(event, id) {
> >
<template #body="{ rows }"> <template #body="{ rows }">
<CardList <CardList
v-for="row of rows"
:id="row.id" :id="row.id"
:key="row.id" :key="row.id"
:title="row.clientName" :title="row.nickname"
@click="navigate($event, row.id)" @click="navigate($event, row.id)"
v-for="row of rows"
> >
<template #list-items> <template #list-items>
<VnLv :label="t('account.card.name')" :value="row.nickname"> <VnLv :label="t('account.card.name')" :value="row.nickname">
@ -87,13 +108,6 @@ function navigate(event, id) {
</VnLv> </VnLv>
</template> </template>
<template #actions> <template #actions>
<QBtn
:label="t('globals.description')"
@click.stop
outline
style="margin-top: 15px"
>
</QBtn>
<QBtn <QBtn
:label="t('components.smartCard.openSummary')" :label="t('components.smartCard.openSummary')"
@click.stop="viewSummary(row.id, AccountSummary)" @click.stop="viewSummary(row.id, AccountSummary)"

View File

@ -1,22 +1,15 @@
<script setup> <script setup>
import { onMounted, ref, computed } from 'vue'; import { ref, computed } from 'vue';
import { useRoute, useRouter } from 'vue-router'; import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { toDate, toCurrency } from 'src/filters';
import CardSummary from 'components/ui/CardSummary.vue'; import CardSummary from 'components/ui/CardSummary.vue';
import FetchData from 'components/FetchData.vue';
import { getUrl } from 'src/composables/getUrl';
import { useSession } from 'src/composables/useSession';
import VnLv from 'src/components/ui/VnLv.vue'; import VnLv from 'src/components/ui/VnLv.vue';
import VnUserLink from 'src/components/ui/VnUserLink.vue';
import VnTitle from 'src/components/common/VnTitle.vue';
import axios from 'axios';
import dashIfEmpty from 'src/filters/dashIfEmpty';
import { useArrayData } from 'src/composables/useArrayData'; import { useArrayData } from 'src/composables/useArrayData';
const route = useRoute(); const route = useRoute();
const { t } = useI18n(); const { t } = useI18n();
const { getTokenMultimedia } = useSession();
const $props = defineProps({ const $props = defineProps({
id: { id: {
@ -38,7 +31,7 @@ const filter = {
<template> <template>
<CardSummary <CardSummary
ref="AccountSummary" ref="AccountSummary"
:url="`VnUsers/preview`" url="VnUsers/preview"
:filter="filter" :filter="filter"
@on-fetch="(data) => (account = data)" @on-fetch="(data) => (account = data)"
> >
@ -46,13 +39,13 @@ const filter = {
<template #body> <template #body>
<QCard class="vn-one"> <QCard class="vn-one">
<QCardSection class="q-pa-none"> <QCardSection class="q-pa-none">
<a <router-link
:to="{ name: 'AccountBasicData', params: { id: entityId } }"
class="header header-link" class="header header-link"
:href="`#/VnUser/${entityId}/basic-data`"
> >
{{ t('globals.pageTitles.basicData') }} {{ t('globals.pageTitles.basicData') }}
<QIcon name="open_in_new" /> <QIcon name="open_in_new" />
</a> </router-link>
</QCardSection> </QCardSection>
<VnLv :label="t('account.card.nickname')" :value="account.nickname" /> <VnLv :label="t('account.card.nickname')" :value="account.nickname" />
<VnLv :label="t('account.card.role')" :value="account.role.name" /> <VnLv :label="t('account.card.role')" :value="account.role.name" />

View File

@ -32,6 +32,10 @@ account:
sync: Sync sync: Sync
delete: Delete delete: Delete
search: Search user search: Search user
filterPanel:
name: Name
nickname: User
roleFk: Role
role: role:
pageTitles: pageTitles:
inheritedRoles: Inherited Roles inheritedRoles: Inherited Roles

View File

@ -40,8 +40,11 @@ account:
name: Eliminar name: Eliminar
title: El usuario será eliminado title: El usuario será eliminado
subtitle: ¿Seguro que quieres continuar? subtitle: ¿Seguro que quieres continuar?
search: Buscar usuario search: Buscar usuario
filterPanel:
name: Nombre
nickname: Usuario
roleFk: Rol
role: role:
pageTitles: pageTitles:
inheritedRoles: Roles heredados inheritedRoles: Roles heredados
@ -51,7 +54,6 @@ role:
description: Descripción description: Descripción
id: Idd id: Idd
name: Nombre name: Nombre
ldap: ldap:
enableSync: Habilitar sincronización enableSync: Habilitar sincronización
server: Servidor server: Servidor