feat: add types

This commit is contained in:
Jian Lu 2025-01-15 22:01:53 +08:00
parent 0a814b48a3
commit 3e933fe4d3
15 changed files with 221 additions and 110 deletions

View File

@ -45,6 +45,7 @@ import { OpenModeProvider } from '../modules/popup/OpenModeProvider';
import { AppSchemaComponentProvider } from './AppSchemaComponentProvider';
import type { Plugin } from './Plugin';
import type { RequireJS } from './utils/requirejs';
import { withSchemaEvent } from '../event-flow';
declare global {
interface Window {
@ -426,7 +427,12 @@ export class Application {
console.error('Component must have a displayName or pass name as second argument');
return;
}
set(this.components, componentName, component);
// event: add pasre of event schema
if (['Page'].includes(componentName)) {
set(this.components, componentName, withSchemaEvent(component));
} else {
set(this.components, componentName, component);
}
}
addComponents(components: Record<string, ComponentType>) {

View File

@ -0,0 +1,71 @@
/**
* 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 { Plugin } from '../application/Plugin';
import { EventSetting, PluginName } from './types';
import { EventSettingItem } from './EventSettingItem';
import { uniqBy } from 'lodash';
import { EventFlowProvider } from './EventFlowProvider';
import { EventDefinition } from './types';
export class EventFlowPlugin extends Plugin {
static name = PluginName;
modules: EventDefinition[] = [];
events: Map<string, EventSetting> = new Map();
async afterAdd() {
// await this.app.pm.add()
}
async beforeLoad() {}
// You can get and modify the app instance here
async load() {
this.schemaSettingsManager.addItem('PageSettings', PluginName, {
Component: EventSettingItem,
});
this.app.use(EventFlowProvider);
// this.app.addComponents({})
// this.app.addScopes({})
// this.app.addProvider()
// this.app.addProviders()
// this.app.router.add()
}
register(values: EventDefinition) {
console.log('register', values);
this.modules.push(values);
this.modules = uniqBy(this.modules, 'name');
}
// 触发事件
emit(moduleName: string, eventName: string, params: any) {
console.log('emit', moduleName, eventName, params);
const event = this.events.find((event) => event.event === `${moduleName}.${eventName}`);
if (event) {
event.actions.forEach((action) => {
const actionModuleName = action.split('.')[0];
const actionName = action.split('.')[1];
const module = this.modules.find((module) => module.name === moduleName);
const moduleAction = this.modules
.find((module) => module.name === actionModuleName)
?.actions?.find((action) => action.name === actionName);
console.log('moduleAction', moduleAction);
if (moduleAction) {
moduleAction?.fn(params);
}
});
}
}
on(event: EventSetting) {
this.events.set(event.event, event);
}
registerEvents(events: EventSetting[]) {
events.forEach((event) => {
this.on(event);
});
}
}

View File

@ -11,9 +11,9 @@ import React from 'react';
import { useControllableValue } from 'ahooks';
import { Card, Space, Button, Tag, Tooltip, Select, TreeSelect } from 'antd';
import { CloseOutlined, PlusOutlined, SettingFilled } from '@ant-design/icons';
import { IEventFlowModule } from '../index';
import { EventDefinition } from '../types';
export default function ActionsInput(props: { modules: IEventFlowModule[]; value: any; onChange: (v: any) => void }) {
export default function ActionsInput(props: { modules: EventDefinition[]; value: any; onChange: (v: any) => void }) {
const { modules } = props;
const [state, setState] = useControllableValue<Array<any>>(props, {
defaultValue: [],

View File

@ -10,9 +10,9 @@
import React from 'react';
import { useControllableValue } from 'ahooks';
import { Card, Space, TreeSelect } from 'antd';
import { IEventFlowModule } from '../index';
import { EventDefinition } from '../types';
export default function EventSelect(props: { modules: IEventFlowModule[]; value: any; onChange: (v: any) => void }) {
export default function EventSelect(props: { modules: EventDefinition[]; value: any; onChange: (v: any) => void }) {
const { modules, onChange } = props;
const [state, setState] = useControllableValue<Array<any>>(props, {
defaultValue: undefined,

View File

@ -14,7 +14,7 @@ import EventSelect from './EventSelect';
import ConditionInput from './ConditionInput';
import ActionsInput from './ActionsInput';
import { CloseOutlined, PlusOutlined } from '@ant-design/icons';
import { IEventFlowEvent } from '../types';
import { EventSetting } from '../types';
const EventCard = (props) => {
const { modules, onDelete } = props;
@ -46,7 +46,7 @@ const EventCard = (props) => {
export default function EventsSetting(props) {
const { modules, value } = props;
const [state, setState] = useControllableValue<Array<IEventFlowEvent | {}>>(props, {
const [state, setState] = useControllableValue<Array<EventSetting | {}>>(props, {
defaultValue: [],
});
console.log('modules', state, value);

View File

@ -18,7 +18,7 @@ import {
import React from 'react';
import { ISchema, useField } from '@formily/react';
import EventsSetting from './EventsSetting';
import { EventFlowPlugin } from '..';
import { EventFlowPlugin, SchemaSettingsKey } from '..';
import { useFieldSchema } from '@formily/react';
export const EventSettingItem = () => {
@ -28,7 +28,7 @@ export const EventSettingItem = () => {
const { patch } = useDesignable();
const app = useApp();
const eventFlowPlugin = usePlugin(EventFlowPlugin.name) as any;
console.log('eventFlowPlugin', schema);
console.log('eventFlowPlugin', eventFlowPlugin);
const { dn } = useDesignable();
const fieldSchema = useFieldSchema();
console.log('fieldSchema', fieldSchema);
@ -45,7 +45,7 @@ export const EventSettingItem = () => {
properties: {
events: {
type: 'array',
default: fieldSchema?.['x-event-flow-setting'] || [],
default: fieldSchema?.[SchemaSettingsKey] || [],
'x-decorator': 'FormItem',
'x-component': 'EventsSetting',
'x-component-props': {
@ -57,11 +57,11 @@ export const EventSettingItem = () => {
}
onSubmit={({ events }) => {
console.log('onSubmit', events);
fieldSchema['x-event-flow-setting'] = events;
fieldSchema[SchemaSettingsKey] = events;
dn.emit('patch', {
schema: {
'x-uid': fieldSchema['x-uid'],
'x-event-flow-setting': events,
[SchemaSettingsKey]: events,
},
});
eventFlowPlugin.registerEvents(events);

View File

@ -0,0 +1,35 @@
/**
* 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 React, { ComponentType } from 'react';
import { observer, useFieldSchema } from '@formily/react';
import { useEventDefinitions, useEventSettings } from '../hooks';
import { SchemaSettingsKey, SchemaDefinitionsKey } from '../types';
const WarpComponent = (props: any) => {
const fieldSchema = useFieldSchema();
useEventDefinitions(fieldSchema?.[SchemaDefinitionsKey]);
useEventSettings(fieldSchema?.[SchemaSettingsKey]);
return props.children;
};
export const withSchemaEvent = (Component: ComponentType) => {
const displayName = Component.displayName || Component.name;
const ComponentParse = (props: any) => {
return (
<WarpComponent>
<Component {...props}>{props.children}</Component>
</WarpComponent>
);
};
Component.displayName = displayName;
ComponentParse.displayName = `withSchemaEvent(${displayName})`;
return ComponentParse;
};

View File

@ -7,4 +7,5 @@
* For more information, please refer to: https://www.nocobase.com/agreement.
*/
export * from './useEventFlow';
export * from './useEventDefinitions';
export * from './useEventSettings';

View File

@ -0,0 +1,33 @@
/**
* 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 { EventDefinition, EventSetting } from '../types';
import { useFieldSchema } from '@formily/react';
import { useApp, usePlugin, useSchemaSettings } from '@nocobase/client';
import React from 'react';
import { ISchema, useField } from '@formily/react';
import { EventFlowPlugin } from '..';
export const useEvent = () => {
const eventFlowPlugin = usePlugin(EventFlowPlugin.name) as any;
return {
// 定义事件
define: (events: EventDefinition[]) => {
eventFlowPlugin.registerEvents(events);
},
// 注册事件
register: (events: EventSetting[]) => {
eventFlowPlugin.registerEvents(events);
},
// 触发事件
emit: (event: EventDefinition) => {
eventFlowPlugin.emit(event);
},
};
};

View File

@ -0,0 +1,14 @@
/**
* 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 { EventDefinition } from '../types';
export const useEventDefinitions = (definitions?: EventDefinition[]) => {
// console.log(definitions);
};

View File

@ -7,16 +7,15 @@
* For more information, please refer to: https://www.nocobase.com/agreement.
*/
import { EventSetting } from '../types';
import { useFieldSchema } from '@formily/react';
import { useApp, usePlugin, useSchemaSettings } from '@nocobase/client';
import React from 'react';
import { ISchema, useField } from '@formily/react';
import EventsSetting from '../components/EventsSetting';
import { EventFlowPlugin } from '..';
import { useEvent } from './useEvent';
export const useEventFlow = () => {
const fieldSchema = useFieldSchema();
const eventFlowPlugin = usePlugin(EventFlowPlugin.name) as any;
console.log('eventFlowPlugin', eventFlowPlugin, fieldSchema);
eventFlowPlugin.registerEvents(fieldSchema?.['x-event-flow-setting'] || []);
export const useEventSettings = (settings?: EventSetting[]) => {
const { register } = useEvent();
register(settings || []);
};

View File

@ -7,90 +7,6 @@
* For more information, please refer to: https://www.nocobase.com/agreement.
*/
import { Plugin } from '../application/Plugin';
import { IEventFlowEvent, PluginName } from './types';
import { EventSettingItem } from './EventSettingItem';
import { uniqBy } from 'lodash';
import { EventFlowProvider } from './EventFlowProvider';
interface IEventParam {
name: string;
title: string;
description: string;
type: string;
}
export interface IEventFlowModule {
name: string;
title: string;
description: string;
actions?: Array<{
name: string;
title: string;
description?: string;
params: IEventParam[];
fn: (params: any) => void;
}>;
events?: Array<{
name: string;
title: string;
description: string;
params: IEventParam[];
}>;
states?: IEventParam[];
}
export class EventFlowPlugin extends Plugin {
static name = PluginName;
modules: IEventFlowModule[] = [];
events: Map<string, IEventFlowEvent> = new Map();
async afterAdd() {
// await this.app.pm.add()
}
async beforeLoad() {}
// You can get and modify the app instance here
async load() {
this.schemaSettingsManager.addItem('PageSettings', PluginName, {
Component: EventSettingItem,
});
this.app.use(EventFlowProvider);
// this.app.addComponents({})
// this.app.addScopes({})
// this.app.addProvider()
// this.app.addProviders()
// this.app.router.add()
}
register(values: IEventFlowModule) {
this.modules.push(values);
this.modules = uniqBy(this.modules, 'name');
}
// 触发事件
emit(moduleName: string, eventName: string, params: any) {
console.log('emit', moduleName, eventName, params);
const event = this.events.find((event) => event.event === `${moduleName}.${eventName}`);
if (event) {
event.actions.forEach((action) => {
const actionModuleName = action.split('.')[0];
const actionName = action.split('.')[1];
const module = this.modules.find((module) => module.name === moduleName);
const moduleAction = this.modules
.find((module) => module.name === actionModuleName)
?.actions?.find((action) => action.name === actionName);
console.log('moduleAction', moduleAction);
if (moduleAction) {
moduleAction?.fn(params);
}
});
}
}
on(event: IEventFlowEvent) {
this.events.set(event.event, event);
}
registerEvents(events: IEventFlowEvent[]) {
events.forEach((event) => {
this.on(event);
});
}
}
export * from './types';
export * from './hoc/withSchemaEvent';
export * from './EventFlowPlugin';

View File

@ -7,9 +7,46 @@
* For more information, please refer to: https://www.nocobase.com/agreement.
*/
export const PluginName = 'event-flow';
export const PluginName = 'event';
export const SchemaSettingsKey = 'x-event-settings';
export const SchemaDefinitionsKey = 'x-event-definitions';
export interface IEventFlowEvent {
interface IEventParam {
name: string;
title: string;
description: string;
type: string;
}
/** 事件动作 */
export interface EventAction {
name: string;
title: string;
description?: string;
params: IEventParam[];
fn: (params: any) => void;
}
/** 事件事件 */
export interface EventEvent {
name: string;
title: string;
description: string;
params: IEventParam[];
}
/** 事件定义 */
export interface EventDefinition {
name: string;
title: string;
description: string;
actions?: EventAction[];
events?: EventEvent[];
states?: IEventParam[];
}
/** 事件设置 */
export interface EventSetting {
event: string;
condition: string;
actions: string[];

View File

@ -12,5 +12,6 @@ import { useCreateFormBlockEventsInterface } from './useCreateFormBlockEventsInt
export function useCreateFormBlockProps() {
useCreateFormBlockEventsInterface();
console.log('11111');
return useFormBlockProps();
}

View File

@ -42,7 +42,6 @@ import { ErrorFallback } from '../error-fallback';
import { useStyles } from './Page.style';
import { PageDesigner, PageTabDesigner } from './PageTabDesigner';
import { PopupRouteContextResetter } from './PopupRouteContextResetter';
import { useEventFlow } from '../../../event-flow/hooks';
interface PageProps {
currentTabUid: string;
@ -50,7 +49,6 @@ interface PageProps {
}
const InternalPage = React.memo((props: PageProps) => {
useEventFlow();
const fieldSchema = useFieldSchema();
const currentTabUid = props.currentTabUid;
const disablePageHeader = fieldSchema['x-component-props']?.disablePageHeader;