amis-saas-7740 新增模型组件功能

Change-Id: Ic0bbaf05ad463130de943c32f4367f1102f956c8
This commit is contained in:
2betop 2023-02-24 14:49:36 +08:00
parent b41b92e167
commit d004152312
5 changed files with 92 additions and 79 deletions

View File

@ -66,7 +66,10 @@ export interface EditorProps extends PluginEventListener {
| Array<string>
| ((id: string, plugin: PluginClass) => boolean);
plugins?: Array<PluginClass>;
plugins?: Array<
| PluginClass
| [PluginClass, Record<string, any> | (() => Record<string, any>)]
>;
/**
*

View File

@ -221,7 +221,10 @@ function SchemaFrom({
submitOnChange,
node,
manager,
justify
justify,
ctx,
pipeIn,
pipeOut
}: {
propKey: string;
env: any;
@ -240,6 +243,9 @@ function SchemaFrom({
manager: EditorManager;
panelById?: string;
justify?: boolean;
ctx?: any;
pipeIn?: (value: any) => any;
pipeOut?: (value: any) => any;
}) {
let containerKey = 'body';
@ -290,14 +296,17 @@ function SchemaFrom({
};
}
value = pipeIn ? pipeIn(value) : value;
return render(
schema,
{
onFinished: (newValue: any) => {
onFinished: async (newValue: any) => {
newValue = pipeOut ? await pipeOut(newValue) : newValue;
const diffValue = diff(value, newValue);
onChange(newValue, diffValue);
},
data: value,
data: ctx ? createObject(ctx, value) : value,
node: node,
manager: manager,
popOverContainer
@ -320,6 +329,8 @@ export function makeSchemaFormRender(
justify?: boolean;
panelById?: string;
formKey?: string;
pipeIn?: (value: any) => any;
pipeOut?: (value: any) => any;
}
) {
const env = {...manager.env, session: 'schema-form'};
@ -366,7 +377,10 @@ export function makeSchemaFormRender(
)
: undefined
}
value={createObject(ctx, value)}
value={value}
ctx={ctx}
pipeIn={schema.pipeIn}
pipeOut={schema.pipeOut}
submitOnChange={schema.submitOnChange}
onChange={onChange}
env={env}

View File

@ -75,11 +75,13 @@ export interface EditorManagerConfig
extends Omit<EditorProps, 'value' | 'onChange'> {}
export interface PluginClass {
new (manager: EditorManager): PluginInterface;
new (manager: EditorManager, options?: any): PluginInterface;
id?: string;
}
const builtInPlugins: Array<PluginClass> = [];
const builtInPlugins: Array<
PluginClass | [PluginClass, Record<string, any> | (() => Record<string, any>)]
> = [];
declare const window: Window & {AMISEditorCustomPlugins: any};
@ -105,8 +107,10 @@ export function autoPreRegisterEditorCustomPlugins() {
export function registerEditorPlugin(klass: PluginClass) {
let isExitPlugin: any = null;
if (klass.prototype && klass.prototype.isNpmCustomWidget) {
isExitPlugin = builtInPlugins.find(
item => item.prototype.name === klass.prototype.name
isExitPlugin = builtInPlugins.find(item =>
Array.isArray(item)
? item[0].prototype.name === klass.prototype.name
: item.prototype.name === klass.prototype.name
);
} else {
// 待进一步优化
@ -130,7 +134,9 @@ export function getEditorPlugins() {
*
*/
export function unRegisterEditorPlugin(id: string) {
const idx = findIndex(builtInPlugins, item => item.id === id);
const idx = findIndex(builtInPlugins, item =>
Array.isArray(item) ? item[0].id === id : item.id === id
);
~idx && builtInPlugins.splice(idx, 1);
}
@ -191,15 +197,23 @@ export class EditorManager {
parent?.plugins ||
(config.disableBultinPlugin ? [] : builtInPlugins) // 页面设计器注册的插件列表
.concat(config.plugins || [])
.filter(p =>
config.disablePluginList
.filter(p => {
p = Array.isArray(p) ? p[0] : p;
return config.disablePluginList
? typeof config.disablePluginList === 'function'
? !config.disablePluginList(p.id || '', p)
: !config.disablePluginList.includes(p.id || 'unkown')
: true
)
: true;
})
.map(Editor => {
const plugin = new Editor(this); // 进行一次实例化
let pluginOptions: Record<string, any> = {};
if (Array.isArray(Editor)) {
pluginOptions =
typeof Editor[1] === 'function' ? Editor[1]() : Editor[1];
Editor = Editor[0];
}
const plugin = new Editor(this, pluginOptions); // 进行一次实例化
plugin.order = plugin.order ?? 0;
// 记录动作定义
@ -538,7 +552,7 @@ export class EditorManager {
// 此处换成for是为了解决异步问题
for (let index = 0, size = this.plugins.length; index < size; index++) {
const pluginItem = this.plugins[index];
let subRenderer = pluginItem.buildSubRenderers?.(
let subRenderer = await pluginItem.buildSubRenderers?.(
contxt,
subRenderers,
getRenderers()
@ -1697,6 +1711,8 @@ export class EditorManager {
justify?: boolean;
panelById?: string;
formKey?: string;
pipeIn?: (value: any) => any;
pipeOut?: (value: any) => any;
}) {
return makeSchemaFormRender(this, schema);
}
@ -1915,8 +1931,14 @@ export class EditorManager {
*
*/
dispose() {
// 有些插件需要销毁,靠这个事件
this.trigger('dispose', {
data: this
});
this.toDispose.forEach(fn => fn());
this.toDispose = [];
this.plugins.forEach(p => p.dispose?.());
this.plugins.splice(0, this.plugins.length);
this.listeners.splice(0, this.listeners.length);
this.broadcasts.splice(0, this.broadcasts.length);
this.lazyPatchSchema.cancel();

View File

@ -863,7 +863,11 @@ export interface PluginInterface
context: RendererEventContext,
subRenderers: Array<SubRendererInfo>,
renderers: Array<RendererConfig>
) => BasicSubRenderInfo | Array<BasicSubRenderInfo> | void;
) =>
| BasicSubRenderInfo
| Array<BasicSubRenderInfo>
| void
| Promise<BasicSubRenderInfo | Array<BasicSubRenderInfo> | void>;
/**
* NPM自定义组件分类和排序[]
@ -894,6 +898,8 @@ export interface PluginInterface
e: any,
data: any
) => void;
dispose?: () => void;
}
export interface RendererPluginEvent {
@ -1132,62 +1138,6 @@ export abstract class BasePlugin implements PluginInterface {
}
}
/**
*
* @param id
* @param schema
* @param region
* @param info
* @param menus
*/
buildEditorContextMenu(
{id, schema, region, info, selections}: ContextMenuEventContext,
menus: Array<ContextMenuItem>
) {
const plugin: PluginInterface = this;
if (
info.plugin === plugin &&
!selections.length &&
(plugin.scaffoldForm?.canRebuild || info.scaffoldForm?.canRebuild)
) {
menus.push({
label: `快速构建「${info.plugin.name}`,
disabled: schema.$$commonSchema,
onSelect: () =>
this.manager.reScaffold(
id,
info.scaffoldForm || plugin.scaffoldForm!,
schema
)
});
}
}
buildEditorToolbar(
{id, schema, info}: BaseEventContext,
toolbars: Array<BasicToolbarItem>
) {
const plugin: PluginInterface = this;
if (
info.plugin === plugin &&
(info.scaffoldForm?.canRebuild ?? plugin.scaffoldForm?.canRebuild)
) {
toolbars.push({
iconSvg: 'harmmer',
tooltip: `快速构建「${info.plugin.name}`,
placement: 'bottom',
onClick: () => this.manager.reScaffoldV2(id)
/*
this.manager.reScaffold(
id,
info.scaffoldForm || plugin.scaffoldForm!,
schema
)
*/
});
}
}
renderPlaceholder(text: string, key?: any, style?: any) {
return React.createElement('div', {
key,
@ -1209,12 +1159,10 @@ export abstract class BasePlugin implements PluginInterface {
}
}
/**
*
*/
export class LayoutBasePlugin extends BasePlugin {
onActive(event: PluginEvent<ActiveEventContext>) {
const context = event.context;
@ -1350,4 +1298,4 @@ export class LayoutBasePlugin extends BasePlugin {
}
});
}
}
}

View File

@ -7,7 +7,8 @@ import {
BasicPanelItem,
BuildPanelEventContext,
PluginEvent,
InsertEventContext
InsertEventContext,
PluginInterface
} from '../plugin';
import {registerEditorPlugin} from '../manager';
import type {MenuItem} from 'amis-ui/lib/components/ContextMenu';
@ -20,7 +21,7 @@ export class BasicToolbarPlugin extends BasePlugin {
order = -9999;
buildEditorToolbar(
{id, schema}: BaseEventContext,
{id, schema, info}: BaseEventContext,
toolbars: Array<BasicToolbarItem>
) {
const store = this.manager.store;
@ -218,10 +219,19 @@ export class BasicToolbarPlugin extends BasePlugin {
}
}
});
if (info.scaffoldForm?.canRebuild ?? info.plugin.scaffoldForm?.canRebuild) {
toolbars.push({
iconSvg: 'harmmer',
tooltip: `快速构建「${info.plugin.name}`,
placement: 'bottom',
onClick: () => this.manager.reScaffoldV2(id)
});
}
}
buildEditorContextMenu(
{id, schema, region, selections}: ContextMenuEventContext,
{id, schema, region, info, selections}: ContextMenuEventContext,
menus: Array<ContextMenuItem>
) {
const manager = this.manager;
@ -522,6 +532,22 @@ export class BasicToolbarPlugin extends BasePlugin {
});
*/
}
if (
!selections.length &&
(info.plugin.scaffoldForm?.canRebuild || info.scaffoldForm?.canRebuild)
) {
menus.push({
label: `快速构建「${info.plugin.name}`,
disabled: schema.$$commonSchema,
onSelect: () =>
this.manager.reScaffold(
id,
info.scaffoldForm || info.plugin.scaffoldForm!,
schema
)
});
}
}
buildEditorPanel(