From c5799967aff0158b59fdf52a404faa9185b13d16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Gr=C3=B6ger?= Date: Tue, 13 Oct 2020 20:17:00 +0200 Subject: [PATCH] =?UTF-8?q?Plugins=20f=C3=BCr=20Plugins=20m=C3=B6glich.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Man kann nun Plugins für Plugins schreiben. Dabei können die Routes vom ursprünglichen Plugin überschrieben werden. Außerdem wird unterschieden zwischen required und optional (loadPlugins) Plugins. routes werden nun kombiniert und die MainLinks ebenfalls. --- src/boot/plugins.ts | 140 ++++++++++++++++-- src/layouts/MainLayout.vue | 16 +- src/pages/Login.vue | 2 +- src/pages/home/Home.vue | 24 --- src/pages/home/NewHome.vue | 14 -- src/pages/home/OldHome.vue | 14 -- src/plugins/plugin-example-2/plugin.ts | 30 ---- src/plugins/plugin-example/plugin.ts | 50 ++++--- .../components/navigation/PluginLinks.vue | 0 .../pages/NewPlugin.vue | 0 .../pages/OldPlugin.vue | 0 .../pages/Plugin.vue | 0 src/plugins/user-plugin/plugin.ts | 33 +++++ .../routes/index.ts | 17 +-- src/plugins/user/pages/User.vue | 28 ++++ src/plugins/user/plugin.ts | 21 +++ src/plugins/user/routes/index.ts | 17 +++ src/router/routes.ts | 18 +-- 18 files changed, 268 insertions(+), 156 deletions(-) delete mode 100644 src/pages/home/Home.vue delete mode 100644 src/pages/home/NewHome.vue delete mode 100644 src/pages/home/OldHome.vue delete mode 100644 src/plugins/plugin-example-2/plugin.ts rename src/plugins/{plugin-example-2 => user-plugin}/components/navigation/PluginLinks.vue (100%) rename src/plugins/{plugin-example-2 => user-plugin}/pages/NewPlugin.vue (100%) rename src/plugins/{plugin-example-2 => user-plugin}/pages/OldPlugin.vue (100%) rename src/plugins/{plugin-example-2 => user-plugin}/pages/Plugin.vue (100%) create mode 100644 src/plugins/user-plugin/plugin.ts rename src/plugins/{plugin-example-2 => user-plugin}/routes/index.ts (56%) create mode 100644 src/plugins/user/pages/User.vue create mode 100644 src/plugins/user/plugin.ts create mode 100644 src/plugins/user/routes/index.ts diff --git a/src/boot/plugins.ts b/src/boot/plugins.ts index cdddfdd..f70c55b 100644 --- a/src/boot/plugins.ts +++ b/src/boot/plugins.ts @@ -13,13 +13,15 @@ interface EssentialLink { } interface Plugin { - router: PluginRouteConfig[]; - store?: Module; + name: string; + routes: PluginRouteConfig[] | RouteConfig[]; + store?: Module[]; 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); }); diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue index c24dc45..a336a9c 100644 --- a/src/layouts/MainLayout.vue +++ b/src/layouts/MainLayout.vue @@ -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 diff --git a/src/pages/Login.vue b/src/pages/Login.vue index 3716c18..66e3199 100644 --- a/src/pages/Login.vue +++ b/src/pages/Login.vue @@ -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 }; diff --git a/src/pages/home/Home.vue b/src/pages/home/Home.vue deleted file mode 100644 index 57ba773..0000000 --- a/src/pages/home/Home.vue +++ /dev/null @@ -1,24 +0,0 @@ - - - diff --git a/src/pages/home/NewHome.vue b/src/pages/home/NewHome.vue deleted file mode 100644 index 8d8dba7..0000000 --- a/src/pages/home/NewHome.vue +++ /dev/null @@ -1,14 +0,0 @@ - - - diff --git a/src/pages/home/OldHome.vue b/src/pages/home/OldHome.vue deleted file mode 100644 index 6c18ea2..0000000 --- a/src/pages/home/OldHome.vue +++ /dev/null @@ -1,14 +0,0 @@ - - - diff --git a/src/plugins/plugin-example-2/plugin.ts b/src/plugins/plugin-example-2/plugin.ts deleted file mode 100644 index 34157f7..0000000 --- a/src/plugins/plugin-example-2/plugin.ts +++ /dev/null @@ -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; diff --git a/src/plugins/plugin-example/plugin.ts b/src/plugins/plugin-example/plugin.ts index 2b5b250..8708048 100644 --- a/src/plugins/plugin-example/plugin.ts +++ b/src/plugins/plugin-example/plugin.ts @@ -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 }; diff --git a/src/plugins/plugin-example-2/components/navigation/PluginLinks.vue b/src/plugins/user-plugin/components/navigation/PluginLinks.vue similarity index 100% rename from src/plugins/plugin-example-2/components/navigation/PluginLinks.vue rename to src/plugins/user-plugin/components/navigation/PluginLinks.vue diff --git a/src/plugins/plugin-example-2/pages/NewPlugin.vue b/src/plugins/user-plugin/pages/NewPlugin.vue similarity index 100% rename from src/plugins/plugin-example-2/pages/NewPlugin.vue rename to src/plugins/user-plugin/pages/NewPlugin.vue diff --git a/src/plugins/plugin-example-2/pages/OldPlugin.vue b/src/plugins/user-plugin/pages/OldPlugin.vue similarity index 100% rename from src/plugins/plugin-example-2/pages/OldPlugin.vue rename to src/plugins/user-plugin/pages/OldPlugin.vue diff --git a/src/plugins/plugin-example-2/pages/Plugin.vue b/src/plugins/user-plugin/pages/Plugin.vue similarity index 100% rename from src/plugins/plugin-example-2/pages/Plugin.vue rename to src/plugins/user-plugin/pages/Plugin.vue diff --git a/src/plugins/user-plugin/plugin.ts b/src/plugins/user-plugin/plugin.ts new file mode 100644 index 0000000..e850196 --- /dev/null +++ b/src/plugins/user-plugin/plugin.ts @@ -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; diff --git a/src/plugins/plugin-example-2/routes/index.ts b/src/plugins/user-plugin/routes/index.ts similarity index 56% rename from src/plugins/plugin-example-2/routes/index.ts rename to src/plugins/user-plugin/routes/index.ts index 3a4fcf7..c0c2ee1 100644 --- a/src/plugins/plugin-example-2/routes/index.ts +++ b/src/plugins/user-plugin/routes/index.ts @@ -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') } ] diff --git a/src/plugins/user/pages/User.vue b/src/plugins/user/pages/User.vue new file mode 100644 index 0000000..4ff0feb --- /dev/null +++ b/src/plugins/user/pages/User.vue @@ -0,0 +1,28 @@ + + + diff --git a/src/plugins/user/plugin.ts b/src/plugins/user/plugin.ts new file mode 100644 index 0000000..7a04344 --- /dev/null +++ b/src/plugins/user/plugin.ts @@ -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; diff --git a/src/plugins/user/routes/index.ts b/src/plugins/user/routes/index.ts new file mode 100644 index 0000000..e176de9 --- /dev/null +++ b/src/plugins/user/routes/index.ts @@ -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; diff --git a/src/router/routes.ts b/src/router/routes.ts index aec091d..774aac9 100644 --- a/src/router/routes.ts +++ b/src/router/routes.ts @@ -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',