diff --git a/src/boot/plugins.ts b/src/boot/plugins.ts index 8290311..ff49cc6 100644 --- a/src/boot/plugins.ts +++ b/src/boot/plugins.ts @@ -2,172 +2,171 @@ import { boot } from 'quasar/wrappers'; import { RouteConfig } from 'vue-router'; import { Module, Store } from 'vuex'; import { StateInterface } from 'src/store'; +import { FG_Plugin } from 'src/plugins'; +import routes from 'src/router/routes'; const config = { // Do not change required Modules !! - requiredModules: ['user'], + requiredModules: ['User'], // here you can import plugins. loadModules: [] }; // do not change anything here !! -interface ShortCutLink { - link: string; - icon: string; -} - -interface Plugin { - name: string; - routes: RouteConfig[]; - store?: Map>; - mainLink: PluginMainLink; - requiredModules: string[]; - shortcuts: ShortCutLink[]; - shortcutsOut: ShortCutLink[]; - version: string; -} - -interface PluginMainLink extends PluginChildLink { - children: PluginChildLink[]; -} - -interface PluginChildLink { - name: string; - title: string; - link: string; - icon: string; -} - -interface LoadedPlugin { - name: string; - version: string; -} - -interface LoadedPlugins { - plugins: LoadedPlugin[]; - routes: RouteConfig[]; - mainLinks: PluginMainLink[]; - shortcuts: ShortCutLink[]; - shortcutsOut: ShortCutLink[]; -} - -export { - Plugin, - PluginChildLink, - PluginMainLink, - ShortCutLink, - LoadedPlugins, - LoadedPlugin -}; - // combine routes from source to target -function combineRoutes ( + +function combineRoutes( target: RouteConfig[], - source: RouteConfig[] + source: FG_Plugin.PluginRouteConfig[], + mainPath: '/' | '/main' = '/' ): RouteConfig[] { - // iterate first layer e.g. /main, / etc. - source.forEach((sourceRouteConfig: RouteConfig) => { - const targetRouteConfig: RouteConfig | undefined = target.find( - (routeConfig: RouteConfig) => { - return sourceRouteConfig.path == routeConfig.path; - } - ); - if (targetRouteConfig) { - // if exists first layer in target exist iterate through 2nd layer e.g. /main/user, /main/about - sourceRouteConfig.children ?.forEach( - (sourcePluginChildRouteConfig: RouteConfig) => { - const targetPluginRouteConfig: - | RouteConfig - | undefined = targetRouteConfig.children ?.find( - (routeConfig: RouteConfig) => { - return sourcePluginChildRouteConfig.path == routeConfig.path; - } - ); - if (targetPluginRouteConfig) { - // if 2nd layer in target exist check if target has children path. - if (targetPluginRouteConfig.children) { - // if target has children path, add children from source. - targetPluginRouteConfig.children = Object.assign( - targetPluginRouteConfig.children, - sourcePluginChildRouteConfig.children - ); - } else { - // if not set children of targen from children of source - targetPluginRouteConfig.children = - sourcePluginChildRouteConfig.children; - } - } else { - // if target not exists in 2nd layer, add source to children of first targen - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - targetRouteConfig.children.push(sourcePluginChildRouteConfig); + target.forEach(target => { + if (target.path === mainPath) { + console.log('target', target.path); + source.forEach((sourceMainConfig: FG_Plugin.PluginRouteConfig) => { + console.log('sourceMainconfig', sourceMainConfig); + const targetMainConfig = target.children?.find( + (targetMainConfig: RouteConfig) => { + return sourceMainConfig.path === targetMainConfig.path; } + ); + if (targetMainConfig) { + const sourceChildren: RouteConfig[] = []; + sourceMainConfig.children?.forEach(child => { + sourceChildren.push(child); + }); + if (targetMainConfig.children) { + targetMainConfig.children = Object.assign( + targetMainConfig.children, + sourceChildren + ); + } else { + targetMainConfig.children = sourceChildren; + } + } else { + if (target.children === undefined) { + target.children = []; + } + target.children.push(sourceMainConfig); } - ); - } else { - // if target not exists in first layer, add source - target.push(sourceRouteConfig); + }); } }); return target; } // combine Links of Plugins from source to target -function combineMainLinks ( - target: PluginMainLink[], - source: PluginMainLink -): PluginMainLink[] { - const targetPluginMainLink: PluginMainLink | undefined = target.find( - (targetPluginMainLink: PluginMainLink) => { +function combineMainLinks( + target: FG_Plugin.PluginMainLink[], + source: FG_Plugin.PluginRouteConfig +): FG_Plugin.PluginMainLink[] { + const targetPluginMainLink: + | FG_Plugin.PluginMainLink + | undefined = target.find( + (targetPluginMainLink: FG_Plugin.PluginMainLink) => { console.log(targetPluginMainLink.title, source.title); return targetPluginMainLink.title == source.title; } ); if (targetPluginMainLink) { - source.children.forEach((sourcePluginChildLink: PluginChildLink) => { - targetPluginMainLink.children.push(sourcePluginChildLink); - }); + source.children?.forEach( + (sourcePluginChildLink: FG_Plugin.PluginRouteConfig) => { + targetPluginMainLink.children.push({ + title: sourcePluginChildLink.title, + icon: sourcePluginChildLink.icon, + link: sourcePluginChildLink.name, + name: sourcePluginChildLink.name + }); + } + ); } else { - target.push(source); + const mainLink: FG_Plugin.PluginMainLink = { + title: source.title, + icon: source.icon, + link: source.name, + name: source.name + }; + source.children?.forEach(child => { + if (mainLink.children === undefined) { + mainLink.children = []; + } + mainLink.children.push({ + title: child.title, + icon: child.icon, + link: child.name, + name: child.name + }); + }); + target.push(mainLink); } return target; } +function loadShortCuts( + target: FG_Plugin.ShortCutLink[], + source: FG_Plugin.PluginRouteConfig[] +): FG_Plugin.ShortCutLink[] { + source.forEach(route => { + if (route.shortcut) { + target.push({ + link: route.name, + icon: route.icon + }); + } + if (route.children) { + target = loadShortCuts(target, route.children); + } + }); + return target; +} + // loade plugins -function loadPlugin ( - loadedPlugins: LoadedPlugins, +function loadPlugin( + loadedPlugins: FG_Plugin.LoadedPlugins, modules: string[], plugins: Plugin[], store: Store -): LoadedPlugins { +): FG_Plugin.LoadedPlugins { modules.forEach(requiredModule => { - const plugin = plugins.find(plugin => { + const plugin = plugins.find(plugin => { return plugin.name == requiredModule; }); if (plugin) { - loadedPlugins.routes = combineRoutes(loadedPlugins.routes, plugin.routes); + if (plugin.mainRoutes) { + loadedPlugins.routes = combineRoutes( + loadedPlugins.routes, + plugin.mainRoutes, + '/main' + ); + plugin.mainRoutes.forEach(route => { + loadedPlugins.mainLinks = combineMainLinks( + loadedPlugins.mainLinks, + route + ); + }); + loadedPlugins.shortcuts = loadShortCuts( + loadedPlugins.shortcuts, + plugin.mainRoutes + ); + } + if (plugin.outRoutes) { + loadedPlugins.routes = combineRoutes( + loadedPlugins.routes, + plugin.outRoutes + ); + loadedPlugins.shortcutsOut = loadShortCuts( + loadedPlugins.shortcutsOut, + plugin.outRoutes + ); + } if (plugin.store) { console.log(plugin.store); console.log(plugin.store.keys()); plugin.store.forEach((store_plugin, store_namespace) => { store.registerModule(store_namespace, store_plugin); }); - //.forEach(store_key => { - // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access - //store.registerModule(store_key, plugin.store.get(store_key)); - //}); } - loadedPlugins.mainLinks = combineMainLinks( - loadedPlugins.mainLinks, - plugin.mainLink - ); - loadedPlugins.shortcuts = loadedPlugins.shortcuts.concat( - plugin.shortcuts - ); - loadedPlugins.shortcutsOut = loadedPlugins.shortcutsOut.concat( - plugin.shortcutsOut - ); loadedPlugins.plugins.push({ name: plugin.name, version: plugin.version @@ -183,8 +182,8 @@ function loadPlugin ( // more info on params: https://quasar.dev/quasar-cli/cli-documentation/boot-files#Anatomy-of-a-boot-file export default boot>(({ Vue, router, store }) => { const plugins: Plugin[] = []; - let loadedPlugins: LoadedPlugins = { - routes: [], + let loadedPlugins: FG_Plugin.LoadedPlugins = { + routes, plugins: [], mainLinks: [], shortcuts: [], diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue index 9bd2a81..8388224 100644 --- a/src/layouts/MainLayout.vue +++ b/src/layouts/MainLayout.vue @@ -99,10 +99,10 @@ import EssentialLink from 'components/navigation/EssentialLink.vue'; import ShortCutLink from 'components/navigation/ShortCutLink.vue'; import { Screen } from 'quasar'; -import { LoadedPlugins, PluginMainLink } from 'boot/plugins'; import { defineComponent, ref, computed } from '@vue/composition-api'; import { Store } from 'vuex'; import { StateInterface } from 'src/store'; +import { FG_Plugin } from 'src/plugins'; const links = [ { @@ -130,7 +130,7 @@ const shortcuts = [ declare module 'vue/types/vue' { interface Vue { - $flaschengeistPlugins: LoadedPlugins; + $flaschengeistPlugins: FG_Plugin.LoadedPlugins; } } @@ -155,9 +155,9 @@ export default defineComponent({ const pluginChildLinks = computed(() => { const link: - | PluginMainLink + | FG_Plugin.PluginMainLink | undefined = ctx.root.$flaschengeistPlugins.mainLinks.find( - (plugin: PluginMainLink) => { + (plugin: FG_Plugin.PluginMainLink) => { if (ctx.root.$route.matched.length > 1) { return plugin.name == ctx.root.$route.matched[1].name; } diff --git a/src/plugins.d.ts b/src/plugins.d.ts new file mode 100644 index 0000000..357230a --- /dev/null +++ b/src/plugins.d.ts @@ -0,0 +1,49 @@ +import { RouteConfig } from 'vue-router'; +import { Module } from 'vuex'; +import { StateInterface } from 'src/store'; +declare namespace FG_Plugin { + interface ShortCutLink { + link: string; + icon: string; + } + + interface PluginRouteConfig extends RouteConfig { + shortcut?: boolean; + title: string; + icon: string; + children?: PluginRouteConfig[]; + } + + interface Plugin { + name: string; + mainRoutes?: PluginRouteConfig[]; + outRoutes?: PluginRouteConfig[]; + store?: Map>; + requiredModules: string[]; + version: string; + } + + interface PluginMainLink extends PluginChildLink { + children: PluginChildLink[]; + } + + interface PluginChildLink { + name: string; + title: string; + link: string; + icon: string; + } + + interface LoadedPlugin { + name: string; + version: string; + } + + interface LoadedPlugins { + plugins: LoadedPlugin[]; + routes: RouteConfig[]; + mainLinks: PluginMainLink[]; + shortcuts: ShortCutLink[]; + shortcutsOut: ShortCutLink[]; + } +} diff --git a/src/plugins/plugin-example/components/navigation/PluginLinks.vue b/src/plugins/plugin-example/components/navigation/PluginLinks.vue deleted file mode 100644 index 84b5d02..0000000 --- a/src/plugins/plugin-example/components/navigation/PluginLinks.vue +++ /dev/null @@ -1,32 +0,0 @@ - - - diff --git a/src/plugins/plugin-example/pages/NewPlugin.vue b/src/plugins/plugin-example/pages/NewPlugin.vue deleted file mode 100644 index b528993..0000000 --- a/src/plugins/plugin-example/pages/NewPlugin.vue +++ /dev/null @@ -1,17 +0,0 @@ - - - diff --git a/src/plugins/plugin-example/pages/OldPlugin.vue b/src/plugins/plugin-example/pages/OldPlugin.vue deleted file mode 100644 index b025fee..0000000 --- a/src/plugins/plugin-example/pages/OldPlugin.vue +++ /dev/null @@ -1,16 +0,0 @@ - - - diff --git a/src/plugins/plugin-example/pages/Plugin.vue b/src/plugins/plugin-example/pages/Plugin.vue deleted file mode 100644 index c0fd5a6..0000000 --- a/src/plugins/plugin-example/pages/Plugin.vue +++ /dev/null @@ -1,22 +0,0 @@ - - - diff --git a/src/plugins/plugin-example/plugin.ts b/src/plugins/plugin-example/plugin.ts deleted file mode 100644 index ff47cdd..0000000 --- a/src/plugins/plugin-example/plugin.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Plugin, PluginMainLink, ShortCutLink } from 'boot/plugins'; -import routes from 'src/plugins/plugin-example/routes'; - -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 plugin: Plugin = { - routes, - mainLink, - name: mainLink.name, - requiredModules: [], - shortcuts: [], - shortcutsOut: [], - version: '1.0.2' -}; - -export { mainLink }; - -export default plugin; diff --git a/src/plugins/plugin-example/routes/index.ts b/src/plugins/plugin-example/routes/index.ts deleted file mode 100644 index e9aa7f6..0000000 --- a/src/plugins/plugin-example/routes/index.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { RouteConfig } from 'vue-router'; - -const routes: RouteConfig[] = [ - { - path: '/main', - components: { - default: () => import('layouts/MainLayout.vue') - }, - children: [ - { - path: 'plugin1', - name: 'plugin1', - meta: { permissions: ['user'] }, - components: { - default: () => import('../pages/Plugin.vue'), - 'plugin-nav': () => import('../components/navigation/PluginLinks.vue') - }, - children: [ - { - path: 'plugin1_1', - name: 'plugin1_1', - meta: { permissions: ['user'] }, - component: () => import('../pages/NewPlugin.vue') - }, - { - path: 'plugin1_2', - name: 'plugin1_2', - meta: { permissions: ['user'] }, - component: () => import('../pages/OldPlugin.vue') - } - ] - } - ] - } -]; - -export default routes; diff --git a/src/plugins/user-plugin/components/navigation/PluginLinks.vue b/src/plugins/user-plugin/components/navigation/PluginLinks.vue deleted file mode 100644 index 2fd0060..0000000 --- a/src/plugins/user-plugin/components/navigation/PluginLinks.vue +++ /dev/null @@ -1,32 +0,0 @@ - - - diff --git a/src/plugins/user-plugin/pages/NewPlugin.vue b/src/plugins/user-plugin/pages/NewPlugin.vue deleted file mode 100644 index b528993..0000000 --- a/src/plugins/user-plugin/pages/NewPlugin.vue +++ /dev/null @@ -1,17 +0,0 @@ - - - diff --git a/src/plugins/user-plugin/pages/OldPlugin.vue b/src/plugins/user-plugin/pages/OldPlugin.vue deleted file mode 100644 index b025fee..0000000 --- a/src/plugins/user-plugin/pages/OldPlugin.vue +++ /dev/null @@ -1,16 +0,0 @@ - - - diff --git a/src/plugins/user-plugin/pages/Plugin.vue b/src/plugins/user-plugin/pages/Plugin.vue deleted file mode 100644 index c0fd5a6..0000000 --- a/src/plugins/user-plugin/pages/Plugin.vue +++ /dev/null @@ -1,22 +0,0 @@ - - - diff --git a/src/plugins/user-plugin/plugin.ts b/src/plugins/user-plugin/plugin.ts deleted file mode 100644 index 45e5641..0000000 --- a/src/plugins/user-plugin/plugin.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Plugin, PluginMainLink, ShortCutLink } 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 shortcuts: ShortCutLink[] = [ - { - link: 'user-plugin2', - icon: 'mdi-account-minus' - } -]; - -const plugin: Plugin = { - routes, - mainLink, - name: mainLink.name, - requiredModules: ['user'], - shortcuts, - shortcutsOut: [], - version: '0.1.0' -}; - -export { mainLink }; -export default plugin; diff --git a/src/plugins/user-plugin/routes/index.ts b/src/plugins/user-plugin/routes/index.ts deleted file mode 100644 index c0c2ee1..0000000 --- a/src/plugins/user-plugin/routes/index.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { RouteConfig } from 'vue-router'; - -const routes: RouteConfig[] = [ - { - path: '/main', - components: { - default: () => import('layouts/MainLayout.vue') - }, - children: [ - { - path: 'user', - name: 'user', - component: () => import('src/plugins/user/pages/User.vue'), - children: [ - { - path: 'user-plugin', - name: 'user-plugin1', - component: () => import('../pages/NewPlugin.vue') - }, - { - path: 'user-plugin2', - name: 'user-plugin2', - component: () => import('../pages/OldPlugin.vue') - } - ] - } - ] - } -]; - -export default routes; diff --git a/src/plugins/user/pages/MainPage.vue b/src/plugins/user/pages/MainPage.vue new file mode 100644 index 0000000..28a0a12 --- /dev/null +++ b/src/plugins/user/pages/MainPage.vue @@ -0,0 +1,39 @@ + + + diff --git a/src/plugins/user/pages/User.vue b/src/plugins/user/pages/User.vue index 1a4d8c3..d51d87e 100644 --- a/src/plugins/user/pages/User.vue +++ b/src/plugins/user/pages/User.vue @@ -1,10 +1,6 @@ diff --git a/src/plugins/user/plugin.ts b/src/plugins/user/plugin.ts index 77dc0ac..877d8c2 100644 --- a/src/plugins/user/plugin.ts +++ b/src/plugins/user/plugin.ts @@ -1,32 +1,14 @@ -import { Plugin, PluginMainLink } from 'boot/plugins'; import { Module } from 'vuex'; import userStore from './store/user'; import sessionsStore from './store/session'; import routes from './routes'; import { StateInterface } from 'src/store'; +import { FG_Plugin } from 'src/plugins'; -const mainLink: PluginMainLink = { - name: 'user', - title: 'loadFromStore("user/displayName")', - link: 'user', - icon: 'mdi-account', - children: [ - { - name: 'user', - title: 'Einstellungen', - link: 'user-settings', - icon: 'mdi-cog' - } - ] -}; - -const plugin: Plugin = { - routes, - mainLink, - name: mainLink.name, +const plugin: FG_Plugin.Plugin = { + name: 'User', + mainRoutes: routes, requiredModules: [], - shortcutsOut: [], - shortcuts: [], version: '0.0.1', store: new Map>([ ['user', userStore], @@ -34,6 +16,4 @@ const plugin: Plugin = { ]) }; -export { mainLink }; - export default plugin; diff --git a/src/plugins/user/routes/index.ts b/src/plugins/user/routes/index.ts index 12957ac..0638c86 100644 --- a/src/plugins/user/routes/index.ts +++ b/src/plugins/user/routes/index.ts @@ -1,26 +1,33 @@ -import { RouteConfig } from 'vue-router'; - -const routes: RouteConfig[] = [ +import { FG_Plugin } from 'src/plugins'; +const mainRoutes: FG_Plugin.PluginRouteConfig[] = [ { - path: '/main', - component: () => import('layouts/MainLayout.vue'), + title: 'loadFromStore("user/displayName")', + icon: 'mdi-account', + path: 'user', + name: 'user', + component: () => import('../pages/MainPage.vue'), + meta: { permission: 'user' }, children: [ { - path: 'user', - name: 'user', - component: () => import('../pages/User.vue'), + title: 'Hauptkanal', + icon: 'mdi-account-hard-hat', + path: 'user-main', + name: 'user-main', + shortcut: false, meta: { permission: 'user' }, - children: [ - { - path: 'settings', - name: 'user-settings', - meta: { permission: 'user' }, - component: () => import('../pages/Settings.vue') - } - ] + component: () => import('../pages/User.vue') + }, + { + title: 'Einstellungen', + icon: 'mdi-cog', + path: 'settings', + name: 'user-settings', + shortcut: true, + meta: { permission: 'user' }, + component: () => import('../pages/Settings.vue') } ] } ]; -export default routes; +export default mainRoutes; diff --git a/src/plugins/user/store/user.ts b/src/plugins/user/store/user.ts index 6f35d37..1c2e9d1 100644 --- a/src/plugins/user/store/user.ts +++ b/src/plugins/user/store/user.ts @@ -73,7 +73,7 @@ const actions: ActionTree = { LocalStorage.set('user', response.data.user); LocalStorage.set('session', response.data.session); - void Router.push({ name: 'user' }); + void Router.push({ name: 'user-main' }); }) .catch(error => { console.exception(error); diff --git a/src/router/index.ts b/src/router/index.ts index e1b75f9..46d6a57 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -1,7 +1,6 @@ import { route } from 'quasar/wrappers'; import VueRouter from 'vue-router'; import { Store } from 'vuex'; -import routes from './routes'; import { StateInterface } from 'src/store'; /* @@ -10,7 +9,6 @@ import { StateInterface } from 'src/store'; */ export const Router: VueRouter = new VueRouter({ scrollBehavior: () => ({ x: 0, y: 0 }), - routes, // Leave these as is and change from quasar.conf.js instead! // quasar.conf.js -> build -> vueRouterMode @@ -19,7 +17,7 @@ export const Router: VueRouter = new VueRouter({ base: process.env.VUE_ROUTER_BASE }); -export default route>(function ({ Vue }) { +export default route>(function({ Vue }) { Vue.use(VueRouter); return Router;