chore: api improve and update demo

This commit is contained in:
gchust 2025-04-19 22:20:48 +08:00
parent 89441cfc0b
commit a57db34dd1
11 changed files with 238 additions and 25 deletions

View File

@ -327,7 +327,7 @@ eventFlowManager.addFlow({
// --- FilterFlow 定义 ---
filterFlowManager.addFlow({
name: 'tabulator:columns',
key: 'tabulator:columns',
title: '表格列展示流程',
steps: [
{
@ -416,7 +416,7 @@ const EventFilterTableDemo: React.FC = (props) => {
[hooks, filterFlowParams],
);
const tableColumns = useApplyFilters(filterFlowManager, 'tabulator:columns', {}, filterContext);
const { columns: tableColumns } = useApplyFilters(filterFlowManager, 'tabulator:columns', null, filterContext);
// 初始化和刷新数据
const refreshData = useCallback(async () => {

View File

@ -30,7 +30,7 @@ filterFlowManager.addFilter({
// 创建过滤器流
filterFlowManager.addFlow({
name: 'basic-text-transform',
key: 'basic-text-transform',
title: '基础文本转换',
steps: [
{

View File

@ -1,5 +1,5 @@
import { Button, Card, Input, Radio, Space, Typography } from 'antd';
import React, { useMemo, useState } from 'react';
import { Card, Input, Space, Typography } from 'antd';
import React, { useState } from 'react';
import { FilterFlowManager, useApplyFilters } from '@nocobase/client';
// 创建FilterFlowManager实例
@ -60,7 +60,7 @@ filterFlowManager.addFilter({
// 创建条件FilterFlow
filterFlowManager.addFlow({
name: 'conditional-text-transform',
key: 'conditional-text-transform',
title: '条件文本转换',
steps: [
{

View File

@ -119,7 +119,7 @@ filterFlowManager.addFilter({
// 创建可配置FilterFlow
filterFlowManager.addFlow({
name: 'configurable-text-transform',
key: 'configurable-text-transform',
title: '可配置文本转换',
steps: [
{

View File

@ -160,7 +160,7 @@ filterFlowManager.addFilter({
// 创建FilterFlow
filterFlowManager.addFlow({
name: 'data-transform-flow',
key: 'data-transform-flow',
title: '数据转换流程',
steps: [
{

View File

@ -0,0 +1,213 @@
import { Card, Space, Typography, Input, Button, Form, Checkbox } from 'antd';
import React, { useState, useEffect, useMemo } from 'react';
import { FilterFlowManager, useApplyFilters } from '@nocobase/client';
// 创建过滤器管理器实例
const filterFlowManager = new FilterFlowManager();
// 注册过滤器组
filterFlowManager.addFilterGroup({
name: 'visibilityControl',
title: '可见性控制',
sort: 1,
});
// 注册过滤器
filterFlowManager.addFilter({
name: 'showHideElements',
title: '显示/隐藏元素',
description: '根据条件控制 actions 和 fields 的可见性',
group: 'visibilityControl',
sort: 1,
uiSchema: {
showActions: {
type: 'array',
title: '显示的操作',
enum: [
{ label: 'Action 1', value: 'action1' },
{ label: 'Action 2', value: 'action2' },
{ label: 'Action 3', value: 'action3' },
],
default: ['action1', 'action2', 'action3'],
'x-decorator': 'FormItem',
'x-component': 'Checkbox.Group',
},
showFields: {
type: 'array',
title: '显示的字段',
enum: [
{ label: 'Field 1', value: 'field1' },
{ label: 'Field 2', value: 'field2' },
{ label: 'Field 3', value: 'field3' },
],
default: ['field1', 'field2', 'field3'],
'x-decorator': 'FormItem',
'x-component': 'Checkbox.Group',
},
},
handler: (currentValue, params, context) => {
// 过滤器处理函数,返回应显示的元素配置
return {
visibleActions: params.showActions || [],
visibleFields: params.showFields || [],
};
},
});
// 创建过滤器流
filterFlowManager.addFlow({
key: 'visibility-control',
title: '元素可见性控制',
steps: [
{
key: 'show-hide-step',
filterName: 'showHideElements',
title: '控制元素可见性',
},
],
});
const HideShowFilterFlow = () => {
const [filterParams, setFilterParams] = useState({
showActions: ['action1', 'action2', 'action3'],
showFields: ['field1', 'field2', 'field3'],
});
const filterContext = useMemo(() => {
return {
meta: {
params: {
'show-hide-step': filterParams,
},
},
};
}, [filterParams]);
// 应用过滤器获取可见性配置
const visibilityConfig = useApplyFilters(filterFlowManager, 'visibility-control', null, filterContext);
// 渲染 Action 按钮
const renderActions = () => {
const actions = [
{ key: 'action1', title: 'Action 1', color: '#1890ff' },
{ key: 'action2', title: 'Action 2', color: '#52c41a' },
{ key: 'action3', title: 'Action 3', color: '#faad14' },
];
return (
<Space>
{actions.map((action) => (
<Button
key={action.key}
type="primary"
style={{
display: visibilityConfig?.visibleActions?.includes(action.key) ? 'inline-block' : 'none',
backgroundColor: action.color,
}}
>
{action.title}
</Button>
))}
</Space>
);
};
// 渲染 Field 表单项
const renderFields = () => {
const fields = [
{ key: 'field1', title: 'Field 1', placeholder: '请输入 Field 1' },
{ key: 'field2', title: 'Field 2', placeholder: '请输入 Field 2' },
{ key: 'field3', title: 'Field 3', placeholder: '请输入 Field 3' },
];
return (
<Form layout="vertical">
{fields.map((field) => (
<Form.Item
key={field.key}
label={field.title}
style={{
display: visibilityConfig?.visibleFields?.includes(field.key) ? 'block' : 'none',
}}
>
<Input placeholder={field.placeholder} />
</Form.Item>
))}
</Form>
);
};
// 过滤器配置表单
const handleVisibilityChange = (type, values) => {
setFilterParams((prev) => ({
...prev,
[type]: values,
}));
};
return (
<div style={{ padding: 24, background: '#f5f5f5', borderRadius: 8 }}>
<Typography.Title level={4}>/</Typography.Title>
<Typography.Paragraph>
使actions fields
</Typography.Paragraph>
<Card title="配置可见性" style={{ marginBottom: 16 }}>
<Space direction="vertical" style={{ width: '100%' }}>
<div>
<Typography.Text strong>:</Typography.Text>
<div>
<Checkbox.Group
options={[
{ label: 'Action 1', value: 'action1' },
{ label: 'Action 2', value: 'action2' },
{ label: 'Action 3', value: 'action3' },
]}
value={filterParams.showActions}
onChange={(values) => handleVisibilityChange('showActions', values)}
/>
</div>
</div>
<div>
<Typography.Text strong>:</Typography.Text>
<div>
<Checkbox.Group
options={[
{ label: 'Field 1', value: 'field1' },
{ label: 'Field 2', value: 'field2' },
{ label: 'Field 3', value: 'field3' },
]}
value={filterParams.showFields}
onChange={(values) => handleVisibilityChange('showFields', values)}
/>
</div>
</div>
</Space>
</Card>
<Card title="过滤器效果" style={{ marginBottom: 16 }}>
<Space direction="vertical" style={{ width: '100%' }}>
<div>
<Typography.Text strong>:</Typography.Text>
<div style={{ margin: '16px 0' }}>{renderActions()}</div>
</div>
<div>
<Typography.Text strong>:</Typography.Text>
<div style={{ margin: '16px 0' }}>{renderFields()}</div>
</div>
</Space>
</Card>
<Card title="过滤器结果" style={{ marginBottom: 16 }}>
<Space direction="vertical" style={{ width: '100%' }}>
<div>
<Typography.Text code>visibilityConfig:</Typography.Text>
<pre>{JSON.stringify(visibilityConfig, null, 2)}</pre>
</div>
</Space>
</Card>
</div>
);
};
export default HideShowFilterFlow;

View File

@ -84,7 +84,7 @@ filterFlowManager.addFilter({
// 创建多步骤FilterFlow
filterFlowManager.addFlow({
name: 'multi-step-text-transform',
key: 'multi-step-text-transform',
title: '多步骤文本转换',
steps: [
{

View File

@ -26,14 +26,12 @@ export interface EventContext<T = any> {
userId?: string;
event?: string | string[]; // 事件名称, 一个事件是可以触发多个eventflow的与filterflow不同
[key: string]: any;
// params?: Record<string, Record<string, any>>;
eventParams?: {
flow?: string;
params?: Record<string, Record<string, any>>;
}[];
actionParams?: {
flow?: string;
event?: string;
params?: Record<string, Record<string, any>>;
}[];
};

View File

@ -108,8 +108,8 @@ export class FilterFlow {
delete this.options.steps;
}
get name() {
return this.options.name;
get key() {
return this.options.key;
}
get title() {
@ -176,7 +176,7 @@ export class FilterFlow {
}
async remove() {
this.filterFlowManager.removeFlow(this.name);
this.filterFlowManager.removeFlow(this.key);
}
setFilterFlowManager(filterFlowManager: FilterFlowManager) {
@ -285,16 +285,16 @@ export class FilterFlowManager {
flowInstance = flowOptions;
flowInstance.setFilterFlowManager(this);
} else {
if (!flowOptions.name) {
throw new Error('FilterFlowOptions must have a name.');
if (!flowOptions.key) {
throw new Error('FilterFlowOptions must have a key.');
}
flowInstance = new FilterFlow(flowOptions, this);
}
if (this.filterFlows.has(flowInstance.name)) {
console.warn(`FilterFlow with name "${flowInstance.name}" is being overwritten.`);
if (this.filterFlows.has(flowInstance.key)) {
console.warn(`FilterFlow with key "${flowInstance.key}" is being overwritten.`);
}
this.filterFlows.set(flowInstance.name, flowInstance);
this.filterFlows.set(flowInstance.key, flowInstance);
return flowInstance;
}
@ -371,8 +371,7 @@ export class FilterFlowManager {
context = context || {};
if (!context.meta) {
context.meta = {
flowKey,
flowName: flow.name,
flowKey: flow.key,
};
}

View File

@ -39,14 +39,15 @@ export function useApplyFilters<T = any>(
useEffect(() => {
if (prevValue.current !== initialValue) {
setTimeout(async () => {
const refreshData = async () => {
const cachedEntry = filterCache.get(cacheKey);
if (cachedEntry?.status === 'resolved') {
const newData = await filterFlowManager.applyFilters(flowName, initialValue, context);
filterCache.set(cacheKey, { status: 'resolved', data: newData, promise: Promise.resolve(newData) });
forceUpdate((prev) => prev + 1);
}
}, 0);
};
refreshData();
prevValue.current = initialValue;
}
}, [initialValue]);

View File

@ -15,10 +15,12 @@ export type FilterHandlerContext<T = any> = {
meta?: {
flowKey?: string;
flowName?: string;
params?: Record<string, Record<string, any>>;
params?: FilterStepParams;
};
};
export type FilterStepParams = Record<string, Record<string, any>>;
export type FilterHandler<T = any> = (
currentValue: any,
params?: Record<string, any>,
@ -45,7 +47,7 @@ export interface FilterFlowStepOptions {
condition?: string;
}
export interface FilterFlowOptions {
name: string;
key: string;
title: string;
steps: FilterFlowStepOptions[];
}