release v2.0.0 #4
|
@ -13,13 +13,15 @@ interface EssentialLink {
|
|||
}
|
||||
|
||||
interface Plugin {
|
||||
router: PluginRouteConfig[];
|
||||
store?: Module<never, never>;
|
||||
name: string;
|
||||
routes: PluginRouteConfig[] | RouteConfig[];
|
||||
store?: Module<never, never>[];
|
||||
mainLink: PluginMainLink;
|
||||
requiredModules: string[];
|
||||
}
|
||||
|
||||
interface PluginMainLink extends PluginChildLink {
|
||||
children: PluginChildLink[] | [];
|
||||
children: PluginChildLink[];
|
||||
}
|
||||
|
||||
interface PluginChildLink {
|
||||
|
@ -29,20 +31,136 @@ interface PluginChildLink {
|
|||
icon: string;
|
||||
}
|
||||
|
||||
const config = {
|
||||
// Do not change required Modules !!
|
||||
requiredModules: ['user'],
|
||||
// here you can import plugins.
|
||||
loadModules: ['plugin1', 'user-plugin']
|
||||
};
|
||||
|
||||
export { PluginRouteConfig, Plugin, PluginChildLink, PluginMainLink };
|
||||
|
||||
function combineRoutes(
|
||||
target: RouteConfig[],
|
||||
source: RouteConfig[]
|
||||
): RouteConfig[] {
|
||||
// iterate first layer e.g. /main, /login etc.
|
||||
source.forEach((sourceRouteConfig: RouteConfig) => {
|
||||
const targetRouteConfig: RouteConfig | undefined = target.find(
|
||||
(routeConfig: RouteConfig) => {
|
||||
return sourceRouteConfig.path == routeConfig.path;
|
||||
}
|
||||
);
|
||||
if (targetRouteConfig) {
|
||||
sourceRouteConfig.children?.forEach(
|
||||
(sourcePluginChildRouteConfig: RouteConfig) => {
|
||||
const targetPluginRouteConfig:
|
||||
| RouteConfig
|
||||
| undefined = targetRouteConfig.children?.find(
|
||||
(routeConfig: RouteConfig) => {
|
||||
return sourcePluginChildRouteConfig.path == routeConfig.path;
|
||||
}
|
||||
);
|
||||
if (targetPluginRouteConfig) {
|
||||
if (targetPluginRouteConfig.children) {
|
||||
targetPluginRouteConfig.children = Object.assign(
|
||||
targetPluginRouteConfig.children,
|
||||
sourcePluginChildRouteConfig.children
|
||||
);
|
||||
} else {
|
||||
targetPluginRouteConfig.children =
|
||||
sourcePluginChildRouteConfig.children;
|
||||
}
|
||||
} else {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
targetRouteConfig.children.push(sourcePluginChildRouteConfig);
|
||||
}
|
||||
}
|
||||
);
|
||||
} else {
|
||||
target.push(sourceRouteConfig);
|
||||
}
|
||||
});
|
||||
return target;
|
||||
}
|
||||
|
||||
function combineMainLinks(
|
||||
target: PluginMainLink[],
|
||||
source: PluginMainLink
|
||||
): PluginMainLink[] {
|
||||
console.log('target', target);
|
||||
console.log('source', source);
|
||||
const targetPluginMainLink: PluginMainLink | undefined = target.find(
|
||||
(targetPluginMainLink: PluginMainLink) => {
|
||||
console.log(targetPluginMainLink.title, source.title);
|
||||
return targetPluginMainLink.title == source.title;
|
||||
}
|
||||
);
|
||||
console.log('targetPluginMainLink', targetPluginMainLink);
|
||||
if (targetPluginMainLink) {
|
||||
source.children.forEach((sourcePluginChildLink: PluginChildLink) => {
|
||||
targetPluginMainLink.children.push(sourcePluginChildLink);
|
||||
});
|
||||
} else {
|
||||
console.log('push source', source);
|
||||
target.push(source);
|
||||
}
|
||||
console.log('merged', target);
|
||||
return target;
|
||||
}
|
||||
|
||||
// "async" is optional;
|
||||
// more info on params: https://quasar.dev/quasar-cli/cli-documentation/boot-files#Anatomy-of-a-boot-file
|
||||
export default boot(({ Vue, router }) => {
|
||||
const plugins = require.context('src/plugins', true, /.+\/plugin.ts$/);
|
||||
const pluginMainLinks: PluginMainLink[] = [];
|
||||
plugins.keys().forEach((fileName: string) => {
|
||||
export default boot(({ Vue, router, store }) => {
|
||||
const pluginsContext = require.context('src/plugins', true, /.+\/plugin.ts$/);
|
||||
let pluginMainLinks: PluginMainLink[] = [];
|
||||
const plugins: Plugin[] = [];
|
||||
pluginsContext.keys().forEach((fileName: string) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
router.addRoutes(plugins(fileName).default.router);
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
pluginMainLinks.push(plugins(fileName).default.mainLink);
|
||||
plugins.push(pluginsContext(fileName).default);
|
||||
});
|
||||
|
||||
let routes: RouteConfig[] = [];
|
||||
|
||||
config.requiredModules.forEach(requiredModule => {
|
||||
const plugin = plugins.find(plugin => {
|
||||
return plugin.name == requiredModule;
|
||||
});
|
||||
if (plugin) {
|
||||
routes = combineRoutes(routes, plugin.routes);
|
||||
if (plugin.store) {
|
||||
plugin.store.forEach(store_module => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
||||
store.registerModule(store_module);
|
||||
});
|
||||
}
|
||||
pluginMainLinks = combineMainLinks(pluginMainLinks, plugin.mainLink);
|
||||
} else {
|
||||
console.exception(`Don't find required Plugin ${requiredModule}`);
|
||||
}
|
||||
});
|
||||
|
||||
config.loadModules.forEach(loadModule => {
|
||||
const plugin = plugins.find(plugin => {
|
||||
return plugin.name == loadModule;
|
||||
});
|
||||
if (plugin) {
|
||||
routes = combineRoutes(routes, plugin.routes);
|
||||
if (plugin.store) {
|
||||
plugin.store.forEach(store_module => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
||||
store.registerModule(store_module);
|
||||
});
|
||||
}
|
||||
pluginMainLinks = combineMainLinks(pluginMainLinks, plugin.mainLink);
|
||||
} else {
|
||||
console.exception(`Don't find Plugin ${loadModule}`);
|
||||
}
|
||||
});
|
||||
console.log(routes);
|
||||
router.addRoutes(routes);
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
Vue.prototype.$flaschengeist_plugins = pluginMainLinks;
|
||||
console.log(plugins);
|
||||
console.log(pluginMainLinks);
|
||||
});
|
||||
|
|
|
@ -103,15 +103,6 @@ import { PluginMainLink } from 'boot/plugins';
|
|||
import { defineComponent, ref, computed } from '@vue/composition-api';
|
||||
|
||||
const links = [
|
||||
{
|
||||
name: 'home',
|
||||
title: 'home',
|
||||
icon: 'mdi-home',
|
||||
children: [
|
||||
{ title: 'Neues Home', link: 'newHome', icon: 'mdi-google-home' },
|
||||
{ title: 'Altes Home', link: 'oldHome', icon: 'mdi-home-modern' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'about',
|
||||
title: 'about',
|
||||
|
@ -162,11 +153,14 @@ export default defineComponent({
|
|||
| PluginMainLink
|
||||
| undefined = ctx.root.$flaschengeist_plugins.find(
|
||||
(plugin: PluginMainLink) => {
|
||||
return plugin.name == ctx.root.$route.matched[1].name;
|
||||
if (ctx.root.$route.matched.length > 1) {
|
||||
return plugin.name == ctx.root.$route.matched[1].name;
|
||||
}
|
||||
}
|
||||
);
|
||||
console.log(test);
|
||||
if (typeof test == undefined) {
|
||||
console.log(typeof test);
|
||||
if (test == undefined) {
|
||||
return [];
|
||||
} else {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
|
|
|
@ -47,7 +47,7 @@ export default defineComponent({
|
|||
|
||||
function doLogin() {
|
||||
console.log(username.value, password.value);
|
||||
void ctx.root.$router.push({ name: 'home' });
|
||||
void ctx.root.$router.push({ name: 'main' });
|
||||
}
|
||||
|
||||
return { username, password, doLogin, rules };
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
<template>
|
||||
<q-page padding class="fit row justify-center content-center items-center">
|
||||
<q-card class="col-4" height="" v-if="$route.name == 'home'">
|
||||
<q-card-section>
|
||||
Home
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
{{ a }}
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
<router-view />
|
||||
</q-page>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from '@vue/composition-api';
|
||||
export default defineComponent({
|
||||
// name: 'PageName'
|
||||
setup(_, ctx) {
|
||||
const a = ctx.root.$flaschengeist_plugins;
|
||||
return { a };
|
||||
}
|
||||
});
|
||||
</script>
|
|
@ -1,14 +0,0 @@
|
|||
<template>
|
||||
<q-card class="col-4" height="">
|
||||
<q-card-section>
|
||||
Neues Zuhause
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from '@vue/composition-api';
|
||||
export default defineComponent({
|
||||
// name: 'PageName'
|
||||
});
|
||||
</script>
|
|
@ -1,14 +0,0 @@
|
|||
<template>
|
||||
<q-card class="col-4" height="">
|
||||
<q-card-section>
|
||||
Altes Zuhause
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from '@vue/composition-api';
|
||||
export default defineComponent({
|
||||
// name: 'PageName'
|
||||
});
|
||||
</script>
|
|
@ -1,30 +0,0 @@
|
|||
import { Plugin } from 'boot/plugins';
|
||||
import routes from 'src/plugins/plugin-example-2/routes';
|
||||
|
||||
const plugin: Plugin = {
|
||||
router: routes,
|
||||
mainLink: {
|
||||
name: 'plugin2',
|
||||
title: 'Plugin2',
|
||||
link: 'plugin2',
|
||||
icon: 'mdi-toy-brick-plus',
|
||||
children: [
|
||||
{
|
||||
name: 'plugin2',
|
||||
title: 'Neues Plugin2',
|
||||
link: 'plugin2_1',
|
||||
icon: 'mdi-information-outline'
|
||||
},
|
||||
{
|
||||
name: 'plugin2',
|
||||
title: 'Altes Plugin2',
|
||||
link: 'plugin2_2',
|
||||
icon: 'mdi-information-variant'
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
const mainLink = plugin.mainLink;
|
||||
export { mainLink };
|
||||
export default plugin;
|
|
@ -1,31 +1,33 @@
|
|||
import { Plugin } from 'boot/plugins';
|
||||
import { Plugin, PluginMainLink } from 'boot/plugins';
|
||||
import routes from 'src/plugins/plugin-example/routes';
|
||||
|
||||
const plugin: Plugin = {
|
||||
router: routes,
|
||||
mainLink: {
|
||||
name: 'plugin1',
|
||||
title: 'Plugin1',
|
||||
link: 'plugin1',
|
||||
icon: 'mdi-toy-brick',
|
||||
children: [
|
||||
{
|
||||
name: 'plugin1',
|
||||
title: 'Neues Plugin1',
|
||||
link: 'plugin1_1',
|
||||
icon: 'mdi-information-outline'
|
||||
},
|
||||
{
|
||||
name: 'plugin1',
|
||||
title: 'Altes Plugin1',
|
||||
link: 'plugin1_2',
|
||||
icon: 'mdi-information-variant'
|
||||
}
|
||||
]
|
||||
}
|
||||
const mainLink: PluginMainLink = {
|
||||
name: 'plugin1',
|
||||
title: 'Plugin1',
|
||||
link: 'plugin1',
|
||||
icon: 'mdi-toy-brick',
|
||||
children: [
|
||||
{
|
||||
name: 'plugin1',
|
||||
title: 'Neues Plugin1',
|
||||
link: 'plugin1_1',
|
||||
icon: 'mdi-information-outline'
|
||||
},
|
||||
{
|
||||
name: 'plugin1',
|
||||
title: 'Altes Plugin1',
|
||||
link: 'plugin1_2',
|
||||
icon: 'mdi-information-variant'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const mainLink = plugin.mainLink;
|
||||
const plugin: Plugin = {
|
||||
routes,
|
||||
mainLink,
|
||||
name: mainLink.name,
|
||||
requiredModules: []
|
||||
};
|
||||
|
||||
export { mainLink };
|
||||
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
import { Plugin, PluginMainLink } from 'boot/plugins';
|
||||
import routes from './routes';
|
||||
|
||||
const mainLink: PluginMainLink = {
|
||||
name: 'user-plugin',
|
||||
title: 'User',
|
||||
link: 'user',
|
||||
icon: 'mdi-account',
|
||||
children: [
|
||||
{
|
||||
name: 'user-plugin',
|
||||
title: 'Erstes Plugin für User',
|
||||
link: 'user-plugin1',
|
||||
icon: 'mdi-account-plus'
|
||||
},
|
||||
{
|
||||
name: 'user-plugin',
|
||||
title: 'Zweites Plugin für User',
|
||||
link: 'user-plugin2',
|
||||
icon: 'mdi-account-minus'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const plugin: Plugin = {
|
||||
routes,
|
||||
mainLink,
|
||||
name: mainLink.name,
|
||||
requiredModules: ['user']
|
||||
};
|
||||
|
||||
export { mainLink };
|
||||
export default plugin;
|
|
@ -8,21 +8,18 @@ const routes: RouteConfig[] = [
|
|||
},
|
||||
children: [
|
||||
{
|
||||
path: 'plugin2',
|
||||
name: 'plugin2',
|
||||
components: {
|
||||
default: () => import('../pages/Plugin.vue'),
|
||||
'plugin-nav': () => import('../components/navigation/PluginLinks.vue')
|
||||
},
|
||||
path: 'user',
|
||||
name: 'user',
|
||||
component: () => import('src/plugins/user/pages/User.vue'),
|
||||
children: [
|
||||
{
|
||||
path: 'plugin2_1',
|
||||
name: 'plugin2_1',
|
||||
path: 'user-plugin',
|
||||
name: 'user-plugin1',
|
||||
component: () => import('../pages/NewPlugin.vue')
|
||||
},
|
||||
{
|
||||
path: 'plugin2_2',
|
||||
name: 'plugin2_2',
|
||||
path: 'user-plugin2',
|
||||
name: 'user-plugin2',
|
||||
component: () => import('../pages/OldPlugin.vue')
|
||||
}
|
||||
]
|
|
@ -0,0 +1,28 @@
|
|||
<template>
|
||||
<div>
|
||||
<q-page
|
||||
padding
|
||||
class="fit row justify-center content-center items-center"
|
||||
v-if="$route.name == mainLink.link"
|
||||
>
|
||||
<q-card class="col-4" height="">
|
||||
<q-card-section>
|
||||
{{ mainLink.title }}
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-page>
|
||||
<router-view />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from '@vue/composition-api';
|
||||
import { mainLink } from '../plugin';
|
||||
export default defineComponent({
|
||||
// name: 'PageName'
|
||||
setup(_, ctx) {
|
||||
const a = ctx.root.$flaschengeist_plugins;
|
||||
return { a, mainLink };
|
||||
}
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,21 @@
|
|||
import { Plugin, PluginMainLink } from 'boot/plugins';
|
||||
import routes from './routes';
|
||||
|
||||
const mainLink: PluginMainLink = {
|
||||
name: 'user',
|
||||
title: 'User',
|
||||
link: 'user',
|
||||
icon: 'mdi-account',
|
||||
children: []
|
||||
};
|
||||
|
||||
const plugin: Plugin = {
|
||||
routes,
|
||||
mainLink,
|
||||
name: mainLink.name,
|
||||
requiredModules: []
|
||||
};
|
||||
|
||||
export { mainLink };
|
||||
|
||||
export default plugin;
|
|
@ -0,0 +1,17 @@
|
|||
import { RouteConfig } from 'vue-router';
|
||||
|
||||
const routes: RouteConfig[] = [
|
||||
{
|
||||
path: '/main',
|
||||
component: () => import('layouts/MainLayout.vue'),
|
||||
children: [
|
||||
{
|
||||
path: 'user',
|
||||
name: 'user',
|
||||
component: () => import('../pages/User.vue')
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
export default routes;
|
|
@ -15,25 +15,9 @@ const routes: RouteConfig[] = [
|
|||
},
|
||||
{
|
||||
path: '/main',
|
||||
name: 'main',
|
||||
component: () => import('layouts/MainLayout.vue'),
|
||||
children: [
|
||||
{
|
||||
name: 'home',
|
||||
path: 'home',
|
||||
component: () => import('pages/home/Home.vue'),
|
||||
children: [
|
||||
{
|
||||
name: 'newHome',
|
||||
path: 'newHome',
|
||||
component: () => import('pages/home/NewHome.vue')
|
||||
},
|
||||
{
|
||||
name: 'oldHome',
|
||||
path: 'oldHome',
|
||||
component: () => import('pages/home/OldHome.vue')
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'about',
|
||||
path: 'about',
|
||||
|
|
Loading…
Reference in New Issue