salix-front/src/components/common/VnCard.vue

83 lines
2.7 KiB
Vue

<script setup>
import { onBeforeMount, computed } from 'vue';
import { useRoute, useRouter, onBeforeRouteUpdate, onBeforeRouteLeave } 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';
const emit = defineEmits(['onFetch']);
const props = defineProps({
id: { type: Number, required: false, default: null },
dataKey: { type: String, required: true },
url: { type: String, default: undefined },
idInWhere: { type: Boolean, default: false },
filter: { type: Object, default: () => {} },
descriptor: { type: Object, required: true },
filterPanel: { type: Object, default: undefined },
searchDataKey: { type: String, default: undefined },
searchbarProps: { type: Object, default: undefined },
redirectOnError: { type: Boolean, default: false },
visual: { type: Boolean, default: true },
});
const route = useRoute();
const stateStore = useStateStore();
const router = useRouter();
const entityId = computed(() => props.id || route?.params?.id);
const arrayData = useArrayData(props.dataKey, {
url: props.url,
userFilter: props.filter,
oneRecord: true,
});
onBeforeRouteLeave(() => {
stateStore.cardDescriptorChangeValue(null);
});
onBeforeMount(async () => {
stateStore.cardDescriptorChangeValue(props.descriptor);
const route = router.currentRoute.value;
try {
await fetch(entityId.value);
} catch {
const { matched: matches } = route;
const { path } = matches.at(-1);
router.push({ path: path.replace(/:id.*/, '') });
}
});
onBeforeRouteUpdate(async (to, from) => {
if (hasRouteParam(to.params)) {
const { matched } = router.currentRoute.value;
const { name } = matched.at(-3);
if (name) {
router.push({ name, params: to.params });
}
}
if (entityId.value !== to.params.id) await fetch(to.params.id, true);
});
async function fetch(id, append = false) {
const regex = /\/(\d+)/;
if (props.idInWhere) arrayData.store.filter.where = { id };
else if (!regex.test(props.url)) arrayData.store.url = `${props.url}/${id}`;
else arrayData.store.url = props.url.replace(regex, `/${id}`);
await arrayData.fetch({ append, updateRouter: false });
emit('onFetch', arrayData.store.data);
}
function hasRouteParam(params, valueToCheck = ':addressId') {
return Object.values(params).includes(valueToCheck);
}
</script>
<template>
<template v-if="visual">
<VnSubToolbar />
<div :class="[useCardSize(), $attrs.class]">
<RouterView :key="$route.path" />
</div>
</template>
</template>