mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-07 14:39:25 +08:00
* feat: init * fix: mobile layout * feat: more code * feat: improve navigate bar * fix: mobile title * feat: improve code * fix: add settings and initailzer * fix: settings * fix: tabbar items settings * feat: tabbar initializer * fix: api * fix: styles * feat: navbar * feat: navigate bar tabs initializer * feat: navigate bar tab settings * feat: navigation bar actions * fix: bug * fix: bug * fix: bug * fix: tabbar active * fix: bug * fix: mobile login and layout * fix: update version * fix: build error * feat: plugin settings support link * fix: add mobile meta * fix: desktop mode * fix: remove old code and change collection name and mobile path * fix: tabbar and tabs initialer layout * fix: initializer style * fix: adjust schema position * fix: mobile style * fix: delete relation resource and home page bug * fix: support multi app * fix: not found page * fix: js bridge * fix: bug * fix: navigation bar schema flat * fix: navigation bar action style * fix: change version * fix: mobile meta and real mobile test * refactor: folder and name * fix: navigation bar sticky and zIndex * fix: full mobile schema * fix: mobile readme and package.json * fix: e2e bug * fix: bug * fix: tabbar style on productino * fix: bug * fix: rename MobileTabBar.Page * fix: support tabbar sort * fix: support page tabs sort * fix: i18n * fix: settings utils import bug * docs: api doc * fix: qrcode refresh * test: unit tests * fix: bug * fix: unit test * fix: build bug * fix: e2e test * fix: overflow scroll * fix: bug * fix: scroll and overflow * fix: bug * fix: e2e expect await * fix: e2e bug * fix: bug * fix: change name * fix: add more e2e * fix: page header * fix: tab support icon * fix: bug * fix: bug * fix: docs * fix(T-4811): scroll bar too long * fix(T-4810): desktop mode * fix: e2e * fix(T-4812): title empty * fix: unit test * feat: hide Open mode option in mobile mode * feat: change default value of Open mode on mobile * feat: add OpenModeProvider * feat: support page mode * fix: fix build * test: update unit tests * chore: remove pro-plugins * fix: bug * fix(T-4812): title is required * fix: bug * fix: bug * fix: bug * fix: bug * refactor: remove z-index * refactor: make better for subpages * fix: drag bug * fix: bug * fix: theme bug * fix(T-4859): create tab bar title empty * fix(T-4857): action too long * fix: e2e bug * fix: remove comment * fix: bug * fix: theme bug * fix: should provider modal component * fix: bug --------- Co-authored-by: chenos <chenlinxh@gmail.com> Co-authored-by: Zeke Zhang <958414905@qq.com>
114 lines
3.2 KiB
TypeScript
114 lines
3.2 KiB
TypeScript
/**
|
|
* This file is part of the NocoBase (R) project.
|
|
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
* Authors: NocoBase Team.
|
|
*
|
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
*/
|
|
|
|
import type { Application } from './Application';
|
|
import type { Plugin } from './Plugin';
|
|
import { getPlugins } from './utils/remotePlugins';
|
|
|
|
export type PluginOptions<T = any> = { name?: string; packageName?: string; config?: T };
|
|
export type PluginType<Opts = any> = typeof Plugin | [typeof Plugin<Opts>, PluginOptions<Opts>];
|
|
export type PluginData = {
|
|
name: string;
|
|
packageName: string;
|
|
version: string;
|
|
url: string;
|
|
type: 'local' | 'upload' | 'npm';
|
|
};
|
|
|
|
export class PluginManager {
|
|
protected pluginInstances: Map<typeof Plugin, Plugin> = new Map();
|
|
protected pluginsAliases: Record<string, Plugin> = {};
|
|
private initPlugins: Promise<void>;
|
|
|
|
constructor(
|
|
protected _plugins: PluginType[],
|
|
protected loadRemotePlugins: boolean,
|
|
protected app: Application,
|
|
) {
|
|
this.app = app;
|
|
this.initPlugins = this.init(_plugins);
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
*/
|
|
async init(_plugins: PluginType[]) {
|
|
await this.initStaticPlugins(_plugins);
|
|
if (this.loadRemotePlugins) {
|
|
await this.initRemotePlugins();
|
|
}
|
|
}
|
|
|
|
private async initStaticPlugins(_plugins: PluginType[] = []) {
|
|
for await (const plugin of _plugins) {
|
|
const pluginClass = Array.isArray(plugin) ? plugin[0] : plugin;
|
|
const opts = Array.isArray(plugin) ? plugin[1] : undefined;
|
|
await this.add(pluginClass, opts);
|
|
}
|
|
}
|
|
|
|
private async initRemotePlugins() {
|
|
const res = await this.app.apiClient.request({ url: 'pm:listEnabled' });
|
|
const pluginList: PluginData[] = res?.data?.data || [];
|
|
const plugins = await getPlugins({
|
|
requirejs: this.app.requirejs,
|
|
pluginData: pluginList,
|
|
devDynamicImport: this.app.devDynamicImport,
|
|
});
|
|
for await (const [name, pluginClass] of plugins) {
|
|
const info = pluginList.find((item) => item.name === name);
|
|
await this.add(pluginClass, info);
|
|
}
|
|
}
|
|
|
|
async add<T = any>(plugin: typeof Plugin, opts: PluginOptions<T> = {}) {
|
|
const instance = this.getInstance(plugin, opts);
|
|
|
|
this.pluginInstances.set(plugin, instance);
|
|
|
|
if (opts.name) {
|
|
this.pluginsAliases[opts.name] = instance;
|
|
}
|
|
|
|
if (opts.packageName) {
|
|
this.pluginsAliases[opts.packageName] = instance;
|
|
}
|
|
|
|
await instance.afterAdd();
|
|
}
|
|
|
|
get<T extends typeof Plugin>(PluginClass: T): InstanceType<T>;
|
|
get<T extends {}>(name: string): T;
|
|
get(nameOrPluginClass: any) {
|
|
if (typeof nameOrPluginClass === 'string') {
|
|
return this.pluginsAliases[nameOrPluginClass];
|
|
}
|
|
return this.pluginInstances.get(nameOrPluginClass.default || nameOrPluginClass);
|
|
}
|
|
|
|
private getInstance<T>(plugin: typeof Plugin, opts?: T) {
|
|
return new plugin(opts, this.app);
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
*/
|
|
async load() {
|
|
await this.initPlugins;
|
|
|
|
for (const plugin of this.pluginInstances.values()) {
|
|
await plugin.beforeLoad();
|
|
}
|
|
|
|
for (const plugin of this.pluginInstances.values()) {
|
|
await plugin.load();
|
|
}
|
|
}
|
|
}
|