flaschengeist-frontend/src/boot/plugins.ts

169 lines
5.2 KiB
TypeScript
Raw Normal View History

import { boot } from 'quasar/wrappers';
import { RouteConfig } from 'vue-router';
import { Module } from 'vuex';
interface PluginRouteConfig extends RouteConfig {
example?: unknown;
}
interface EssentialLink {
title: string;
link: string;
icon?: string;
}
interface Plugin {
name: string;
routes: PluginRouteConfig[] | RouteConfig[];
store?: Module<never, never>[];
2020-10-13 09:27:27 +00:00
mainLink: PluginMainLink;
requiredModules: string[];
}
2020-10-13 09:27:27 +00:00
interface PluginMainLink extends PluginChildLink {
children: PluginChildLink[];
2020-10-13 09:27:27 +00:00
}
interface PluginChildLink {
name: string;
title: string;
link: string;
icon: string;
}
const config = {
// Do not change required Modules !!
requiredModules: ['user'],
// here you can import plugins.
loadModules: ['plugin1', 'user-plugin']
};
2020-10-13 09:27:27 +00:00
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, store }) => {
const pluginsContext = require.context('src/plugins', true, /.+\/plugin.ts$/);
let pluginMainLinks: PluginMainLink[] = [];
const plugins: Plugin[] = [];
pluginsContext.keys().forEach((fileName: string) => {
2020-10-13 09:27:27 +00:00
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
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);
2020-10-13 09:27:27 +00:00
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
2020-10-13 21:13:42 +00:00
Vue.prototype.$flaschengeistPluginsMainLinks = pluginMainLinks;
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
Vue.prototype.$flaschengeistPlugins = plugins;
console.log(pluginMainLinks);
});