flaschengeist-frontend/src/boot/plugins.ts

219 lines
6.3 KiB
TypeScript
Raw Normal View History

import { boot } from 'quasar/wrappers';
import { RouteConfig } from 'vue-router';
2020-10-16 06:45:40 +00:00
import { Module, Store } from 'vuex';
import { StateInterface } from 'src/store';
const config = {
// Do not change required Modules !!
requiredModules: ['user'],
// here you can import plugins.
2020-10-16 06:45:40 +00:00
loadModules: []
};
// do not change anything here !!
interface ShortCutLink {
link: string;
icon: string;
}
interface Plugin {
name: string;
routes: RouteConfig[];
store?: Map<string, Module<any, StateInterface>>;
2020-10-13 09:27:27 +00:00
mainLink: PluginMainLink;
requiredModules: string[];
shortcuts: ShortCutLink[];
shortcutsOut: ShortCutLink[];
version: 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;
}
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 (
target: RouteConfig[],
source: RouteConfig[]
): RouteConfig[] {
2020-10-16 06:45:40 +00:00
// 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);
}
}
);
} 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) => {
console.log(targetPluginMainLink.title, source.title);
return targetPluginMainLink.title == source.title;
}
);
if (targetPluginMainLink) {
source.children.forEach((sourcePluginChildLink: PluginChildLink) => {
targetPluginMainLink.children.push(sourcePluginChildLink);
});
} else {
target.push(source);
}
return target;
}
// loade plugins
function loadPlugin (
loadedPlugins: LoadedPlugins,
modules: string[],
plugins: Plugin[],
2020-10-16 06:45:40 +00:00
store: Store<any>
): LoadedPlugins {
modules.forEach(requiredModule => {
const plugin = plugins.find(plugin => {
return plugin.name == requiredModule;
});
if (plugin) {
loadedPlugins.routes = combineRoutes(loadedPlugins.routes, plugin.routes);
if (plugin.store) {
2020-10-16 06:45:40 +00:00
console.log(plugin.store);
console.log(plugin.store.keys());
plugin.store.forEach((store_plugin, store_namespace) => {
store.registerModule(store_namespace, store_plugin);
});
2020-10-16 06:45:40 +00:00
//.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
});
} else {
console.exception(`Don't find required Plugin ${requiredModule}`);
}
});
return loadedPlugins;
}
// "async" is optional;
// more info on params: https://quasar.dev/quasar-cli/cli-documentation/boot-files#Anatomy-of-a-boot-file
export default boot<Store<StateInterface>>(({ Vue, router, store }) => {
const plugins: Plugin[] = [];
let loadedPlugins: LoadedPlugins = {
routes: [],
plugins: [],
mainLinks: [],
shortcuts: [],
shortcutsOut: []
};
// get all plugins
const pluginsContext = require.context('src/plugins', true, /.+\/plugin.ts$/);
pluginsContext.keys().forEach((fileName: string) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
plugins.push(pluginsContext(fileName).default);
});
// load plugins
loadedPlugins = loadPlugin(
loadedPlugins,
config.requiredModules,
plugins,
store
);
loadedPlugins = loadPlugin(loadedPlugins, config.loadModules, plugins, store);
console.log(loadedPlugins.routes);
// add new routes for plugins
router.addRoutes(loadedPlugins.routes);
// save plugins in VM-variable
2020-10-13 21:13:42 +00:00
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
Vue.prototype.$flaschengeistPlugins = loadedPlugins;
});