feat: refs #8197 better leftMenu and VnCardMain improvements
gitea/salix-front/pipeline/pr-master There was a failure building this commit Details

This commit is contained in:
Alex Moreno 2024-12-16 09:41:50 +01:00
parent 1b1aa8e488
commit 5d744ca456
10 changed files with 108 additions and 77 deletions

View File

@ -92,13 +92,11 @@ function findMatches(search, item) {
}
function addChildren(module, route, parent) {
if (route.menus) {
const mainMenus = route.menus[props.source];
const matches = findMatches(mainMenus, route);
if (!route?.meta?.menu) return;
const matches = findMatches(route.meta.menu, route);
for (const child of matches) {
navigation.addMenuItem(module, child, parent);
}
for (const child of matches) {
navigation.addMenuItem(module, child, parent);
}
}
@ -120,15 +118,14 @@ function getRoutes() {
}
if (props.source === 'card') {
const currentRoute = route.matched[1];
const currentModule = toLowerCamel(currentRoute.name);
const moduleDef = routes.find(
(route) => toLowerCamel(route.name) === currentModule
);
let menuRoute;
let index = route.matched.length - 1;
if (!moduleDef) return;
addChildren(currentModule, moduleDef, items.value);
while (!menuRoute && index > 0) {
if (route.matched[index]?.meta?.menu) menuRoute = route.matched[index];
index--;
}
addChildren('', menuRoute, items.value);
}
}

View File

@ -15,7 +15,7 @@ let root = ref(null);
watchEffect(() => {
matched.value = currentRoute.value.matched.filter(
(matched) => Object.keys(matched.meta).length
(matched) => !!matched?.meta?.title || !!matched?.meta?.icon
);
breadcrumbs.value.length = 0;
if (!matched.value[0]) return;

View File

@ -2,25 +2,78 @@
import LeftMenu from '../LeftMenu.vue';
import { useStateStore } from 'stores/useStateStore';
import RightMenu from './RightMenu.vue';
import VnSearchbar from 'components/ui/VnSearchbar.vue';
import VnTableFilter from '../VnTable/VnTableFilter.vue';
import { onBeforeMount } from 'vue';
import { useArrayData } from 'src/composables/useArrayData';
const stateStore = useStateStore();
defineProps({
const $props = defineProps({
section: {
type: String,
required: true,
},
dataKey: {
type: String,
default: null,
},
searchBar: {
type: Boolean,
default: true,
},
prefix: {
type: String,
default: null,
},
rightFilter: {
type: Boolean,
default: true,
},
columns: {
type: Array,
default: null,
},
arrayDataProps: {
type: Object,
default: null,
},
});
onBeforeMount(() => {
if ($props.dataKey)
useArrayData($props.dataKey, {
searchUrl: 'table',
...$props.arrayDataProps,
});
});
</script>
<template>
<slot name="searchbar" />
<slot name="searchbar">
<VnSearchbar
v-if="searchBar"
v-bind="arrayDataProps"
:data-key="dataKey"
:label="$t(`${prefix}.search`)"
:info="$t(`${prefix}.searchInfo`)"
/>
</slot>
<Teleport to="#left-panel" v-if="stateStore.isHeaderMounted()">
<LeftMenu v-if="section == $route.name" />
</Teleport>
<slot name="body" v-if="section == $route.name" />
<RouterView v-else />
<RightMenu>
<template #right-panel v-if="$slots['rightMenu']">
<slot name="rightMenu" />
<template #right-panel v-if="$slots['rightMenu'] || rightFilter">
<slot name="rightMenu">
<VnTableFilter
v-if="rightFilter && columns"
:data-key="dataKey"
:columns="columns"
/>
</slot>
</template>
</RightMenu>
<slot name="body" v-if="section == $route.name" />
<RouterView v-else />
</template>

View File

@ -1,22 +1,17 @@
<script setup>
import { useI18n } from 'vue-i18n';
import { ref, computed, onBeforeMount } from 'vue';
import { computed } from 'vue';
import VnTable from 'components/VnTable/VnTable.vue';
import VnSearchbar from 'components/ui/VnSearchbar.vue';
import AccountSummary from './Card/AccountSummary.vue';
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
import VnCardMain from 'src/components/common/VnCardMain.vue';
import VnTableFilter from 'src/components/VnTable/VnTableFilter.vue';
import { useArrayData } from 'src/composables/useArrayData';
const { t } = useI18n();
const { viewSummary } = useSummaryDialog();
const tableRef = ref();
const filter = {
include: { relation: 'role', scope: { fields: ['id', 'name'] } },
};
const dataKey = 'AccountList';
const url = 'VnUsers/preview';
const columns = computed(() => [
{
align: 'left',
@ -87,15 +82,6 @@ const columns = computed(() => [
},
]);
onBeforeMount(() => {
useArrayData(dataKey, {
url,
userFilter: filter,
order: 'id DESC',
exprBuilder,
searchUrl: 'table',
});
});
function exprBuilder(param, value) {
switch (param) {
case 'search':
@ -117,17 +103,20 @@ function exprBuilder(param, value) {
</script>
<template>
<VnCardMain :section="dataKey">
<template #searchbar>
<VnSearchbar
:data-key="dataKey"
:label="t('account.search')"
:info="t('account.searchInfo')"
/>
</template>
<VnCardMain
:section="dataKey"
:data-key="dataKey"
:columns="columns"
prefix="account"
:array-data-props="{
url: 'VnUsers/preview',
userFilter: filter,
order: 'id DESC',
exprBuilder,
}"
>
<template #body>
<VnTable
ref="tableRef"
:data-key="dataKey"
:columns="columns"
default-mode="table"
@ -136,9 +125,6 @@ function exprBuilder(param, value) {
:right-search="false"
/>
</template>
<template #rightMenu>
<VnTableFilter :data-key="dataKey" :columns="columns" />
</template>
</VnCardMain>
</template>

View File

@ -3,7 +3,6 @@ import { useI18n } from 'vue-i18n';
import { computed, ref } from 'vue';
import VnTable from 'components/VnTable/VnTable.vue';
import { useRoute } from 'vue-router';
import VnSearchbar from 'components/ui/VnSearchbar.vue';
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
import RoleSummary from './Card/RoleSummary.vue';
import VnCardMain from 'src/components/common/VnCardMain.vue';
@ -86,21 +85,17 @@ const exprBuilder = (param, value) => {
</script>
<template>
<VnCardMain :section="dataKey">
<template #searchbar>
<VnSearchbar
:url="url"
:data-key="dataKey"
:expr-builder="exprBuilder"
:label="t('role.searchRoles')"
:info="t('role.searchInfo')"
/>
</template>
<VnCardMain
:section="dataKey"
:data-key="dataKey"
:columns="columns"
prefix="role"
:array-data-props="{ url, exprBuilder, order: 'id ASC' }"
>
<template #body>
<VnTable
ref="tableRef"
:data-key="dataKey"
:url="url"
:create="{
urlCreate: 'VnRoles',
title: t('Create rol'),
@ -109,7 +104,6 @@ const exprBuilder = (param, value) => {
editorFk: entityId,
},
}"
order="id ASC"
:disable-option="{ card: true }"
:columns="columns"
default-mode="table"

View File

@ -66,7 +66,7 @@ account:
mailInputInfo: All emails will be forwarded to the specified address.
role:
newRole: New role
searchRoles: Search role
search: Search role
searchInfo: Search role by id or name
description: Description
id: Id

View File

@ -1,7 +1,6 @@
import { RouterView } from 'vue-router';
import accountCard from './account/accountCard';
import roleCard from './account/roleCard';
import getSections from 'src/utils/getSections';
export default {
path: '/account',
@ -11,11 +10,7 @@ export default {
icon: 'face',
moduleName: 'Account',
keyBinding: 'u',
},
component: RouterView,
redirect: { name: 'AccountMain' },
menus: {
main: [
menu: [
'AccountList',
'AccountAliasList',
'AccountRoles',
@ -25,8 +20,9 @@ export default {
'AccountAcls',
'AccountConnections',
],
card: getSections(accountCard.children),
},
component: RouterView,
redirect: { name: 'AccountMain' },
children: [
{
path: '',

View File

@ -3,6 +3,16 @@ export default {
path: ':id',
redirect: { name: 'AccountSummary' },
component: () => import('src/pages/Account/Card/AccountCard.vue'),
meta: {
menu: [
'AccountBasicData',
'AccountInheritedRoles',
'AccountMailForwarding',
'AccountMailAlias',
'AccountPrivileges',
'AccountLog',
],
},
children: [
{
name: 'AccountSummary',

View File

@ -3,6 +3,9 @@ export default {
path: ':id',
component: () => import('src/pages/Account/Role/Card/RoleCard.vue'),
redirect: { name: 'RoleSummary' },
meta: {
menu: ['RoleBasicData', 'SubRoles', 'InheritedRoles', 'RoleLog'],
},
children: [
{
name: 'RoleSummary',

View File

@ -1,8 +0,0 @@
export default (sections) => {
const names = [];
for (const section of sections) {
if (section.path == 'summary') continue;
names.push(section.name);
}
return names;
};