diff --git a/ui/src/router/index.tsx b/ui/src/router/index.tsx index dca1e1be..4cb222a9 100644 --- a/ui/src/router/index.tsx +++ b/ui/src/router/index.tsx @@ -21,6 +21,7 @@ import { Suspense, lazy } from 'react'; import { RouteObject } from 'react-router-dom'; import Layout from '@/pages/Layout'; +import { mergeRoutePlugins } from '@/utils/pluginKit'; import baseRoutes, { RouteNode } from './routes'; import RouteGuard from './RouteGuard'; @@ -69,5 +70,6 @@ const routeWrapper = (routeNodes: RouteNode[], root: RouteNode[]) => { }; routeWrapper(baseRoutes, routes); +const mergedRoutes = mergeRoutePlugins(routes); -export default routes as RouteObject[]; +export default mergedRoutes as RouteObject[]; diff --git a/ui/src/utils/pluginKit/index.ts b/ui/src/utils/pluginKit/index.ts index dfc1f736..481fadd3 100644 --- a/ui/src/utils/pluginKit/index.ts +++ b/ui/src/utils/pluginKit/index.ts @@ -17,14 +17,16 @@ * under the License. */ -import { NamedExoticComponent, FC } from 'react'; +import React from 'react'; import builtin from '@/plugins/builtin'; import * as allPlugins from '@/plugins'; import type * as Type from '@/common/interface'; +import { LOGGED_TOKEN_STORAGE_KEY } from '@/common/constants'; import { getPluginsStatus } from '@/services'; +import Storage from '@/utils/storage'; -import { initI18nResource } from './utils'; +import { initI18nResource, Plugin, PluginInfo, PluginType } from './utils'; /** * This information is to be defined for all components. @@ -38,24 +40,6 @@ import { initI18nResource } from './utils'; * @field description: Plugin description, optionally configurable. Usually read from the `i18n` file */ -export type PluginType = 'connector' | 'search' | 'editor'; -export interface PluginInfo { - slug_name: string; - type: PluginType; - name?: string; - description?: string; -} - -export interface Plugin { - info: PluginInfo; - component: NamedExoticComponent | FC; - i18nConfig?; - hooks?: { - useRender?: Array<(element: HTMLElement | null) => void>; - }; - activated?: boolean; -} - class Plugins { plugins: Plugin[] = []; @@ -155,5 +139,46 @@ const useRenderHtmlPlugin = (element: HTMLElement | null) => { }); }; -export { useRenderHtmlPlugin }; +const getRoutePlugins = () => { + return plugins.getPlugins().filter((plugin) => plugin.info.type === 'route'); +}; + +const defaultProps = () => { + const token = Storage.get(LOGGED_TOKEN_STORAGE_KEY) || ''; + return { + key: token, + headers: { + Authorization: token, + }, + }; +}; + +const mergeRoutePlugins = (routes) => { + const routePlugins = getRoutePlugins(); + if (routePlugins.length === 0) { + return routes; + } + routes.forEach((route) => { + if (route.page === 'pages/Layout') { + route.children?.forEach((child) => { + if (child.page === 'pages/SideNavLayout') { + routePlugins.forEach((plugin) => { + const { slug_name, route: path } = plugin.info; + const Component = plugin.component; + + child.children.push({ + page: `plugin/${slug_name}`, + path, + element: React.createElement(Component, defaultProps(), null), + }); + }); + } + }); + } + }); + return routes; +}; + +export { useRenderHtmlPlugin, mergeRoutePlugins }; +export type { Plugin, PluginInfo, PluginType }; export default plugins; diff --git a/ui/src/utils/pluginKit/utils.ts b/ui/src/utils/pluginKit/utils.ts index 76bbf388..a179360d 100644 --- a/ui/src/utils/pluginKit/utils.ts +++ b/ui/src/utils/pluginKit/utils.ts @@ -35,17 +35,23 @@ import i18next from 'i18next'; const I18N_NS = 'plugin'; -export type PluginType = 'connector' | 'search' | 'editor'; +export type PluginType = 'connector' | 'search' | 'editor' | 'route'; export interface PluginInfo { slug_name: string; type: PluginType; name?: string; description?: string; + route?: string; } export interface Plugin { info: PluginInfo; component: NamedExoticComponent | FC; + i18nConfig?; + hooks?: { + useRender?: Array<(element: HTMLElement | null) => void>; + }; + activated?: boolean; } interface I18nResource {