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

86 lines
1.9 KiB
Vue

<script setup>
import { watch, ref, onMounted } from 'vue';
import { useArrayData } from 'composables/useArrayData';
import VnDescriptor from './VnDescriptor.vue';
const $props = defineProps({
url: {
type: String,
default: '',
},
filter: {
type: Object,
default: null,
},
dataKey: {
type: String,
default: null,
},
});
let arrayData;
let store;
const entity = ref();
const isLoading = ref(false);
const containerRef = ref(null);
onMounted(async () => {
let isPopup;
let el = containerRef.value.$el;
while (el) {
if (el.classList?.contains('q-menu')) {
isPopup = true;
break;
}
el = el.parentElement;
}
arrayData = useArrayData($props.dataKey + (isPopup ? 'Proxy' : ''), {
url: $props.url,
userFilter: $props.filter,
skip: 0,
oneRecord: true,
});
store = arrayData.store;
watch(
() => [$props.url, $props.filter],
async () => {
await getData();
},
{ immediate: true },
);
watch(
() => arrayData.store.data,
(newValue) => {
entity.value = newValue;
},
);
});
defineExpose({ getData });
const emit = defineEmits(['onFetch']);
async function getData() {
store.url = $props.url;
store.filter = $props.filter ?? {};
isLoading.value = true;
try {
await arrayData.fetch({ append: false, updateRouter: false });
const { data } = store;
emit('onFetch', data);
} finally {
isLoading.value = false;
}
}
</script>
<template>
<VnDescriptor v-model="entity" v-bind="$attrs" :module="dataKey" ref="containerRef">
<template v-for="(_, slotName) in $slots" #[slotName]="slotData" :key="slotName">
<slot :name="slotName" v-bind="slotData ?? {}" :key="slotName" />
</template>
</VnDescriptor>
</template>