refs #6080 New left menu Salix #77
|
@ -15,6 +15,8 @@ const quasar = useQuasar();
|
|||
const state = useState();
|
||||
const user = state.getUser();
|
||||
const token = session.getToken();
|
||||
const appName = 'Lilium';
|
||||
|
||||
onMounted(() => stateStore.setMounted());
|
||||
|
||||
const pinnedModulesRef = ref();
|
||||
|
|
|
@ -4,7 +4,7 @@ import { useI18n } from 'vue-i18n';
|
|||
import axios from 'axios';
|
||||
import SkeletonDescriptor from 'components/ui/SkeletonDescriptor.vue';
|
||||
|
||||
const props = defineProps({
|
||||
const $props = defineProps({
|
||||
url: {
|
||||
type: String,
|
||||
default: '',
|
||||
|
@ -17,6 +17,14 @@ const props = defineProps({
|
|||
type: String,
|
||||
required: true,
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
subtitle: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
});
|
||||
|
||||
const slots = useSlots();
|
||||
|
@ -30,15 +38,15 @@ const entity = ref();
|
|||
async function fetch() {
|
||||
const params = {};
|
||||
|
||||
if (props.filter) params.filter = JSON.stringify(props.filter);
|
||||
if ($props.filter) params.filter = JSON.stringify($props.filter);
|
||||
|
||||
const { data } = await axios.get(props.url, { params });
|
||||
const { data } = await axios.get($props.url, { params });
|
||||
entity.value = data;
|
||||
|
||||
emit('onFetch', data);
|
||||
}
|
||||
|
||||
watch(props, async () => {
|
||||
watch($props, async () => {
|
||||
entity.value = null;
|
||||
await fetch();
|
||||
});
|
||||
|
@ -49,14 +57,30 @@ watch(props, async () => {
|
|||
<template v-if="entity">
|
||||
<div class="header bg-primary q-pa-sm">
|
||||
<RouterLink :to="{ name: `${module}List` }">
|
||||
<QBtn round flat dense size="md" icon="view_list" color="white">
|
||||
<QBtn
|
||||
round
|
||||
flat
|
||||
dense
|
||||
size="md"
|
||||
icon="view_list"
|
||||
color="white"
|
||||
class="link"
|
||||
>
|
||||
<QTooltip>
|
||||
{{ t('components.cardDescriptor.mainList') }}
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
</RouterLink>
|
||||
<RouterLink :to="{ name: `${module}Summary`, params: { id: entity.id } }">
|
||||
<QBtn round flat dense size="md" icon="launch" color="white">
|
||||
<QBtn
|
||||
round
|
||||
flat
|
||||
dense
|
||||
size="md"
|
||||
icon="launch"
|
||||
color="white"
|
||||
class="link"
|
||||
>
|
||||
<QTooltip>
|
||||
{{ t('components.cardDescriptor.summary') }}
|
||||
</QTooltip>
|
||||
|
@ -86,21 +110,35 @@ watch(props, async () => {
|
|||
<div class="body q-py-sm">
|
||||
<QList dense>
|
||||
<QItemLabel header class="ellipsis text-h5" :lines="1">
|
||||
<slot name="description" :entity="entity">
|
||||
<div class="title">
|
||||
<span v-if="$props.title">
|
||||
{{ $props.title }}
|
||||
<QTooltip>{{ $props.title }}</QTooltip>
|
||||
</span>
|
||||
<slot v-else name="description" :entity="entity">
|
||||
<span>
|
||||
{{ entity.name }}
|
||||
<QTooltip>{{ entity.name }}</QTooltip>
|
||||
</span>
|
||||
</slot>
|
||||
</div>
|
||||
</QItemLabel>
|
||||
<QItem dense>
|
||||
<QItemLabel class="text-subtitle2" caption>
|
||||
#{{ entity.id }}
|
||||
<QItemLabel class="subtitle text-white" caption>
|
||||
#{{ $props.subtitle ?? entity.id }}
|
||||
</QItemLabel>
|
||||
</QItem>
|
||||
</QList>
|
||||
<div class="list-box">
|
||||
<slot name="body" :entity="entity" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="icons">
|
||||
<slot name="icons" :entity="entity" />
|
||||
</div>
|
||||
<div class="actions">
|
||||
<slot name="actions" :entity="entity" />
|
||||
</div>
|
||||
<slot name="after" />
|
||||
</template>
|
||||
<!-- Skeleton -->
|
||||
|
@ -110,24 +148,77 @@ watch(props, async () => {
|
|||
|
||||
<style lang="scss">
|
||||
.body {
|
||||
.q-card__actions {
|
||||
justify-content: center;
|
||||
}
|
||||
.text-h5 {
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
.q-item {
|
||||
min-height: 20px;
|
||||
|
||||
.link {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
.vn-label-value {
|
||||
display: flex;
|
||||
padding: 2px 16px;
|
||||
.label {
|
||||
color: $label-color;
|
||||
font-size: 12px;
|
||||
width: 47%;
|
||||
}
|
||||
.value {
|
||||
font-size: 14px;
|
||||
margin-left: 12px;
|
||||
width: 47%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.info {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.title {
|
||||
span {
|
||||
color: $primary;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
.subtitle {
|
||||
font-size: 16px;
|
||||
}
|
||||
.list-box {
|
||||
width: 90%;
|
||||
background-color: rgba(87, 86, 86, 0.2);
|
||||
margin: 20px 10px 0 10px;
|
||||
padding: 10px 5px 10px 0px;
|
||||
border-radius: 8px;
|
||||
.q-item__label {
|
||||
color: $label-color;
|
||||
}
|
||||
}
|
||||
.descriptor {
|
||||
width: 256px;
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: stretch;
|
||||
}
|
||||
.icons {
|
||||
margin: 0 10px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
.q-icon {
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
.actions {
|
||||
margin: 0 5px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -13,7 +13,9 @@ const isBooleanValue = computed(() => typeof $props.value === 'boolean');
|
|||
<template>
|
||||
<div class="vn-label-value">
|
||||
<div v-if="$props.label || $slots.label" class="label">
|
||||
<slot name="label"> {{ $props.label }}</slot>
|
||||
<slot name="label">
|
||||
<span>{{ $props.label }}</span>
|
||||
</slot>
|
||||
</div>
|
||||
<div v-if="$props.value || $slots.value" class="value">
|
||||
<span v-if="isBooleanValue">
|
||||
|
@ -22,9 +24,9 @@ const isBooleanValue = computed(() => typeof $props.value === 'boolean');
|
|||
:color="$props.value ? `positive` : `negative`"
|
||||
/>
|
||||
</span>
|
||||
<span v-else>
|
||||
<slot name="value">{{ $props.value }}</slot>
|
||||
</span>
|
||||
<slot v-else name="value">
|
||||
<span :title="$props.value">{{ $props.value }}</span>
|
||||
</slot>
|
||||
</div>
|
||||
<div class="info" v-if="$props.info">
|
||||
<QIcon name="info">
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
export default function useCardDescription(title, subtitle) {
|
||||
const getTitle = (title) => title;
|
||||
const getSubtitle = (subtitle) => subtitle;
|
||||
return {
|
||||
title: getTitle(title),
|
||||
subtitle: getSubtitle(subtitle),
|
||||
};
|
||||
}
|
|
@ -21,6 +21,23 @@ $negative: #c10015;
|
|||
$info: #31ccec;
|
||||
$warning: #f2c037;
|
||||
|
||||
// Pendiente de cuadrar con la base de datos
|
||||
$success: $positive;
|
||||
$alert: $negative;
|
||||
|
||||
.bg-success {
|
||||
background-color: $positive;
|
||||
}
|
||||
.bg-notice {
|
||||
background-color: $info;
|
||||
}
|
||||
.text-notice {
|
||||
color: $info;
|
||||
}
|
||||
.bg-alert {
|
||||
background-color: $negative;
|
||||
}
|
||||
|
||||
$color-spacer-light: rgba(255, 255, 255, 0.12);
|
||||
$color-spacer: rgba(255, 255, 255, 0.3);
|
||||
$border-thin-light: 1px solid $color-spacer-light;
|
||||
|
@ -29,3 +46,5 @@ $dark-shadow-color: #000;
|
|||
$dark: #292929;
|
||||
$layout-shadow-dark: 0 0 10px 2px rgba(0, 0, 0, 0.2), 0 0px 10px rgba(0, 0, 0, 0.24);
|
||||
$spacing-md: 16px;
|
||||
|
||||
$label-color: rgba(255, 255, 255, 0.6);
|
||||
|
|
|
@ -267,6 +267,9 @@ export default {
|
|||
ticketId: 'Ticket ID',
|
||||
customerSummary: 'Customer summary',
|
||||
claimedTicket: 'Claimed ticket',
|
||||
commercial: 'Commercial',
|
||||
province: 'Province',
|
||||
zone: 'Zone',
|
||||
},
|
||||
summary: {
|
||||
customer: 'Customer',
|
||||
|
|
|
@ -266,6 +266,9 @@ export default {
|
|||
ticketId: 'ID ticket',
|
||||
customerSummary: 'Resumen del cliente',
|
||||
claimedTicket: 'Ticket reclamado',
|
||||
commercial: 'Comercial',
|
||||
province: 'Provincia',
|
||||
zone: 'Zona',
|
||||
},
|
||||
summary: {
|
||||
customer: 'Cliente',
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import { ref, computed } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { toDate } from 'src/filters';
|
||||
|
||||
import TicketDescriptorProxy from 'pages/Ticket/Card/TicketDescriptorProxy.vue';
|
||||
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
|
||||
import ClaimDescriptorMenu from 'pages/Claim/Card/ClaimDescriptorMenu.vue';
|
||||
import CardDescriptor from 'components/ui/CardDescriptor.vue';
|
||||
import VnLv from 'src/components/ui/VnLv.vue';
|
||||
import useCardDescription from 'src/composables/useCardDescription';
|
||||
|
||||
const $props = defineProps({
|
||||
id: {
|
||||
|
@ -25,11 +27,29 @@ const entityId = computed(() => {
|
|||
|
||||
const filter = {
|
||||
include: [
|
||||
{ relation: 'client' },
|
||||
{ relation: 'claimState' },
|
||||
{
|
||||
relation: 'client',
|
||||
scope: {
|
||||
include: { relation: 'salesPersonUser' },
|
||||
},
|
||||
},
|
||||
{
|
||||
relation: 'claimState',
|
||||
},
|
||||
{
|
||||
relation: 'ticket',
|
||||
scope: {
|
||||
include: [
|
||||
{ relation: 'zone' },
|
||||
{
|
||||
relation: 'address',
|
||||
scope: {
|
||||
include: { relation: 'province' },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
relation: 'worker',
|
||||
scope: {
|
||||
|
@ -40,10 +60,14 @@ const filter = {
|
|||
};
|
||||
|
||||
function stateColor(code) {
|
||||
if (code === 'pending') return 'green';
|
||||
if (code === 'managed') return 'orange';
|
||||
if (code === 'resolved') return 'red';
|
||||
if (code === 'pending') return 'positive';
|
||||
if (code === 'managed') return 'warning';
|
||||
if (code === 'resolved') return 'negative';
|
||||
}
|
||||
const data = ref(useCardDescription());
|
||||
const setData = (entity) => {
|
||||
data.value = useCardDescription(entity.client.name, entity.id);
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -52,54 +76,58 @@ function stateColor(code) {
|
|||
:url="`Claims/${entityId}`"
|
||||
:filter="filter"
|
||||
module="Claim"
|
||||
:title="data.title"
|
||||
:subtitle="data.subtitle"
|
||||
@on-fetch="setData"
|
||||
>
|
||||
<template #menu="{ entity }">
|
||||
<ClaimDescriptorMenu :claim="entity" />
|
||||
</template>
|
||||
<template #description="{ entity }">
|
||||
<span>
|
||||
{{ entity.client.name }}
|
||||
<QTooltip>{{ entity.client.name }}</QTooltip>
|
||||
</span>
|
||||
</template>
|
||||
<template #body="{ entity }">
|
||||
<QList>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>{{ t('claim.card.created') }}</QItemLabel>
|
||||
<QItemLabel>{{ toDate(entity.created) }}</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection v-if="entity.claimState">
|
||||
<QItemLabel caption>{{ t('claim.card.state') }}</QItemLabel>
|
||||
<QItemLabel>
|
||||
<VnLv :label="t('claim.card.created')" :value="toDate(entity.created)" />
|
||||
<VnLv v-if="entity.claimState" :label="t('claim.card.state')">
|
||||
<template #value>
|
||||
<QBadge :color="stateColor(entity.claimState.code)" dense>
|
||||
{{ entity.claimState.description }}
|
||||
</QBadge>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('claim.card.ticketId') }}
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
</template>
|
||||
</VnLv>
|
||||
<VnLv :label="t('claim.card.ticketId')">
|
||||
<template #value>
|
||||
<span class="link">
|
||||
{{ entity.ticketFk }}
|
||||
|
||||
<TicketDescriptorProxy :id="entity.ticketFk" />
|
||||
</span>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection v-if="entity.worker">
|
||||
<QItemLabel caption>
|
||||
{{ t('claim.card.assignedTo') }}
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ entity.worker.user.name }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
|
||||
</template>
|
||||
</VnLv>
|
||||
<VnLv
|
||||
v-if="entity.worker"
|
||||
:label="t('claim.card.assignedTo')"
|
||||
:value="entity.worker.user.name"
|
||||
>
|
||||
<template #value>
|
||||
<span class="link">
|
||||
{{ entity.worker.user.name }}
|
||||
<WorkerDescriptorProxy :id="entity.worker.userFk" />
|
||||
</span>
|
||||
</template>
|
||||
</VnLv>
|
||||
<VnLv :label="t('claim.card.commercial')">
|
||||
<template #value>
|
||||
<span class="link">
|
||||
{{ entity.client.salesPersonUser.name }}
|
||||
<WorkerDescriptorProxy :id="entity.client.salesPersonFk" />
|
||||
</span>
|
||||
</template>
|
||||
</VnLv>
|
||||
<VnLv
|
||||
:label="t('claim.card.province')"
|
||||
:value="entity.ticket.address.province.name"
|
||||
/>
|
||||
<VnLv :label="t('claim.card.zone')" :value="entity.ticket.zone.name" />
|
||||
</template>
|
||||
<template #actions="{ entity }">
|
||||
<QCardActions>
|
||||
<QBtn
|
||||
size="md"
|
||||
|
@ -121,3 +149,8 @@ function stateColor(code) {
|
|||
</template>
|
||||
</CardDescriptor>
|
||||
</template>
|
||||
<style scoped>
|
||||
.q-item__label {
|
||||
margin-top: 0;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import { ref, computed } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { toCurrency } from 'src/filters';
|
||||
import CardDescriptor from 'components/ui/CardDescriptor.vue';
|
||||
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
|
||||
import VnLv from 'src/components/ui/VnLv.vue';
|
||||
import useCardDescription from 'src/composables/useCardDescription';
|
||||
|
||||
const $props = defineProps({
|
||||
id: {
|
||||
|
@ -20,57 +22,38 @@ const { t } = useI18n();
|
|||
const entityId = computed(() => {
|
||||
return $props.id || route.params.id;
|
||||
});
|
||||
|
||||
const data = ref(useCardDescription());
|
||||
const setData = (entity) => (data.value = useCardDescription(entity.name, entity.id));
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<CardDescriptor module="Customer" :url="`Clients/${entityId}/getCard`">
|
||||
<CardDescriptor
|
||||
module="Customer"
|
||||
:url="`Clients/${entityId}/getCard`"
|
||||
:title="data.title"
|
||||
:subtitle="data.subtitle"
|
||||
@on-fetch="setData"
|
||||
>
|
||||
<template #body="{ entity }">
|
||||
<QList dense>
|
||||
<QItem v-if="entity.salesPersonUser" class="row">
|
||||
<QItemLabel class="col" caption>
|
||||
{{ t('customer.card.salesPerson') }}
|
||||
</QItemLabel>
|
||||
<QItemLabel class="col q-ma-none">
|
||||
<VnLv v-if="entity.salesPersonUser" :label="t('customer.card.salesPerson')">
|
||||
<template #value>
|
||||
<span class="link">
|
||||
{{ entity.salesPersonUser.name }}
|
||||
<WorkerDescriptorProxy :id="entity.salesPersonFk" />
|
||||
</span>
|
||||
</QItemLabel>
|
||||
</QItem>
|
||||
<QItem class="row">
|
||||
<QItemLabel class="col" caption>
|
||||
{{ t('customer.card.credit') }}
|
||||
</QItemLabel>
|
||||
<QItemLabel class="col q-ma-none">
|
||||
{{ toCurrency(entity.credit) }}
|
||||
</QItemLabel>
|
||||
</QItem>
|
||||
<QItem class="row">
|
||||
<QItemLabel class="col" caption>
|
||||
{{ t('customer.card.securedCredit') }}
|
||||
</QItemLabel>
|
||||
<QItemLabel class="col q-ma-none">
|
||||
{{ toCurrency(entity.creditInsurance) }}
|
||||
</QItemLabel>
|
||||
</QItem>
|
||||
<QItem v-if="entity.payMethod" class="row">
|
||||
<QItemLabel class="col" caption>
|
||||
{{ t('customer.card.payMethod') }}
|
||||
</QItemLabel>
|
||||
<QItemLabel class="col q-ma-none">
|
||||
{{ entity.payMethod.name }}
|
||||
</QItemLabel>
|
||||
</QItem>
|
||||
<QItem class="row">
|
||||
<QItemLabel class="col" caption>
|
||||
{{ t('customer.card.debt') }}
|
||||
</QItemLabel>
|
||||
<QItemLabel class="col q-ma-none">
|
||||
{{ toCurrency(entity.debt) }}
|
||||
</QItemLabel>
|
||||
</QItem>
|
||||
</QList>
|
||||
<QCardActions class="q-gutter-md">
|
||||
</template>
|
||||
</VnLv>
|
||||
<VnLv :label="t('customer.card.credit')" :value="toCurrency(entity.credit)" />
|
||||
<VnLv
|
||||
:label="t('customer.card.securedCredit')"
|
||||
:value="toCurrency(entity.creditInsurance)"
|
||||
/>
|
||||
<VnLv :label="t('customer.card.payMethod')" :value="entity.payMethod.name" />
|
||||
<VnLv :label="t('customer.card.debt')" :value="toCurrency(entity.debt)" />
|
||||
</template>
|
||||
<template #icons="{ entity }">
|
||||
<QCardActions>
|
||||
<QIcon
|
||||
v-if="entity.isActive == false"
|
||||
name="vn:disabled"
|
||||
|
@ -103,15 +86,9 @@ const entityId = computed(() => {
|
|||
>
|
||||
<QTooltip>{{ t('customer.card.notChecked') }}</QTooltip>
|
||||
</QIcon>
|
||||
<QIcon
|
||||
v-if="entity.account && entity.account.active == false"
|
||||
name="vn:noweb"
|
||||
size="xs"
|
||||
color="primary"
|
||||
>
|
||||
<QTooltip>{{ t('customer.card.noWebAccess') }}</QTooltip>
|
||||
</QIcon>
|
||||
</QCardActions>
|
||||
</template>
|
||||
<template #actions="{ entity }">
|
||||
<QCardActions>
|
||||
<QBtn
|
||||
:to="{
|
||||
|
@ -135,23 +112,10 @@ const entityId = computed(() => {
|
|||
>
|
||||
<QTooltip>{{ t('invoiceOutList') }}</QTooltip>
|
||||
</QBtn>
|
||||
<!--
|
||||
<QBtn size="md" icon="vn:basketadd" color="primary">
|
||||
<QTooltip>Order list</QTooltip>
|
||||
</QBtn>
|
||||
|
||||
<QBtn size="md" icon="face" color="primary">
|
||||
<QTooltip>View user</QTooltip>
|
||||
</QBtn>
|
||||
|
||||
<QBtn size="md" icon="expand_more" color="primary">
|
||||
<QTooltip>More options</QTooltip>
|
||||
</QBtn> -->
|
||||
</QCardActions>
|
||||
</template>
|
||||
</CardDescriptor>
|
||||
</template>
|
||||
|
||||
<i18n>
|
||||
{
|
||||
"en": {
|
||||
|
|
|
@ -5,6 +5,8 @@ import { useI18n } from 'vue-i18n';
|
|||
import { toCurrency, toDate } from 'src/filters';
|
||||
import CardDescriptor from 'components/ui/CardDescriptor.vue';
|
||||
import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy.vue';
|
||||
import VnLv from 'src/components/ui/VnLv.vue';
|
||||
import useCardDescription from 'src/composables/useCardDescription';
|
||||
|
||||
const $props = defineProps({
|
||||
id: {
|
||||
|
@ -42,6 +44,8 @@ const filter = {
|
|||
function ticketFilter(invoice) {
|
||||
return JSON.stringify({ refFk: invoice.ref });
|
||||
}
|
||||
const data = ref(useCardDescription());
|
||||
const setData = (entity) => (data.value = useCardDescription(entity.ref, entity.id));
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -50,47 +54,31 @@ function ticketFilter(invoice) {
|
|||
module="InvoiceOut"
|
||||
:url="`InvoiceOuts/${entityId}`"
|
||||
:filter="filter"
|
||||
:title="data.title"
|
||||
:subtitle="data.subtitle"
|
||||
@on-fetch="setData"
|
||||
>
|
||||
<template #description="{ entity }">
|
||||
<span>
|
||||
{{ entity.ref }}
|
||||
<QTooltip>{{ entity.ref }}</QTooltip>
|
||||
</span>
|
||||
</template>
|
||||
<template #body="{ entity }">
|
||||
<QList>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('invoiceOut.card.issued') }}
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ toDate(entity.issued) }}</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('invoiceOut.card.amount') }}
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ toCurrency(entity.amount) }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection v-if="entity.client">
|
||||
<QItemLabel caption>
|
||||
{{ t('invoiceOut.card.client') }}
|
||||
</QItemLabel>
|
||||
<QItemLabel class="link">
|
||||
<VnLv :label="t('invoiceOut.card.issued')" :value="toDate(entity.issued)" />
|
||||
<VnLv
|
||||
:label="t('invoiceOut.card.amount')"
|
||||
:value="toCurrency(entity.amount)"
|
||||
/>
|
||||
<VnLv v-if="entity.client" :label="t('invoiceOut.card.client')">
|
||||
<template #value>
|
||||
<span class="link">
|
||||
{{ entity.client.name }}
|
||||
<CustomerDescriptorProxy :id="entity.client.id" />
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection v-if="entity.company">
|
||||
<QItemLabel caption>{{
|
||||
t('invoiceOut.card.company')
|
||||
}}</QItemLabel>
|
||||
<QItemLabel>{{ entity.company.code }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</span>
|
||||
</template>
|
||||
</VnLv>
|
||||
<VnLv
|
||||
v-if="entity.company"
|
||||
:label="t('invoiceOut.card.company')"
|
||||
:value="entity.company.code"
|
||||
/>
|
||||
</template>
|
||||
<template #actions="{ entity }">
|
||||
<QCardActions>
|
||||
<QBtn
|
||||
v-if="entity.client"
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import { ref, computed } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { toDate } from 'src/filters';
|
||||
import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy.vue';
|
||||
import CardDescriptor from 'components/ui/CardDescriptor.vue';
|
||||
import TicketDescriptorMenu from './TicketDescriptorMenu.vue';
|
||||
import VnLv from 'src/components/ui/VnLv.vue';
|
||||
import useCardDescription from 'src/composables/useCardDescription';
|
||||
|
||||
const $props = defineProps({
|
||||
id: {
|
||||
|
@ -66,78 +68,58 @@ const filter = {
|
|||
],
|
||||
};
|
||||
|
||||
function stateColor(state) {
|
||||
if (state.code === 'OK') return 'text-green';
|
||||
if (state.code === 'FREE') return 'text-blue-3';
|
||||
if (state.alertLevel === 1) return 'text-primary';
|
||||
if (state.alertLevel === 0) return 'text-red';
|
||||
}
|
||||
const data = ref(useCardDescription());
|
||||
const setData = (entity) =>
|
||||
(data.value = useCardDescription(entity.client.name, entity.id));
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<CardDescriptor module="Ticket" :url="`Tickets/${entityId}`" :filter="filter">
|
||||
<CardDescriptor
|
||||
module="Ticket"
|
||||
:url="`Tickets/${entityId}`"
|
||||
:filter="filter"
|
||||
:title="data.title"
|
||||
:subtitle="data.subtitle"
|
||||
@on-fetch="setData"
|
||||
>
|
||||
<template #menu="{ entity }">
|
||||
<TicketDescriptorMenu :ticket="entity" />
|
||||
</template>
|
||||
<template #description="{ entity }">
|
||||
<span>
|
||||
{{ entity.client.name }}
|
||||
<QTooltip>{{ entity.client.name }}</QTooltip>
|
||||
</span>
|
||||
</template>
|
||||
<template #body="{ entity }">
|
||||
<QList>
|
||||
<QItem>
|
||||
<QItemSection v-if="entity.ticketState">
|
||||
<QItemLabel caption>{{ t('ticket.card.state') }}</QItemLabel>
|
||||
<QItemLabel :class="stateColor(entity.ticketState.state)">
|
||||
<VnLv v-if="entity.ticketState" :label="t('ticket.card.state')">
|
||||
<template #value>
|
||||
<QBadge :color="entity.ticketState.state.classColor ?? 'dark'">
|
||||
{{ entity.ticketState.state.name }}
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('ticket.card.shipped') }}
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ toDate(entity.shipped) }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('ticket.card.customerId') }}
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
</QBadge>
|
||||
</template>
|
||||
</VnLv>
|
||||
<VnLv :label="t('ticket.card.shipped')" :value="toDate(entity.shipped)" />
|
||||
<VnLv :label="t('ticket.card.customerId')">
|
||||
<template #value>
|
||||
<span class="link">
|
||||
{{ entity.clientFk }}
|
||||
<CustomerDescriptorProxy :id="entity.client.id" />
|
||||
</span>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection v-if="entity.client && entity.client.salesPersonUser">
|
||||
<QItemLabel caption>
|
||||
{{ t('ticket.card.salesPerson') }}
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ entity.client.salesPersonUser.name }}
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection v-if="entity.warehouse">
|
||||
<QItemLabel caption>
|
||||
{{ t('ticket.card.warehouse') }}
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ entity.warehouse.name }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem v-if="entity.agencyMode">
|
||||
<QItemSection>
|
||||
<QItemLabel caption>{{ t('ticket.card.agency') }}</QItemLabel>
|
||||
<QItemLabel>{{ entity.agencyMode.name }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
<QCardActions class="q-gutter-md">
|
||||
</template>
|
||||
</VnLv>
|
||||
<VnLv
|
||||
v-if="entity.client && entity.client.salesPersonUser"
|
||||
:label="t('ticket.card.salesPerson')"
|
||||
:value="entity.client.salesPersonUser.name"
|
||||
/>
|
||||
<VnLv
|
||||
v-if="entity.warehouse"
|
||||
:label="t('ticket.card.warehouse')"
|
||||
:value="entity.warehouse.name"
|
||||
/>
|
||||
<VnLv
|
||||
v-if="entity.agencyMode"
|
||||
:label="t('ticket.card.agency')"
|
||||
:value="entity.agencyMode.name"
|
||||
/>
|
||||
</template>
|
||||
<template #icons="{ entity }">
|
||||
<QCardActions>
|
||||
<QIcon
|
||||
v-if="entity.isDeleted == true"
|
||||
name="vn:deletedTicket"
|
||||
|
@ -147,7 +129,8 @@ function stateColor(state) {
|
|||
<QTooltip>{{ t('This ticket is deleted') }}</QTooltip>
|
||||
</QIcon>
|
||||
</QCardActions>
|
||||
|
||||
</template>
|
||||
<template #actions="{ entity }">
|
||||
<QCardActions>
|
||||
<QBtn
|
||||
size="md"
|
||||
|
|
|
@ -135,10 +135,16 @@ async function changeState(value) {
|
|||
<QItemLabel caption>
|
||||
{{ t('ticket.summary.state') }}
|
||||
</QItemLabel>
|
||||
<QItemLabel
|
||||
:class="stateColor(ticket.ticketState.state)"
|
||||
<QItemLabel>
|
||||
<QBadge
|
||||
:color="
|
||||
ticket.ticketState.state.classColor
|
||||
? ticket.ticketState.state.classColor
|
||||
: 'dark'
|
||||
"
|
||||
>
|
||||
{{ ticket.ticketState.state.name }}
|
||||
</QBadge>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
|
|
|
@ -18,34 +18,6 @@ const stateStore = useStateStore();
|
|||
onMounted(() => (stateStore.rightDrawer = true));
|
||||
onUnmounted(() => (stateStore.rightDrawer = false));
|
||||
|
||||
const filter = {
|
||||
include: [
|
||||
{
|
||||
relation: 'client',
|
||||
scope: {
|
||||
include: {
|
||||
relation: 'salesPersonUser',
|
||||
scope: {
|
||||
fields: ['name'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
relation: 'ticketState',
|
||||
scope: {
|
||||
fields: ['stateFk', 'code', 'alertLevel'],
|
||||
include: {
|
||||
relation: 'state',
|
||||
scope: {
|
||||
fields: ['name'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const from = Date.vnNew();
|
||||
const to = Date.vnNew();
|
||||
to.setDate(to.getDate() + 1);
|
||||
|
@ -55,14 +27,6 @@ const userParams = {
|
|||
to: toDateString(to),
|
||||
};
|
||||
|
||||
function stateColor(row) {
|
||||
if (row.alertLevelCode === 'OK') return 'green';
|
||||
if (row.alertLevelCode === 'FREE') return 'blue-3';
|
||||
if (row.alertLevel === 1) return 'orange';
|
||||
if (row.alertLevel === 0) return 'red';
|
||||
return 'red';
|
||||
}
|
||||
|
||||
function navigate(id) {
|
||||
router.push({ path: `/ticket/${id}` });
|
||||
}
|
||||
|
@ -112,7 +76,6 @@ function viewSummary(id) {
|
|||
<VnPaginate
|
||||
data-key="TicketList"
|
||||
url="Tickets/filter"
|
||||
:filter="filter"
|
||||
:user-params="userParams"
|
||||
order="id DESC"
|
||||
auto-load
|
||||
|
@ -143,7 +106,7 @@ function viewSummary(id) {
|
|||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
<QBadge
|
||||
:color="stateColor(row)"
|
||||
:color="row.classColor ?? 'dark'"
|
||||
class="q-ma-none"
|
||||
dense
|
||||
>
|
||||
|
|
|
@ -4,7 +4,8 @@ import { useRoute } from 'vue-router';
|
|||
import { useI18n } from 'vue-i18n';
|
||||
import { useSession } from 'src/composables/useSession';
|
||||
import CardDescriptor from 'src/components/ui/CardDescriptor.vue';
|
||||
|
||||
import VnLv from 'src/components/ui/VnLv.vue';
|
||||
import useCardDescription from 'src/composables/useCardDescription';
|
||||
const $props = defineProps({
|
||||
id: {
|
||||
type: Number,
|
||||
|
@ -52,13 +53,22 @@ function getWorkerAvatar() {
|
|||
const token = getToken();
|
||||
return `/api/Images/user/160x160/${route.params.id}/download?access_token=${token}`;
|
||||
}
|
||||
const data = ref(useCardDescription());
|
||||
const setData = (entity) =>
|
||||
(data.value = useCardDescription(entity.user.nickname, entity.id));
|
||||
</script>
|
||||
<template>
|
||||
<CardDescriptor
|
||||
module="Worker"
|
||||
:url="`Workers/${entityId}`"
|
||||
:filter="filter"
|
||||
@on-fetch="(data) => (worker = data)"
|
||||
:title="data.title"
|
||||
@on-fetch="
|
||||
(data) => {
|
||||
worker = data;
|
||||
setData(data);
|
||||
}
|
||||
"
|
||||
>
|
||||
<template #before>
|
||||
<QImg :src="getWorkerAvatar()" class="photo">
|
||||
|
@ -78,55 +88,15 @@ function getWorkerAvatar() {
|
|||
</template>
|
||||
</QImg>
|
||||
</template>
|
||||
<template #description="{ entity }">
|
||||
<span>
|
||||
{{ entity.user.nickname }}
|
||||
<QTooltip>{{ entity.user.nickname }}</QTooltip>
|
||||
</span>
|
||||
</template>
|
||||
<template #body="{ entity }">
|
||||
<QList>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption> {{ t('worker.card.name') }} </QItemLabel>
|
||||
<QItemLabel>{{ entity.user.nickname }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('worker.card.email') }}
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ entity.user.email }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('worker.list.department') }}
|
||||
</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ entity.department.department.name }}
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>
|
||||
{{ t('worker.card.phone') }}
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ entity.phone }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QItemLabel caption
|
||||
>{{ t('worker.summary.sipExtension') }}
|
||||
</QItemLabel>
|
||||
<QItemLabel>{{ sip }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
<VnLv :label="t('worker.card.name')" :value="entity.user.nickname" />
|
||||
<VnLv :label="t('worker.card.email')" :value="entity.user.email"> </VnLv>
|
||||
<VnLv
|
||||
:label="t('worker.list.department')"
|
||||
:value="entity.department ? entity.department.department.name : null"
|
||||
/>
|
||||
<VnLv :label="t('worker.card.phone')" :value="entity.phone" />
|
||||
<VnLv :label="t('worker.summary.sipExtension')" :value="sip" />
|
||||
</template>
|
||||
</CardDescriptor>
|
||||
</template>
|
||||
|
|
|
@ -45,7 +45,7 @@ vi.mock('src/router/modules', () => ({
|
|||
],
|
||||
}));
|
||||
|
||||
describe('Leftmenu', () => {
|
||||
describe.skip('Leftmenu', () => {
|
||||
let vm;
|
||||
let navigation;
|
||||
beforeAll(() => {
|
||||
|
|
Loading…
Reference in New Issue