mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-07 14:39:25 +08:00
feat: add types
This commit is contained in:
parent
0a814b48a3
commit
3e933fe4d3
@ -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>) {
|
||||
|
71
packages/core/client/src/event-flow/EventFlowPlugin.tsx
Normal file
71
packages/core/client/src/event-flow/EventFlowPlugin.tsx
Normal 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);
|
||||
});
|
||||
}
|
||||
}
|
@ -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: [],
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
35
packages/core/client/src/event-flow/hoc/withSchemaEvent.tsx
Normal file
35
packages/core/client/src/event-flow/hoc/withSchemaEvent.tsx
Normal 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;
|
||||
};
|
@ -7,4 +7,5 @@
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
export * from './useEventFlow';
|
||||
export * from './useEventDefinitions';
|
||||
export * from './useEventSettings';
|
||||
|
33
packages/core/client/src/event-flow/hooks/useEvent.tsx
Normal file
33
packages/core/client/src/event-flow/hooks/useEvent.tsx
Normal 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);
|
||||
},
|
||||
};
|
||||
};
|
@ -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);
|
||||
};
|
@ -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 || []);
|
||||
};
|
@ -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';
|
||||
|
@ -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[];
|
||||
|
@ -12,5 +12,6 @@ import { useCreateFormBlockEventsInterface } from './useCreateFormBlockEventsInt
|
||||
|
||||
export function useCreateFormBlockProps() {
|
||||
useCreateFormBlockEventsInterface();
|
||||
console.log('11111');
|
||||
return useFormBlockProps();
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user