mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-07-01 18:52:20 +08:00
feat: add settingsMenuLevel parameter to control menu hierarchy
This commit is contained in:
parent
a8546e3599
commit
75b4de9b07
@ -75,6 +75,9 @@ interface FlowModelRendererProps {
|
||||
|
||||
/** 是否在最外层包装 FlowErrorFallback 组件,默认 false */
|
||||
showErrorFallback?: boolean; // 默认 false
|
||||
|
||||
/** 设置菜单层级:1=仅当前模型(默认),2=包含子模型 */
|
||||
settingsMenuLevel?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -89,6 +92,7 @@ const FlowModelRendererWithAutoFlows: React.FC<{
|
||||
sharedContext?: Record<string, any>;
|
||||
independentAutoFlowExecution?: boolean;
|
||||
showErrorFallback?: boolean;
|
||||
settingsMenuLevel?: number;
|
||||
}> = observer(
|
||||
({
|
||||
model,
|
||||
@ -99,6 +103,7 @@ const FlowModelRendererWithAutoFlows: React.FC<{
|
||||
sharedContext,
|
||||
independentAutoFlowExecution,
|
||||
showErrorFallback,
|
||||
settingsMenuLevel,
|
||||
}) => {
|
||||
useApplyAutoFlows(model, extraContext, !independentAutoFlowExecution);
|
||||
|
||||
@ -110,6 +115,7 @@ const FlowModelRendererWithAutoFlows: React.FC<{
|
||||
flowSettingsVariant={flowSettingsVariant}
|
||||
hideRemoveInSettings={hideRemoveInSettings}
|
||||
showErrorFallback={showErrorFallback}
|
||||
settingsMenuLevel={settingsMenuLevel}
|
||||
/>
|
||||
</FlowModelProvider>
|
||||
);
|
||||
@ -126,8 +132,17 @@ const FlowModelRendererWithoutAutoFlows: React.FC<{
|
||||
hideRemoveInSettings: boolean;
|
||||
sharedContext?: Record<string, any>;
|
||||
showErrorFallback?: boolean;
|
||||
settingsMenuLevel?: number;
|
||||
}> = observer(
|
||||
({ model, showFlowSettings, flowSettingsVariant, hideRemoveInSettings, sharedContext, showErrorFallback }) => {
|
||||
({
|
||||
model,
|
||||
showFlowSettings,
|
||||
flowSettingsVariant,
|
||||
hideRemoveInSettings,
|
||||
sharedContext,
|
||||
showErrorFallback,
|
||||
settingsMenuLevel,
|
||||
}) => {
|
||||
return (
|
||||
<FlowModelProvider model={model}>
|
||||
<FlowModelRendererCore
|
||||
@ -136,6 +151,7 @@ const FlowModelRendererWithoutAutoFlows: React.FC<{
|
||||
flowSettingsVariant={flowSettingsVariant}
|
||||
hideRemoveInSettings={hideRemoveInSettings}
|
||||
showErrorFallback={showErrorFallback}
|
||||
settingsMenuLevel={settingsMenuLevel}
|
||||
/>
|
||||
</FlowModelProvider>
|
||||
);
|
||||
@ -151,68 +167,75 @@ const FlowModelRendererCore: React.FC<{
|
||||
flowSettingsVariant: string;
|
||||
hideRemoveInSettings: boolean;
|
||||
showErrorFallback?: boolean;
|
||||
}> = observer(({ model, showFlowSettings, flowSettingsVariant, hideRemoveInSettings, showErrorFallback }) => {
|
||||
// 渲染模型内容
|
||||
const modelContent = model.render();
|
||||
settingsMenuLevel?: number;
|
||||
}> = observer(
|
||||
({ model, showFlowSettings, flowSettingsVariant, hideRemoveInSettings, showErrorFallback, settingsMenuLevel }) => {
|
||||
// 渲染模型内容
|
||||
const modelContent = model.render();
|
||||
|
||||
// 包装 ErrorBoundary 的辅助函数
|
||||
const wrapWithErrorBoundary = (children: React.ReactNode) => {
|
||||
if (showErrorFallback) {
|
||||
return <ErrorBoundary FallbackComponent={FlowErrorFallback}>{children}</ErrorBoundary>;
|
||||
// 包装 ErrorBoundary 的辅助函数
|
||||
const wrapWithErrorBoundary = (children: React.ReactNode) => {
|
||||
if (showErrorFallback) {
|
||||
return <ErrorBoundary FallbackComponent={FlowErrorFallback}>{children}</ErrorBoundary>;
|
||||
}
|
||||
return children;
|
||||
};
|
||||
|
||||
// 如果不显示流程设置,直接返回模型内容(可能包装 ErrorBoundary)
|
||||
if (!showFlowSettings) {
|
||||
return wrapWithErrorBoundary(modelContent);
|
||||
}
|
||||
return children;
|
||||
};
|
||||
|
||||
// 如果不显示流程设置,直接返回模型内容(可能包装 ErrorBoundary)
|
||||
if (!showFlowSettings) {
|
||||
return wrapWithErrorBoundary(modelContent);
|
||||
}
|
||||
// 根据 flowSettingsVariant 包装相应的设置组件
|
||||
switch (flowSettingsVariant) {
|
||||
case 'dropdown':
|
||||
return (
|
||||
<FlowsFloatContextMenu
|
||||
model={model}
|
||||
showDeleteButton={!hideRemoveInSettings}
|
||||
showBackground={_.isObject(showFlowSettings) ? showFlowSettings.showBackground : undefined}
|
||||
showBorder={_.isObject(showFlowSettings) ? showFlowSettings.showBorder : undefined}
|
||||
settingsMenuLevel={settingsMenuLevel}
|
||||
>
|
||||
{wrapWithErrorBoundary(modelContent)}
|
||||
</FlowsFloatContextMenu>
|
||||
);
|
||||
|
||||
// 根据 flowSettingsVariant 包装相应的设置组件
|
||||
switch (flowSettingsVariant) {
|
||||
case 'dropdown':
|
||||
return (
|
||||
<FlowsFloatContextMenu
|
||||
model={model}
|
||||
showDeleteButton={!hideRemoveInSettings}
|
||||
showBackground={_.isObject(showFlowSettings) ? showFlowSettings.showBackground : undefined}
|
||||
showBorder={_.isObject(showFlowSettings) ? showFlowSettings.showBorder : undefined}
|
||||
>
|
||||
{wrapWithErrorBoundary(modelContent)}
|
||||
</FlowsFloatContextMenu>
|
||||
);
|
||||
case 'contextMenu':
|
||||
return (
|
||||
<FlowsContextMenu model={model} showDeleteButton={!hideRemoveInSettings}>
|
||||
{wrapWithErrorBoundary(modelContent)}
|
||||
</FlowsContextMenu>
|
||||
);
|
||||
|
||||
case 'contextMenu':
|
||||
return (
|
||||
<FlowsContextMenu model={model} showDeleteButton={!hideRemoveInSettings}>
|
||||
{wrapWithErrorBoundary(modelContent)}
|
||||
</FlowsContextMenu>
|
||||
);
|
||||
case 'modal':
|
||||
// TODO: 实现 modal 模式的流程设置
|
||||
console.warn('FlowModelRenderer: modal variant is not implemented yet');
|
||||
return wrapWithErrorBoundary(modelContent);
|
||||
|
||||
case 'modal':
|
||||
// TODO: 实现 modal 模式的流程设置
|
||||
console.warn('FlowModelRenderer: modal variant is not implemented yet');
|
||||
return wrapWithErrorBoundary(modelContent);
|
||||
case 'drawer':
|
||||
// TODO: 实现 drawer 模式的流程设置
|
||||
console.warn('FlowModelRenderer: drawer variant is not implemented yet');
|
||||
return wrapWithErrorBoundary(modelContent);
|
||||
|
||||
case 'drawer':
|
||||
// TODO: 实现 drawer 模式的流程设置
|
||||
console.warn('FlowModelRenderer: drawer variant is not implemented yet');
|
||||
return wrapWithErrorBoundary(modelContent);
|
||||
|
||||
default:
|
||||
console.warn(`FlowModelRenderer: Unknown flowSettingsVariant '${flowSettingsVariant}', falling back to dropdown`);
|
||||
return (
|
||||
<FlowsFloatContextMenu
|
||||
model={model}
|
||||
showDeleteButton={!hideRemoveInSettings}
|
||||
showBackground={_.isObject(showFlowSettings) ? showFlowSettings.showBackground : undefined}
|
||||
showBorder={_.isObject(showFlowSettings) ? showFlowSettings.showBorder : undefined}
|
||||
>
|
||||
{wrapWithErrorBoundary(modelContent)}
|
||||
</FlowsFloatContextMenu>
|
||||
);
|
||||
}
|
||||
});
|
||||
default:
|
||||
console.warn(
|
||||
`FlowModelRenderer: Unknown flowSettingsVariant '${flowSettingsVariant}', falling back to dropdown`,
|
||||
);
|
||||
return (
|
||||
<FlowsFloatContextMenu
|
||||
model={model}
|
||||
showDeleteButton={!hideRemoveInSettings}
|
||||
showBackground={_.isObject(showFlowSettings) ? showFlowSettings.showBackground : undefined}
|
||||
showBorder={_.isObject(showFlowSettings) ? showFlowSettings.showBorder : undefined}
|
||||
settingsMenuLevel={settingsMenuLevel}
|
||||
>
|
||||
{wrapWithErrorBoundary(modelContent)}
|
||||
</FlowsFloatContextMenu>
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* A React component responsible for rendering a FlowModel.
|
||||
@ -228,6 +251,7 @@ const FlowModelRendererCore: React.FC<{
|
||||
* @param {any} props.extraContext - Extra context to pass to useApplyAutoFlows when skipApplyAutoFlows is false.
|
||||
* @param {any} props.sharedContext - Shared context to pass to the model.
|
||||
* @param {boolean} props.independentAutoFlowExecution - Whether each component has independent auto flow execution.
|
||||
* @param {number} props.settingsMenuLevel - Settings menu levels: 1=current model only (default), 2=include sub-models.
|
||||
* @returns {React.ReactNode | null} The rendered output of the model, or null if the model or its render method is invalid.
|
||||
*/
|
||||
export const FlowModelRenderer: React.FC<FlowModelRendererProps> = observer(
|
||||
@ -242,6 +266,7 @@ export const FlowModelRenderer: React.FC<FlowModelRendererProps> = observer(
|
||||
sharedContext,
|
||||
independentAutoFlowExecution = false,
|
||||
showErrorFallback = false,
|
||||
settingsMenuLevel,
|
||||
}) => {
|
||||
if (!model || typeof model.render !== 'function') {
|
||||
// 可以选择渲染 null 或者一个错误/提示信息
|
||||
@ -264,6 +289,7 @@ export const FlowModelRenderer: React.FC<FlowModelRendererProps> = observer(
|
||||
hideRemoveInSettings={hideRemoveInSettings}
|
||||
sharedContext={sharedContext}
|
||||
showErrorFallback={showErrorFallback}
|
||||
settingsMenuLevel={settingsMenuLevel}
|
||||
/>
|
||||
</Suspense>
|
||||
);
|
||||
@ -279,6 +305,7 @@ export const FlowModelRenderer: React.FC<FlowModelRendererProps> = observer(
|
||||
sharedContext={sharedContext}
|
||||
independentAutoFlowExecution={independentAutoFlowExecution}
|
||||
showErrorFallback={showErrorFallback}
|
||||
settingsMenuLevel={settingsMenuLevel}
|
||||
/>
|
||||
</Suspense>
|
||||
);
|
||||
|
@ -40,6 +40,7 @@ const renderToolbarItems = (
|
||||
showDeleteButton: boolean,
|
||||
showCopyUidButton: boolean,
|
||||
flowEngine: FlowEngine,
|
||||
settingsMenuLevel?: number,
|
||||
) => {
|
||||
const toolbarItems = flowEngine?.flowSettings?.getToolbarItems?.() || [];
|
||||
|
||||
@ -60,6 +61,7 @@ const renderToolbarItems = (
|
||||
model={model}
|
||||
showDeleteButton={showDeleteButton}
|
||||
showCopyUidButton={showCopyUidButton}
|
||||
menuLevels={settingsMenuLevel}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -144,6 +146,10 @@ interface ModelProvidedProps {
|
||||
* @default true
|
||||
*/
|
||||
showBackground?: boolean;
|
||||
/**
|
||||
* Settings menu levels: 1=current model only (default), 2=include sub-models
|
||||
*/
|
||||
settingsMenuLevel?: number;
|
||||
}
|
||||
|
||||
interface ModelByIdProps {
|
||||
@ -163,6 +169,10 @@ interface ModelByIdProps {
|
||||
* @default true
|
||||
*/
|
||||
showBackground?: boolean;
|
||||
/**
|
||||
* Settings menu levels: 1=current model only (default), 2=include sub-models
|
||||
*/
|
||||
settingsMenuLevel?: number;
|
||||
}
|
||||
|
||||
type FlowsFloatContextMenuProps = ModelProvidedProps | ModelByIdProps;
|
||||
@ -193,6 +203,7 @@ const isModelByIdProps = (props: FlowsFloatContextMenuProps): props is ModelById
|
||||
* @param props.showCopyUidButton 是否显示复制UID按钮,默认为true
|
||||
* @param props.containerStyle 容器自定义样式
|
||||
* @param props.className 容器自定义类名
|
||||
* @param props.settingsMenuLevel 设置菜单层级:1=仅当前模型(默认),2=包含子模型
|
||||
*/
|
||||
const FlowsFloatContextMenu: React.FC<FlowsFloatContextMenuProps> = observer((props) => {
|
||||
const flowEngine = useFlowEngine();
|
||||
@ -219,6 +230,7 @@ const FlowsFloatContextMenuWithModel: React.FC<ModelProvidedProps> = observer(
|
||||
className,
|
||||
showBackground = true,
|
||||
showBorder = true,
|
||||
settingsMenuLevel,
|
||||
}: ModelProvidedProps) => {
|
||||
const [hideMenu, setHideMenu] = useState<boolean>(false);
|
||||
const [hasButton, setHasButton] = useState<boolean>(false);
|
||||
@ -293,7 +305,7 @@ const FlowsFloatContextMenuWithModel: React.FC<ModelProvidedProps> = observer(
|
||||
<div className="general-schema-designer">
|
||||
<div className="general-schema-designer-icons">
|
||||
<Space size={3} align="center">
|
||||
{renderToolbarItems(model, showDeleteButton, showCopyUidButton, flowEngine)}
|
||||
{renderToolbarItems(model, showDeleteButton, showCopyUidButton, flowEngine, settingsMenuLevel)}
|
||||
</Space>
|
||||
</div>
|
||||
</div>
|
||||
@ -313,6 +325,7 @@ const FlowsFloatContextMenuWithModelById: React.FC<ModelByIdProps> = observer(
|
||||
showCopyUidButton = true,
|
||||
containerStyle,
|
||||
className,
|
||||
settingsMenuLevel,
|
||||
}) => {
|
||||
const model = useFlowModelById(uid, modelClassName);
|
||||
|
||||
@ -328,6 +341,7 @@ const FlowsFloatContextMenuWithModelById: React.FC<ModelByIdProps> = observer(
|
||||
showCopyUidButton={showCopyUidButton}
|
||||
containerStyle={containerStyle}
|
||||
className={className}
|
||||
settingsMenuLevel={settingsMenuLevel}
|
||||
>
|
||||
{children}
|
||||
</FlowsFloatContextMenuWithModel>
|
||||
|
Loading…
x
Reference in New Issue
Block a user