mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-05 21:49:25 +08:00
chore: api and demo update
This commit is contained in:
parent
2ac824c85a
commit
f87d5f0e49
@ -139,36 +139,63 @@ eventFlowManager.addFlow({
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const PARAMS = {
|
||||||
|
events: {
|
||||||
|
'button-id': {
|
||||||
|
stepParams: {
|
||||||
|
'message-step': {
|
||||||
|
title: '消息标题',
|
||||||
|
content: '这是一条测试消息',
|
||||||
|
type: 'info',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
filters: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
const getParams = async (id: string) => {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
resolve(PARAMS['events'][id]); // 模拟异步获取
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const setParams = async (id: string, params: Record<string, any>) => {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
PARAMS['events'][id] = params; // 模拟异步更新
|
||||||
|
resolve(params);
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// 主演示组件
|
// 主演示组件
|
||||||
const ConfigurableActionDemo = () => {
|
const ConfigurableActionDemo = () => {
|
||||||
const [currentParams, setCurrentParams] = useState<Record<string, any>>({
|
const componentId = 'button-id';
|
||||||
title: '消息标题',
|
|
||||||
content: '这是一条测试消息',
|
|
||||||
type: 'info',
|
|
||||||
});
|
|
||||||
|
|
||||||
// 打开配置弹窗
|
// 打开配置弹窗
|
||||||
const showConfig = () => {
|
const showConfig = async () => {
|
||||||
const step = eventFlowManager.getFlow('message-flow').getStep('message-step');
|
const step = eventFlowManager.getFlow('message-flow').getStep('message-step');
|
||||||
const ctx = {
|
const ctx = {
|
||||||
payload: {
|
payload: {
|
||||||
step,
|
step,
|
||||||
onChange: (values) => {
|
onChange: async (values) => {
|
||||||
setCurrentParams(values);
|
await setParams(componentId, values);
|
||||||
},
|
},
|
||||||
currentParams,
|
currentParams: await getParams(componentId),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
eventBus.dispatchEvent('configure:click', ctx);
|
eventBus.dispatchEvent('configure:click', ctx);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 触发消息动作
|
// 触发消息动作
|
||||||
const triggerAction = () => {
|
const triggerAction = async () => {
|
||||||
const ctx = {
|
const ctx = {
|
||||||
payload: {},
|
payload: {},
|
||||||
meta: {
|
meta: {
|
||||||
stepParams: {
|
stepParams: {
|
||||||
'message-step': currentParams,
|
'message-step': await getParams(componentId),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -182,15 +209,6 @@ const ConfigurableActionDemo = () => {
|
|||||||
点击"配置参数"按钮修改消息的标题、内容和类型,然后点击"执行动作"查看效果。
|
点击"配置参数"按钮修改消息的标题、内容和类型,然后点击"执行动作"查看效果。
|
||||||
</Typography.Paragraph>
|
</Typography.Paragraph>
|
||||||
|
|
||||||
<div style={{ marginBottom: 16 }}>
|
|
||||||
<Typography.Text strong>当前配置:</Typography.Text>
|
|
||||||
<ul>
|
|
||||||
<li>标题: {currentParams.title}</li>
|
|
||||||
<li>内容: {currentParams.content}</li>
|
|
||||||
<li>类型: {currentParams.type}</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Space>
|
<Space>
|
||||||
<Button type="primary" onClick={showConfig}>
|
<Button type="primary" onClick={showConfig}>
|
||||||
配置参数
|
配置参数
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Button, Card, Form, Input, Select, Space, Typography, Modal, Switch, InputNumber } from 'antd';
|
import { Button, Card, Form, Input, Select, Space, Typography, Modal, Switch, InputNumber } from 'antd';
|
||||||
import React, { useMemo, useState } from 'react';
|
import React, { useCallback, useMemo, useState } from 'react';
|
||||||
import { FilterFlowManager, useApplyFilters } from '@nocobase/client';
|
import { FilterFlowManager, FilterHandlerContext, FilterStepParams, useApplyFilters } from '@nocobase/client';
|
||||||
import { configureAction } from '../actions/open-configure-dialog';
|
import { configureAction } from '../actions/open-configure-dialog';
|
||||||
|
|
||||||
// 创建FilterFlowManager实例
|
// 创建FilterFlowManager实例
|
||||||
@ -135,42 +135,65 @@ filterFlowManager.addFlow({
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
const ConfigurableFilter = () => {
|
const PARAMS = {
|
||||||
const [inputText, setInputText] = useState('Hello configurable filter demo');
|
filters: {
|
||||||
const [stepParams, setStepParams] = useState({
|
'demo-id': {
|
||||||
'replace-step': {
|
'replace-step': {
|
||||||
search: 'Hello',
|
search: 'Hello',
|
||||||
replacement: 'hi',
|
replacement: 'hi',
|
||||||
useRegex: false,
|
useRegex: false,
|
||||||
|
},
|
||||||
|
'truncate-step': {
|
||||||
|
maxLength: 10,
|
||||||
|
suffix: '...',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
'truncate-step': {
|
},
|
||||||
maxLength: 10,
|
};
|
||||||
suffix: '...',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const context = useMemo(
|
const getParams = async (id: string): Promise<FilterStepParams> => {
|
||||||
() => ({
|
return new Promise((resolve) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
resolve(PARAMS['filters'][id]); // 模拟异步获取
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const setParams = async (id: string, params: Record<string, any>) => {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
PARAMS['filters'][id] = params; // 模拟异步更新
|
||||||
|
resolve(params);
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const ConfigurableFilter = () => {
|
||||||
|
const demoId = 'demo-id';
|
||||||
|
const [inputText, setInputText] = useState('Hello configurable filter demo');
|
||||||
|
|
||||||
|
const getContext = useCallback(
|
||||||
|
async (): Promise<FilterHandlerContext> => ({
|
||||||
meta: {
|
meta: {
|
||||||
params: stepParams,
|
params: await getParams(demoId),
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
[inputText, stepParams],
|
[demoId],
|
||||||
);
|
);
|
||||||
|
|
||||||
const outputText = useApplyFilters(filterFlowManager, 'configurable-text-transform', inputText, context);
|
const outputText = useApplyFilters(filterFlowManager, 'configurable-text-transform', inputText, getContext, demoId);
|
||||||
|
|
||||||
// 打开配置Modal
|
// 打开配置Modal
|
||||||
const openConfigModal = (stepKey) => {
|
const openConfigModal = async (stepKey) => {
|
||||||
const flow = filterFlowManager.getFlow('configurable-text-transform');
|
const flow = filterFlowManager.getFlow('configurable-text-transform');
|
||||||
const step = flow.getStep(stepKey);
|
const step = flow.getStep(stepKey);
|
||||||
const actionContext = {
|
const actionContext = {
|
||||||
payload: {
|
payload: {
|
||||||
step,
|
step,
|
||||||
currentParams: stepParams[stepKey],
|
currentParams: (await getParams(demoId))?.[stepKey],
|
||||||
onChange: (values) => {
|
onChange: async (values) => {
|
||||||
setStepParams({
|
// await setParams(demoId, PARAMS['filters'][demoId]);
|
||||||
...stepParams,
|
await setParams(demoId, {
|
||||||
|
...PARAMS['filters'][demoId],
|
||||||
[stepKey]: values,
|
[stepKey]: values,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -197,15 +197,6 @@ const HideShowFilterFlow = () => {
|
|||||||
</div>
|
</div>
|
||||||
</Space>
|
</Space>
|
||||||
</Card>
|
</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>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -21,6 +21,11 @@
|
|||||||
|
|
||||||
<code src="./demos/filters/multi-step-filterflow.tsx"></code>
|
<code src="./demos/filters/multi-step-filterflow.tsx"></code>
|
||||||
|
|
||||||
|
## 控制元素可见性过滤器流
|
||||||
|
演示如何控制元素的可见性
|
||||||
|
|
||||||
|
<code src="./demos/filters/hide-show-filterflow.tsx"></code>
|
||||||
|
|
||||||
## 数据转换过滤器流
|
## 数据转换过滤器流
|
||||||
展示如何使用过滤器流转换数据
|
展示如何使用过滤器流转换数据
|
||||||
|
|
||||||
|
@ -25,24 +25,36 @@ export function useApplyFilters<T = any>(
|
|||||||
filterFlowManager: FilterFlowManager,
|
filterFlowManager: FilterFlowManager,
|
||||||
flowName: string,
|
flowName: string,
|
||||||
initialValue: any,
|
initialValue: any,
|
||||||
context?: FilterHandlerContext,
|
context?: FilterHandlerContext | (() => Promise<FilterHandlerContext>),
|
||||||
|
id?: string,
|
||||||
): T {
|
): T {
|
||||||
const [, forceUpdate] = useState(0);
|
const [, forceUpdate] = useState(0);
|
||||||
|
|
||||||
const cacheKey = useMemo(() => {
|
const cacheKey = useMemo(() => {
|
||||||
const key = JSON.stringify([flowName, context]);
|
if (id) {
|
||||||
return key;
|
return `${flowName}-${id}`;
|
||||||
}, [flowName, context]);
|
}
|
||||||
|
return JSON.stringify([flowName, context]);
|
||||||
|
}, [flowName, context, id]);
|
||||||
|
|
||||||
const prevValue = useRef(initialValue);
|
const prevValue = useRef(initialValue);
|
||||||
const prevCacheKey = useRef(cacheKey);
|
const prevCacheKey = useRef(cacheKey);
|
||||||
|
const contextPromise = new Promise<FilterHandlerContext>((resolve, reject) => {
|
||||||
|
if (typeof context === 'function') {
|
||||||
|
context().then(resolve).catch(reject);
|
||||||
|
} else {
|
||||||
|
resolve(context);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (prevValue.current !== initialValue) {
|
if (prevValue.current !== initialValue) {
|
||||||
const refreshData = async () => {
|
const refreshData = async () => {
|
||||||
const cachedEntry = filterCache.get(cacheKey);
|
const cachedEntry = filterCache.get(cacheKey);
|
||||||
if (cachedEntry?.status === 'resolved') {
|
if (cachedEntry?.status === 'resolved') {
|
||||||
const newData = await filterFlowManager.applyFilters(flowName, initialValue, context);
|
const newData = await contextPromise.then((ctx) =>
|
||||||
|
filterFlowManager.applyFilters(flowName, initialValue, ctx),
|
||||||
|
);
|
||||||
filterCache.set(cacheKey, { status: 'resolved', data: newData, promise: Promise.resolve(newData) });
|
filterCache.set(cacheKey, { status: 'resolved', data: newData, promise: Promise.resolve(newData) });
|
||||||
forceUpdate((prev) => prev + 1);
|
forceUpdate((prev) => prev + 1);
|
||||||
}
|
}
|
||||||
@ -50,7 +62,8 @@ export function useApplyFilters<T = any>(
|
|||||||
refreshData();
|
refreshData();
|
||||||
prevValue.current = initialValue;
|
prevValue.current = initialValue;
|
||||||
}
|
}
|
||||||
}, [initialValue]);
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [initialValue]); //输入变化时,应该重新计算
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (prevCacheKey.current !== cacheKey) {
|
if (prevCacheKey.current !== cacheKey) {
|
||||||
@ -77,8 +90,8 @@ export function useApplyFilters<T = any>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 创建新的 Promise
|
// 创建新的 Promise
|
||||||
const promise = filterFlowManager
|
const promise = contextPromise
|
||||||
.applyFilters(flowName, initialValue, context)
|
.then((ctx) => filterFlowManager.applyFilters(flowName, initialValue, ctx))
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
// 成功时更新缓存
|
// 成功时更新缓存
|
||||||
filterCache.set(cacheKey, { status: 'resolved', data: result, promise });
|
filterCache.set(cacheKey, { status: 'resolved', data: result, promise });
|
||||||
|
Loading…
x
Reference in New Issue
Block a user