Merge pull request 'refactor: refs #8197 backward compatible' (!1091) from 8197-VnCardMain_backwardCompatibility into 8197-VnCardMain
gitea/salix-front/pipeline/pr-beta There was a failure building this commit
Details
gitea/salix-front/pipeline/pr-beta There was a failure building this commit
Details
Reviewed-on: #1091
This commit is contained in:
commit
3bd028aa20
|
@ -92,8 +92,10 @@ function findMatches(search, item) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function addChildren(module, route, parent) {
|
function addChildren(module, route, parent) {
|
||||||
if (!route?.meta?.menu) return;
|
const menus = route?.meta?.menu ?? route?.menus?.[props.source]; //backwards compatible
|
||||||
const matches = findMatches(route.meta.menu, route);
|
if (!menus) return;
|
||||||
|
|
||||||
|
const matches = findMatches(menus, route);
|
||||||
|
|
||||||
for (const child of matches) {
|
for (const child of matches) {
|
||||||
navigation.addMenuItem(module, child, parent);
|
navigation.addMenuItem(module, child, parent);
|
||||||
|
@ -118,17 +120,28 @@ function getRoutes() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (props.source === 'card') {
|
if (props.source === 'card') {
|
||||||
let menuRoute;
|
const currentRoute = route.matched[1];
|
||||||
let index = route.matched.length - 1;
|
const currentModule = toLowerCamel(currentRoute.name);
|
||||||
|
let moduleDef = routes.find(
|
||||||
|
(route) => toLowerCamel(route.name) === currentModule
|
||||||
|
);
|
||||||
|
|
||||||
while (!menuRoute && index > 0) {
|
if (!moduleDef) return;
|
||||||
if (route.matched[index]?.meta?.menu) menuRoute = route.matched[index];
|
if (!moduleDef?.menus) moduleDef = betaGetRoutes();
|
||||||
index--;
|
addChildren(currentModule, moduleDef, items.value);
|
||||||
}
|
|
||||||
addChildren('', menuRoute, items.value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function betaGetRoutes() {
|
||||||
|
let menuRoute;
|
||||||
|
let index = route.matched.length - 1;
|
||||||
|
while (!menuRoute && index > 0) {
|
||||||
|
if (route.matched[index]?.meta?.menu) menuRoute = route.matched[index];
|
||||||
|
index--;
|
||||||
|
}
|
||||||
|
return menuRoute;
|
||||||
|
}
|
||||||
|
|
||||||
async function togglePinned(item, event) {
|
async function togglePinned(item, event) {
|
||||||
if (event.defaultPrevented) return;
|
if (event.defaultPrevented) return;
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
|
@ -4,7 +4,10 @@ import { useRoute, useRouter, onBeforeRouteUpdate } from 'vue-router';
|
||||||
import { useArrayData } from 'src/composables/useArrayData';
|
import { useArrayData } from 'src/composables/useArrayData';
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
import useCardSize from 'src/composables/useCardSize';
|
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 LeftMenu from 'components/LeftMenu.vue';
|
||||||
|
import RightMenu from 'components/common/RightMenu.vue';
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
dataKey: { type: String, required: true },
|
dataKey: { type: String, required: true },
|
||||||
baseUrl: { type: String, default: undefined },
|
baseUrl: { type: String, default: undefined },
|
||||||
|
@ -26,7 +29,10 @@ const url = computed(() => {
|
||||||
}
|
}
|
||||||
return props.customUrl;
|
return props.customUrl;
|
||||||
});
|
});
|
||||||
|
const searchRightDataKey = computed(() => {
|
||||||
|
if (!props.searchDataKey) return route.name;
|
||||||
|
return props.searchDataKey;
|
||||||
|
});
|
||||||
const arrayData = useArrayData(props.dataKey, {
|
const arrayData = useArrayData(props.dataKey, {
|
||||||
url: url.value,
|
url: url.value,
|
||||||
filter: props.filter,
|
filter: props.filter,
|
||||||
|
@ -53,13 +59,32 @@ if (props.baseUrl) {
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<Teleport to="#left-panel" v-if="stateStore.isHeaderMounted()">
|
<QDrawer
|
||||||
<component :is="descriptor" />
|
v-model="stateStore.leftDrawer"
|
||||||
<QSeparator />
|
show-if-above
|
||||||
<LeftMenu source="card" />
|
:width="256"
|
||||||
</Teleport>
|
v-if="stateStore.isHeaderMounted()"
|
||||||
<VnSubToolbar />
|
>
|
||||||
<div :class="[useCardSize(), $attrs.class]">
|
<QScrollArea class="fit">
|
||||||
<RouterView :key="route.path" />
|
<component :is="descriptor" />
|
||||||
</div>
|
<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.path" />
|
||||||
|
</div>
|
||||||
|
</QPage>
|
||||||
|
</QPageContainer>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
<script setup>
|
||||||
|
import { onBeforeMount, computed } from 'vue';
|
||||||
|
import { useRoute, useRouter, onBeforeRouteUpdate } from 'vue-router';
|
||||||
|
import { useArrayData } from 'src/composables/useArrayData';
|
||||||
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
|
import useCardSize from 'src/composables/useCardSize';
|
||||||
|
import LeftMenu from 'components/LeftMenu.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 },
|
||||||
|
redirectOnError: { type: Boolean, default: false },
|
||||||
|
});
|
||||||
|
|
||||||
|
const stateStore = useStateStore();
|
||||||
|
const route = useRoute();
|
||||||
|
const router = useRouter();
|
||||||
|
const url = computed(() => {
|
||||||
|
if (props.baseUrl) {
|
||||||
|
return `${props.baseUrl}/${route.params.id}`;
|
||||||
|
}
|
||||||
|
return props.customUrl;
|
||||||
|
});
|
||||||
|
|
||||||
|
const arrayData = useArrayData(props.dataKey, {
|
||||||
|
url: url.value,
|
||||||
|
filter: props.filter,
|
||||||
|
});
|
||||||
|
|
||||||
|
onBeforeMount(async () => {
|
||||||
|
try {
|
||||||
|
if (!props.baseUrl) arrayData.store.filter.where = { id: route.params.id };
|
||||||
|
await arrayData.fetch({ append: false, updateRouter: false });
|
||||||
|
} catch {
|
||||||
|
const { matched: matches } = router.currentRoute.value;
|
||||||
|
const { path } = matches.at(-1);
|
||||||
|
router.push({ path: path.replace(/:id.*/, '') });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
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>
|
||||||
|
<Teleport to="#left-panel" v-if="stateStore.isHeaderMounted()">
|
||||||
|
<component :is="descriptor" />
|
||||||
|
<QSeparator />
|
||||||
|
<LeftMenu source="card" />
|
||||||
|
</Teleport>
|
||||||
|
<VnSubToolbar />
|
||||||
|
<div :class="[useCardSize(), $attrs.class]">
|
||||||
|
<RouterView :key="route.path" />
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -1,12 +1,12 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import VnCard from 'components/common/VnCard.vue';
|
import VnCardBeta from 'components/common/VnCardBeta.vue';
|
||||||
import AliasDescriptor from './AliasDescriptor.vue';
|
import AliasDescriptor from './AliasDescriptor.vue';
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VnCard
|
<VnCardBeta
|
||||||
data-key="Alias"
|
data-key="Alias"
|
||||||
base-url="MailAliases"
|
base-url="MailAliases"
|
||||||
:descriptor="AliasDescriptor"
|
:descriptor="AliasDescriptor"
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import VnCard from 'components/common/VnCard.vue';
|
import VnCardBeta from 'components/common/VnCardBeta.vue';
|
||||||
import AccountDescriptor from './AccountDescriptor.vue';
|
import AccountDescriptor from './AccountDescriptor.vue';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VnCard data-key="AccountId" :descriptor="AccountDescriptor" />
|
<VnCardBeta data-key="AccountId" :descriptor="AccountDescriptor" />
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import VnCard from 'components/common/VnCard.vue';
|
import VnCardBeta from 'components/common/VnCardBeta.vue';
|
||||||
import RoleDescriptor from './RoleDescriptor.vue';
|
import RoleDescriptor from './RoleDescriptor.vue';
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<VnCard data-key="Role" :descriptor="RoleDescriptor" />
|
<VnCardBeta data-key="Role" :descriptor="RoleDescriptor" />
|
||||||
</template>
|
</template>
|
||||||
|
|
Loading…
Reference in New Issue