diff --git a/packages/core/client/src/flow/FlowPage.tsx b/packages/core/client/src/flow/FlowPage.tsx
index 1f1a8a7910..5e46747d3a 100644
--- a/packages/core/client/src/flow/FlowPage.tsx
+++ b/packages/core/client/src/flow/FlowPage.tsx
@@ -15,15 +15,15 @@ import { useParams } from 'react-router-dom';
import { useKeepAlive } from '../route-switch';
import { SkeletonFallback } from './components/SkeletonFallback';
-function InternalFlowPage({ uid, sharedContext }) {
+function InternalFlowPage({ uid, ...props }) {
const model = useFlowModelById(uid);
return (
}
- showFlowSettings={{ showBackground: false, showBorder: false }}
hideRemoveInSettings
+ showFlowSettings={{ showBackground: false, showBorder: false }}
+ {...props}
/>
);
}
@@ -32,6 +32,7 @@ export const FlowRoute = () => {
const layoutContentRef = useRef(null);
const flowEngine = useFlowEngine();
const params = useParams();
+ // console.log('FlowRoute params:', params);
// const { active } = useKeepAlive();
const model = useMemo(() => {
return flowEngine.createModel({
@@ -49,13 +50,13 @@ export const FlowRoute = () => {
model.setSharedContext({
layoutContentElement: layoutContentRef.current,
});
- model.dispatchEvent('click', { target: layoutContentRef.current });
- }, [model, params.name]);
+ model.dispatchEvent('click', { target: layoutContentRef.current, activeTab: params.tabUid });
+ }, [model, params.name, params.tabUid]);
return
;
};
export const FlowPage = (props) => {
- const { parentId, sharedContext } = props;
+ const { parentId, ...rest } = props;
const flowEngine = useFlowEngine();
const { loading, data } = useRequest(
async () => {
@@ -71,6 +72,7 @@ export const FlowPage = (props) => {
use: 'PageTabModel',
subModels: {
grid: {
+ async: true,
use: 'BlockGridModel',
},
},
@@ -88,5 +90,23 @@ export const FlowPage = (props) => {
if (loading || !data?.uid) {
return ;
}
- return ;
+ return ;
+};
+
+export const RemoteFlowModelRenderer = (props) => {
+ const { uid, parentId, ...rest } = props;
+ const flowEngine = useFlowEngine();
+ const { loading, data } = useRequest(
+ async () => {
+ const data = await flowEngine.loadModel({ uid, parentId });
+ return data;
+ },
+ {
+ refreshDeps: [uid, parentId],
+ },
+ );
+ if (loading || !data?.uid) {
+ return ;
+ }
+ return ;
};
diff --git a/packages/core/client/src/flow/models/base/PageModel.tsx b/packages/core/client/src/flow/models/base/PageModel.tsx
index 1f96e390d0..57e480a07a 100644
--- a/packages/core/client/src/flow/models/base/PageModel.tsx
+++ b/packages/core/client/src/flow/models/base/PageModel.tsx
@@ -11,10 +11,10 @@ import { PlusOutlined } from '@ant-design/icons';
import { PageHeader } from '@ant-design/pro-layout';
import { uid } from '@formily/shared';
import { FlowModel, FlowModelRenderer, FlowSettingsButton } from '@nocobase/flow-engine';
+import { tval } from '@nocobase/utils/client';
import { Tabs } from 'antd';
import _ from 'lodash';
import React from 'react';
-import { tval } from '@nocobase/utils/client';
type PageModelStructure = {
subModels: {
@@ -29,7 +29,7 @@ export class PageModel extends FlowModel {
}
getItems() {
- return this.subModels.tabs?.map((tab) => {
+ return this.mapSubModels('tabs', (tab) => {
return {
key: tab.uid,
label: tab.props.label || 'Unnamed',
diff --git a/packages/core/client/src/flow/models/base/PageTabModel.tsx b/packages/core/client/src/flow/models/base/PageTabModel.tsx
index 74663fdbab..95ea066bc0 100644
--- a/packages/core/client/src/flow/models/base/PageTabModel.tsx
+++ b/packages/core/client/src/flow/models/base/PageTabModel.tsx
@@ -9,6 +9,7 @@
import { FlowModel, FlowModelRenderer } from '@nocobase/flow-engine';
import React from 'react';
+import { RemoteFlowModelRenderer } from '../../FlowPage';
import { BlockGridModel } from './GridModel';
export class PageTabModel extends FlowModel<{
@@ -17,10 +18,9 @@ export class PageTabModel extends FlowModel<{
};
}> {
render() {
- console.log('TabFlowModel render', this.uid);
return (
-
+
);
}
diff --git a/packages/core/client/src/flow/models/data-blocks/table/TableColumnModel.tsx b/packages/core/client/src/flow/models/data-blocks/table/TableColumnModel.tsx
index 14e4179ad7..10fc4be813 100644
--- a/packages/core/client/src/flow/models/data-blocks/table/TableColumnModel.tsx
+++ b/packages/core/client/src/flow/models/data-blocks/table/TableColumnModel.tsx
@@ -8,10 +8,11 @@
*/
import { QuestionCircleOutlined } from '@ant-design/icons';
+import { css } from '@emotion/css';
import { FlowsFloatContextMenu } from '@nocobase/flow-engine';
+import { tval } from '@nocobase/utils/client';
import { TableColumnProps, Tooltip } from 'antd';
import React from 'react';
-import { tval } from '@nocobase/utils/client';
import { FieldModel } from '../../base/FieldModel';
import { ReadPrettyFieldModel } from '../../fields/ReadPrettyField/ReadPrettyFieldModel';
@@ -24,9 +25,19 @@ export class TableColumnModel extends FieldModel {
showBorder={false}
settingsMenuLevel={2}
>
- {this.props.title}
+
+ {this.props.title}
+
);
+ console.log('TableColumnModel props:', this.props);
return {
...this.props,
ellipsis: true,
@@ -43,7 +54,7 @@ export class TableColumnModel extends FieldModel {
onCell: (record) => ({
record,
width: this.props.width,
- editable: this.props.editable || false,
+ editable: this.props.editable,
dataIndex: this.props.dataIndex,
title: this.props.title,
// handleSave,
@@ -120,6 +131,7 @@ TableColumnModel.registerFlow({
};
},
handler(ctx, params) {
+ console.log('editColumTitle params:', params);
const title = ctx.globals.flowEngine.translate(params.title || ctx.model.collectionField?.title);
ctx.model.setProps('title', title);
},
@@ -162,8 +174,10 @@ TableColumnModel.registerFlow({
'x-decorator': 'FormItem',
},
},
- defaultParams: {
- editable: false,
+ defaultParams(ctx) {
+ return {
+ editable: ctx.model.parent.props.editable || false,
+ };
},
handler(ctx, params) {
ctx.model.setProps('editable', params.editable);
diff --git a/packages/core/client/src/flow/models/data-blocks/table/TableModel.tsx b/packages/core/client/src/flow/models/data-blocks/table/TableModel.tsx
index 63c0c9893d..dd4b81577f 100644
--- a/packages/core/client/src/flow/models/data-blocks/table/TableModel.tsx
+++ b/packages/core/client/src/flow/models/data-blocks/table/TableModel.tsx
@@ -109,7 +109,6 @@ export class TableModel extends DataBlockModel {
},
]}
onModelCreated={async (model: TableColumnModel) => {
- // model.setSharedContext({ currentBlockModel: this });
await model.applyAutoFlows();
}}
onSubModelAdded={async (model: TableColumnModel) => {
@@ -222,7 +221,6 @@ export class TableModel extends DataBlockModel {
);
}
@@ -240,7 +238,6 @@ export class TableModel extends DataBlockModel {
);
}
@@ -287,6 +284,22 @@ TableModel.registerFlow({
key: 'default',
auto: true,
steps: {
+ enableEditable: {
+ title: tval('Editable'),
+ uiSchema: {
+ editable: {
+ 'x-component': 'Switch',
+ 'x-decorator': 'FormItem',
+ },
+ },
+ defaultParams: {
+ editable: false,
+ },
+ handler(ctx, params) {
+ console.log('enableEditable params:', params);
+ ctx.model.setProps('editable', params.editable);
+ },
+ },
step1: {
paramsRequired: true,
hideInSettings: true,
diff --git a/packages/core/flow-engine/src/flowEngine.ts b/packages/core/flow-engine/src/flowEngine.ts
index 25993af49e..cafccdd070 100644
--- a/packages/core/flow-engine/src/flowEngine.ts
+++ b/packages/core/flow-engine/src/flowEngine.ts
@@ -8,6 +8,7 @@
*/
import { observable } from '@formily/reactive';
import { FlowSettings } from './flowSettings';
+import { initFlowEngineLocale } from './locale';
import { FlowModel } from './models';
import { ReactView } from './ReactView';
import {
@@ -20,7 +21,6 @@ import {
ModelConstructor,
} from './types';
import { isInheritedFrom } from './utils';
-import { initFlowEngineLocale } from './locale';
interface ApplyFlowCacheEntry {
status: 'pending' | 'resolved' | 'rejected';
@@ -42,14 +42,26 @@ export class FlowEngine {
private modelRepository: IFlowModelRepository | null = null;
private _applyFlowCache = new Map();
- reactView: ReactView;
+ /**
+ * 实验性 API:用于在 FlowEngine 中集成 React 视图渲染能力。
+ * 该属性未来可能发生重大变更或被移除,请谨慎依赖。
+ * @experimental
+ */
+ public reactView: ReactView;
constructor() {
this.reactView = new ReactView(this);
this.flowSettings.registerScopes({ t: this.translate.bind(this) });
}
- // 注册默认的 FlowModel
+ /**
+ * 设置模型仓库,用于持久化和查询模型实例。
+ * 如果之前已设置过模型仓库,将会覆盖原有设置,并输出警告。
+ *
+ * @param modelRepository 要设置的模型仓库实例,实现 IFlowModelRepository 接口。
+ * @example
+ * flowEngine.setModelRepository(new MyFlowModelRepository());
+ */
setModelRepository(modelRepository: IFlowModelRepository) {
if (this.modelRepository) {
console.warn('FlowEngine: Model repository is already set and will be overwritten.');
@@ -375,9 +387,9 @@ export class FlowEngine {
return true;
}
- async loadModel(uid: string): Promise {
+ async loadModel(options): Promise {
if (!this.ensureModelRepository()) return;
- const data = await this.modelRepository.findOne({ uid });
+ const data = await this.modelRepository.findOne(options);
return data?.uid ? this.createModel(data as any) : null;
}
diff --git a/packages/core/flow-engine/src/models/flowModel.tsx b/packages/core/flow-engine/src/models/flowModel.tsx
index 94d8868b47..48587e9f2e 100644
--- a/packages/core/flow-engine/src/models/flowModel.tsx
+++ b/packages/core/flow-engine/src/models/flowModel.tsx
@@ -901,7 +901,7 @@ export class FlowModel