salix-front/src/components/ui/CardDescriptor.vue

130 lines
3.5 KiB
Vue

<script setup>
import { onMounted, useSlots, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import axios from 'axios';
import SkeletonDescriptor from 'components/ui/SkeletonDescriptor.vue';
const props = defineProps({
url: {
type: String,
default: '',
},
filter: {
type: Object,
default: null,
},
module: {
type: String,
required: true,
}
});
const slots = useSlots();
const { t } = useI18n();
onMounted(() => fetch());
const entity = ref();
async function fetch() {
const params = {};
if (props.filter) params.filter = props.filter;
const { data } = await axios.get(props.url, { params });
entity.value = data;
}
watch(props, async () => {
entity.value = null;
await fetch();
});
</script>
<template>
<div class="descriptor">
<template v-if="entity">
<div class="header bg-primary q-pa-sm">
<router-link :to="{ name: `${module}List` }">
<q-btn round flat dense size="md" icon="view_list" color="white">
<q-tooltip>{{
t('components.cardDescriptor.mainList')
}}</q-tooltip>
</q-btn>
</router-link>
<router-link
:to="{ name: `${module}Summary`, params: { id: entity.id } }"
>
<q-btn round flat dense size="md" icon="launch" color="white">
<q-tooltip>{{
t('components.cardDescriptor.summary')
}}</q-tooltip>
</q-btn>
</router-link>
<q-btn
v-if="slots.menu"
size="md"
icon="more_vert"
color="white"
round
flat
dense
>
<q-tooltip>
{{ t('components.cardDescriptor.moreOptions') }}
</q-tooltip>
<q-menu>
<q-list>
<slot name="menu" :entity="entity" />
</q-list>
</q-menu>
</q-btn>
</div>
<div class="body q-py-sm">
<q-list>
<q-item-label header class="ellipsis text-h5" :lines="1">
<slot name="description" :entity="entity">
<span>
{{ entity.name }}
<q-tooltip>{{ entity.name }}</q-tooltip>
</span>
</slot>
</q-item-label>
<q-item dense>
<q-item-label class="text-subtitle2" caption>
#{{ entity.id }}
</q-item-label>
</q-item>
</q-list>
<slot name="body" :entity="entity" />
</div>
</template>
<!-- Skeleton -->
<skeleton-descriptor v-if="!entity" />
</div>
</template>
<style lang="scss">
.body {
.q-card__actions {
justify-content: center;
}
.text-h5 {
padding-top: 5px;
padding-bottom: 5px;
}
}
</style>
<style lang="scss" scoped>
.descriptor {
width: 256px;
.header {
display: flex;
justify-content: space-between;
align-items: stretch;
}
}
</style>