feat: refs #6683 add PropertySummary component for detailed property overview

This commit is contained in:
Jose Antonio Tubau 2025-04-01 15:09:39 +02:00
parent 5847734ef7
commit c6b9b3646f
1 changed files with 302 additions and 0 deletions

View File

@ -0,0 +1,302 @@
<script setup>
import { onMounted, ref, computed } from 'vue';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
import axios from 'axios';
import { dashIfEmpty, toDate, toCurrency } from 'src/filters';
import CardSummary from 'components/ui/CardSummary.vue';
import VnLv from 'src/components/ui/VnLv.vue';
import { getUrl } from 'src/composables/getUrl';
import useNotify from 'src/composables/useNotify.js';
import { useArrayData } from 'composables/useArrayData';
import VnTitle from 'src/components/common/VnTitle.vue';
import VnToSummary from 'src/components/ui/VnToSummary.vue';
import FetchData from 'src/components/FetchData.vue';
import PropertyNotes from './PropertyNotes.vue';
import VnAvatar from 'src/components/ui/VnAvatar.vue';
import VnUserLink from 'src/components/ui/VnUserLink.vue';
import VnCheckbox from 'src/components/common/VnCheckbox.vue';
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
const route = useRoute();
const { notify } = useNotify();
const { t } = useI18n();
const $props = defineProps({
id: {
type: Number,
default: null,
},
});
const dmsColumns = ref([
{
align: 'left',
label: t('globals.id'),
name: 'id',
field: ({ id }) => id,
},
{
align: 'left',
label: t('globals.type'),
name: 'type',
field: ({ type }) => type?.name,
},
{
align: 'left',
label: t('globals.order'),
name: 'order',
field: ({ hardCopyNumber }) => dashIfEmpty(hardCopyNumber),
},
{
align: 'left',
label: t('globals.reference'),
name: 'reference',
field: ({ reference }) => dashIfEmpty(reference),
},
{
align: 'left',
label: t('globals.description'),
name: 'description',
field: ({ description }) => dashIfEmpty(description),
},
{
align: 'left',
label: t('globals.original'),
name: 'hasFile',
toolTip: t('The documentation is available in paper form'),
component: 'checkbox',
field: ({ hasFile }) => hasFile,
},
{
align: 'left',
label: t('globals.worker'),
name: 'worker',
field: ({ worker }) => worker?.name,
},
{
align: 'left',
label: t('globals.created'),
name: 'created',
field: ({ created }) => toDate(created),
},
]);
const entityId = computed(() => $props.id || route.params.id);
const summary = ref();
const property = computed(() => summary.value?.entity);
const propertyUrl = ref();
const propertyDms = ref(null);
const descriptorData = useArrayData('Property');
onMounted(async () => {
propertyUrl.value = (await getUrl('property/')) + entityId.value + '/';
});
function toPropertyUrl(section) {
return '#/property/' + entityId.value + '/' + section;
}
onMounted(async () => {
const filter = { fields: ['code', 'name', 'id', 'alertLevel'] };
const params = { filter: JSON.stringify(filter) };
});
</script>
<template>
<FetchData
ref="propertyDms"
:url="`Properties/${entityId}/dms`"
@on-fetch="
(data) => {
propertyDms.value = data;
}
"
/>
<CardSummary
ref="summary"
:url="`Properties/${entityId}/summary`"
data-key="PropertySummary"
v-bind="$attrs.width"
>
<template #header-left>
<VnToSummary
v-if="route?.name !== 'PropertySummary'"
:route-name="'PropertySummary'"
:entity-id="entityId"
:url="PropertyUrl"
/>
</template>
<template #header="{ entity }">
<div>Property #{{ entity.id }} - {{ entity.name }}</div>
</template>
<template #menu="{ entity }">
<!-- <PropertyDescriptorMenu :ticket="entity" /> -->
</template>
<template #body="{ entity }">
<QCard class="vn-one">
<VnTitle
:url="toPropertyUrl('basic-data')"
:text="t('globals.summary.basicData')"
/>
<div class="vn-card-group">
<div class="vn-card-content">
<VnLv
:label="t('property.owner')"
:value="dashIfEmpty(entity.company.code)"
/>
<VnLv :label="t('property.map')" :value="dashIfEmpty(entity.url)">
<template #value>
<a
v-if="entity?.url"
:href="`${entity?.url}`"
target="_blank"
class="grafana"
>
{{ t('property.goToMap') }}
</a>
</template>
</VnLv>
<VnLv
:label="t('property.value')"
:value="toCurrency(entity.value)"
/>
<VnLv
:label="t('property.protocol')"
:value="dashIfEmpty(entity.protocol)"
/>
<VnLv
:label="t('property.purchased')"
:value="toDate(entity.purchased)"
/>
<VnLv
:label="t('property.booked')"
:value="toDate(entity.booked)"
/>
</div>
</div>
</QCard>
<QCard class="vn-one">
<VnTitle
:url="toPropertyUrl('basic-data')"
:text="t('globals.summary.basicData')"
/>
<div class="vn-card-content">
<VnLv
:label="t('property.cadaster')"
:value="dashIfEmpty(entity.cadaster)"
/>
<VnLv
:label="t('property.smallHolding')"
:value="dashIfEmpty(entity.smallHolding)"
/>
<VnLv :label="t('property.area')" :value="dashIfEmpty(entity.area)" />
<VnLv
:label="t('property.allocation')"
:value="dashIfEmpty(entity.allocation)"
/>
<VnLv
:label="t('property.town')"
:value="dashIfEmpty(entity.town.name)"
/>
<VnLv :label="t('property.m2')" :value="dashIfEmpty(entity.m2)" />
</div>
</QCard>
<QCard class="vn-one">
<VnTitle
:url="toPropertyUrl('basic-data')"
:text="t('globals.summary.basicData')"
/>
<div class="vn-card-content">
<VnLv
:label="t('property.registry')"
:value="dashIfEmpty(entity.registry)"
/>
<VnLv :label="t('property.tome')" :value="dashIfEmpty(entity.tome)" />
<VnLv :label="t('property.book')" :value="dashIfEmpty(entity.book)" />
<VnLv :label="t('property.page')" :value="dashIfEmpty(entity.page)" />
<VnLv :label="t('property.farm')" :value="dashIfEmpty(entity.farm)" />
<VnLv
:label="t('property.registration')"
:value="dashIfEmpty(entity.registration)"
/>
</div>
</QCard>
<QCard v-if="entity?.propertyDms.length > 0" class="vn-max">
<VnTitle :url="toPropertyUrl('dms')" :text="t('globals.pageTitles.dms')" />
<QTable :columns="dmsColumns" :rows="entity?.propertyDms" flat>
<template #header="props">
<QTr :props="props">
<QTh auto-width class="text-left">{{ t('globals.id') }}</QTh>
<QTh auto-width class="text-left">{{ t('globals.type') }}</QTh>
<QTh auto-width class="text-left">{{ t('globals.order') }}</QTh>
<QTh auto-width class="text-left">{{ t('globals.reference') }}</QTh>
<QTh auto-width class="text-left">{{ t('globals.description') }}</QTh>
<QTh auto-width class="text-center">{{ t('globals.original') }}</QTh>
<QTh auto-width class="text-left">{{ t('globals.worker') }}</QTh>
<QTh auto-width class="text-center">{{ t('globals.created') }}</QTh>
</QTr>
</template>
<template #body="props">
<QTr :props="props">
<QTd class="text-left">{{ props.row.dms.id }}</QTd>
<QTd class="text-left">{{ props.row.dms.dmsType.name }}</QTd>
<QTd class="text-left">{{ props.row.dms.hardCopyNumber }}</QTd>
<QTd class="text-left">{{ props.row.dms.reference }}</QTd>
<QTd class="text-left">{{ props.row.dms.description }}</QTd>
<QTd class="text-center"><VnCheckbox :disable="true" v-model="props.row.dms.hasFile"/></QTd>
<QTd class="text-left"><span class="link" @click.stop>{{ props.row.dms.worker.firstName }}<WorkerDescriptorProxy :id="props.row.dms.worker.id" /></span></QTd>
<QTd class="text-center">{{ toDate(props.row.dms.created) }}</QTd>
</QTr>
</template>
</QTable>
</QCard>
<QCard v-if="entity?.notes.length > 0" class="vn-max">
<VnTitle :url="toPropertyUrl('notes')" :text="t('globals.notes')" />
<QCardSection
v-if="entity?.notes"
v-for="note in entity?.notes"
horizontal
class="q-pb-sm"
>
<VnAvatar
:descriptor="false"
:worker-id="note.workerFk"
size="md"
:title="note.worker?.user.nickname"
class="q-pr-xs"
/>
<VnUserLink
:name="`${note.worker.user.name}`"
:worker-id="note.worker.id"
/>
<span class="q-pr-xs">{{ ':' }}</span>
<span class="no-margin">
{{ note.text }}
</span>
</QCardSection>
</QCard>
</template>
</CardSummary>
</template>
<style lang="scss" scoped>
.q-card.q-card--dark.q-dark.vn-one {
& > .bodyCard {
padding: 1%;
}
}
.q-table {
tr,
th,
.q-td {
border-bottom: 1px solid black;
}
}
.grafana {
color: $primary-light;
}
</style>