81 lines
2.7 KiB
Vue
81 lines
2.7 KiB
Vue
<script setup>
|
|
import { onBeforeMount, computed } from 'vue';
|
|
import { useRoute, onBeforeRouteUpdate } from 'vue-router';
|
|
import { useArrayData } from 'src/composables/useArrayData';
|
|
import { useStateStore } from 'stores/useStateStore';
|
|
import useCardSize from 'src/composables/useCardSize';
|
|
import VnSubToolbar from '../ui/VnSubToolbar.vue';
|
|
import VnSearchbar from 'components/ui/VnSearchbar.vue';
|
|
import LeftMenu from 'components/LeftMenu.vue';
|
|
import RightMenu from 'components/common/RightMenu.vue';
|
|
const props = defineProps({
|
|
dataKey: { type: String, required: true },
|
|
baseUrl: { type: String, default: undefined },
|
|
customUrl: { type: String, default: undefined },
|
|
filter: { type: Object, default: () => {} },
|
|
descriptor: { type: Object, required: true },
|
|
filterPanel: { type: Object, default: undefined },
|
|
searchDataKey: { type: String, default: undefined },
|
|
searchbarProps: { type: Object, default: undefined },
|
|
});
|
|
|
|
const stateStore = useStateStore();
|
|
const route = useRoute();
|
|
const url = computed(() => {
|
|
if (props.baseUrl) return `${props.baseUrl}/${route.params.id}`;
|
|
return props.customUrl;
|
|
});
|
|
const searchRightDataKey = computed(() => {
|
|
if (!props.searchDataKey) return route.name;
|
|
return props.searchDataKey;
|
|
});
|
|
const arrayData = useArrayData(props.dataKey, {
|
|
url: url.value,
|
|
filter: props.filter,
|
|
});
|
|
|
|
onBeforeMount(async () => {
|
|
if (!props.baseUrl) arrayData.store.filter.where = { id: route.params.id };
|
|
await arrayData.fetch({ append: false, updateRouter: false });
|
|
});
|
|
|
|
if (props.baseUrl) {
|
|
onBeforeRouteUpdate(async (to, from) => {
|
|
if (to.params.id !== from.params.id) {
|
|
arrayData.store.url = `${props.baseUrl}/${to.params.id}`;
|
|
await arrayData.fetch({ append: false, updateRouter: false });
|
|
}
|
|
});
|
|
}
|
|
</script>
|
|
<template>
|
|
<QDrawer
|
|
v-model="stateStore.leftDrawer"
|
|
show-if-above
|
|
:width="256"
|
|
v-if="stateStore.isHeaderMounted()"
|
|
>
|
|
<QScrollArea class="fit">
|
|
<component :is="descriptor" />
|
|
<QSeparator />
|
|
<LeftMenu source="card" />
|
|
</QScrollArea>
|
|
</QDrawer>
|
|
<slot name="searchbar" v-if="props.searchDataKey">
|
|
<VnSearchbar :data-key="props.searchDataKey" v-bind="props.searchbarProps" />
|
|
</slot>
|
|
<RightMenu>
|
|
<template #right-panel v-if="props.filterPanel">
|
|
<component :is="props.filterPanel" :data-key="searchRightDataKey" />
|
|
</template>
|
|
</RightMenu>
|
|
<QPageContainer>
|
|
<QPage>
|
|
<VnSubToolbar />
|
|
<div :class="[useCardSize(), $attrs.class]">
|
|
<RouterView :key="route.fullPath" />
|
|
</div>
|
|
</QPage>
|
|
</QPageContainer>
|
|
</template>
|