mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-07-01 18:52:20 +08:00
fix: improve code
This commit is contained in:
parent
49bcc1a38f
commit
a521faee7b
@ -15,15 +15,15 @@ import { useParams } from 'react-router-dom';
|
|||||||
import { useKeepAlive } from '../route-switch';
|
import { useKeepAlive } from '../route-switch';
|
||||||
import { SkeletonFallback } from './components/SkeletonFallback';
|
import { SkeletonFallback } from './components/SkeletonFallback';
|
||||||
|
|
||||||
function InternalFlowPage({ uid, sharedContext }) {
|
function InternalFlowPage({ uid, ...props }) {
|
||||||
const model = useFlowModelById(uid);
|
const model = useFlowModelById(uid);
|
||||||
return (
|
return (
|
||||||
<FlowModelRenderer
|
<FlowModelRenderer
|
||||||
model={model}
|
model={model}
|
||||||
sharedContext={sharedContext}
|
|
||||||
fallback={<SkeletonFallback />}
|
fallback={<SkeletonFallback />}
|
||||||
showFlowSettings={{ showBackground: false, showBorder: false }}
|
|
||||||
hideRemoveInSettings
|
hideRemoveInSettings
|
||||||
|
showFlowSettings={{ showBackground: false, showBorder: false }}
|
||||||
|
{...props}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -32,6 +32,7 @@ export const FlowRoute = () => {
|
|||||||
const layoutContentRef = useRef(null);
|
const layoutContentRef = useRef(null);
|
||||||
const flowEngine = useFlowEngine();
|
const flowEngine = useFlowEngine();
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
|
// console.log('FlowRoute params:', params);
|
||||||
// const { active } = useKeepAlive();
|
// const { active } = useKeepAlive();
|
||||||
const model = useMemo(() => {
|
const model = useMemo(() => {
|
||||||
return flowEngine.createModel({
|
return flowEngine.createModel({
|
||||||
@ -49,13 +50,13 @@ export const FlowRoute = () => {
|
|||||||
model.setSharedContext({
|
model.setSharedContext({
|
||||||
layoutContentElement: layoutContentRef.current,
|
layoutContentElement: layoutContentRef.current,
|
||||||
});
|
});
|
||||||
model.dispatchEvent('click', { target: layoutContentRef.current });
|
model.dispatchEvent('click', { target: layoutContentRef.current, activeTab: params.tabUid });
|
||||||
}, [model, params.name]);
|
}, [model, params.name, params.tabUid]);
|
||||||
return <div ref={layoutContentRef} />;
|
return <div ref={layoutContentRef} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const FlowPage = (props) => {
|
export const FlowPage = (props) => {
|
||||||
const { parentId, sharedContext } = props;
|
const { parentId, ...rest } = props;
|
||||||
const flowEngine = useFlowEngine();
|
const flowEngine = useFlowEngine();
|
||||||
const { loading, data } = useRequest(
|
const { loading, data } = useRequest(
|
||||||
async () => {
|
async () => {
|
||||||
@ -71,6 +72,7 @@ export const FlowPage = (props) => {
|
|||||||
use: 'PageTabModel',
|
use: 'PageTabModel',
|
||||||
subModels: {
|
subModels: {
|
||||||
grid: {
|
grid: {
|
||||||
|
async: true,
|
||||||
use: 'BlockGridModel',
|
use: 'BlockGridModel',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -88,5 +90,23 @@ export const FlowPage = (props) => {
|
|||||||
if (loading || !data?.uid) {
|
if (loading || !data?.uid) {
|
||||||
return <SkeletonFallback />;
|
return <SkeletonFallback />;
|
||||||
}
|
}
|
||||||
return <InternalFlowPage uid={data.uid} sharedContext={sharedContext} />;
|
return <InternalFlowPage uid={data.uid} {...rest} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
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 <SkeletonFallback />;
|
||||||
|
}
|
||||||
|
return <InternalFlowPage uid={data.uid} {...rest} />;
|
||||||
};
|
};
|
||||||
|
@ -11,10 +11,10 @@ import { PlusOutlined } from '@ant-design/icons';
|
|||||||
import { PageHeader } from '@ant-design/pro-layout';
|
import { PageHeader } from '@ant-design/pro-layout';
|
||||||
import { uid } from '@formily/shared';
|
import { uid } from '@formily/shared';
|
||||||
import { FlowModel, FlowModelRenderer, FlowSettingsButton } from '@nocobase/flow-engine';
|
import { FlowModel, FlowModelRenderer, FlowSettingsButton } from '@nocobase/flow-engine';
|
||||||
|
import { tval } from '@nocobase/utils/client';
|
||||||
import { Tabs } from 'antd';
|
import { Tabs } from 'antd';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { tval } from '@nocobase/utils/client';
|
|
||||||
|
|
||||||
type PageModelStructure = {
|
type PageModelStructure = {
|
||||||
subModels: {
|
subModels: {
|
||||||
@ -29,7 +29,7 @@ export class PageModel extends FlowModel<PageModelStructure> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getItems() {
|
getItems() {
|
||||||
return this.subModels.tabs?.map((tab) => {
|
return this.mapSubModels('tabs', (tab) => {
|
||||||
return {
|
return {
|
||||||
key: tab.uid,
|
key: tab.uid,
|
||||||
label: tab.props.label || 'Unnamed',
|
label: tab.props.label || 'Unnamed',
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
import { FlowModel, FlowModelRenderer } from '@nocobase/flow-engine';
|
import { FlowModel, FlowModelRenderer } from '@nocobase/flow-engine';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { RemoteFlowModelRenderer } from '../../FlowPage';
|
||||||
import { BlockGridModel } from './GridModel';
|
import { BlockGridModel } from './GridModel';
|
||||||
|
|
||||||
export class PageTabModel extends FlowModel<{
|
export class PageTabModel extends FlowModel<{
|
||||||
@ -17,10 +18,9 @@ export class PageTabModel extends FlowModel<{
|
|||||||
};
|
};
|
||||||
}> {
|
}> {
|
||||||
render() {
|
render() {
|
||||||
console.log('TabFlowModel render', this.uid);
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<FlowModelRenderer model={this.subModels.grid} />
|
<RemoteFlowModelRenderer parentId={this.uid} showFlowSettings={false} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -8,10 +8,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { QuestionCircleOutlined } from '@ant-design/icons';
|
import { QuestionCircleOutlined } from '@ant-design/icons';
|
||||||
|
import { css } from '@emotion/css';
|
||||||
import { FlowsFloatContextMenu } from '@nocobase/flow-engine';
|
import { FlowsFloatContextMenu } from '@nocobase/flow-engine';
|
||||||
|
import { tval } from '@nocobase/utils/client';
|
||||||
import { TableColumnProps, Tooltip } from 'antd';
|
import { TableColumnProps, Tooltip } from 'antd';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { tval } from '@nocobase/utils/client';
|
|
||||||
import { FieldModel } from '../../base/FieldModel';
|
import { FieldModel } from '../../base/FieldModel';
|
||||||
import { ReadPrettyFieldModel } from '../../fields/ReadPrettyField/ReadPrettyFieldModel';
|
import { ReadPrettyFieldModel } from '../../fields/ReadPrettyField/ReadPrettyFieldModel';
|
||||||
|
|
||||||
@ -24,9 +25,19 @@ export class TableColumnModel extends FieldModel {
|
|||||||
showBorder={false}
|
showBorder={false}
|
||||||
settingsMenuLevel={2}
|
settingsMenuLevel={2}
|
||||||
>
|
>
|
||||||
{this.props.title}
|
<div
|
||||||
|
className={css`
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
width: calc(${this.props.width}px - 16px);
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
{this.props.title}
|
||||||
|
</div>
|
||||||
</FlowsFloatContextMenu>
|
</FlowsFloatContextMenu>
|
||||||
);
|
);
|
||||||
|
console.log('TableColumnModel props:', this.props);
|
||||||
return {
|
return {
|
||||||
...this.props,
|
...this.props,
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
@ -43,7 +54,7 @@ export class TableColumnModel extends FieldModel {
|
|||||||
onCell: (record) => ({
|
onCell: (record) => ({
|
||||||
record,
|
record,
|
||||||
width: this.props.width,
|
width: this.props.width,
|
||||||
editable: this.props.editable || false,
|
editable: this.props.editable,
|
||||||
dataIndex: this.props.dataIndex,
|
dataIndex: this.props.dataIndex,
|
||||||
title: this.props.title,
|
title: this.props.title,
|
||||||
// handleSave,
|
// handleSave,
|
||||||
@ -120,6 +131,7 @@ TableColumnModel.registerFlow({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
handler(ctx, params) {
|
handler(ctx, params) {
|
||||||
|
console.log('editColumTitle params:', params);
|
||||||
const title = ctx.globals.flowEngine.translate(params.title || ctx.model.collectionField?.title);
|
const title = ctx.globals.flowEngine.translate(params.title || ctx.model.collectionField?.title);
|
||||||
ctx.model.setProps('title', title);
|
ctx.model.setProps('title', title);
|
||||||
},
|
},
|
||||||
@ -162,8 +174,10 @@ TableColumnModel.registerFlow({
|
|||||||
'x-decorator': 'FormItem',
|
'x-decorator': 'FormItem',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
defaultParams: {
|
defaultParams(ctx) {
|
||||||
editable: false,
|
return {
|
||||||
|
editable: ctx.model.parent.props.editable || false,
|
||||||
|
};
|
||||||
},
|
},
|
||||||
handler(ctx, params) {
|
handler(ctx, params) {
|
||||||
ctx.model.setProps('editable', params.editable);
|
ctx.model.setProps('editable', params.editable);
|
||||||
|
@ -109,7 +109,6 @@ export class TableModel extends DataBlockModel<TableModelStructure> {
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
onModelCreated={async (model: TableColumnModel) => {
|
onModelCreated={async (model: TableColumnModel) => {
|
||||||
// model.setSharedContext({ currentBlockModel: this });
|
|
||||||
await model.applyAutoFlows();
|
await model.applyAutoFlows();
|
||||||
}}
|
}}
|
||||||
onSubModelAdded={async (model: TableColumnModel) => {
|
onSubModelAdded={async (model: TableColumnModel) => {
|
||||||
@ -222,7 +221,6 @@ export class TableModel extends DataBlockModel<TableModelStructure> {
|
|||||||
<FlowModelRenderer
|
<FlowModelRenderer
|
||||||
model={action}
|
model={action}
|
||||||
showFlowSettings={{ showBackground: false, showBorder: false }}
|
showFlowSettings={{ showBackground: false, showBorder: false }}
|
||||||
sharedContext={{ currentBlockModel: this }}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -240,7 +238,6 @@ export class TableModel extends DataBlockModel<TableModelStructure> {
|
|||||||
<FlowModelRenderer
|
<FlowModelRenderer
|
||||||
model={action}
|
model={action}
|
||||||
showFlowSettings={{ showBackground: false, showBorder: false }}
|
showFlowSettings={{ showBackground: false, showBorder: false }}
|
||||||
sharedContext={{ currentBlockModel: this }}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -287,6 +284,22 @@ TableModel.registerFlow({
|
|||||||
key: 'default',
|
key: 'default',
|
||||||
auto: true,
|
auto: true,
|
||||||
steps: {
|
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: {
|
step1: {
|
||||||
paramsRequired: true,
|
paramsRequired: true,
|
||||||
hideInSettings: true,
|
hideInSettings: true,
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
import { observable } from '@formily/reactive';
|
import { observable } from '@formily/reactive';
|
||||||
import { FlowSettings } from './flowSettings';
|
import { FlowSettings } from './flowSettings';
|
||||||
|
import { initFlowEngineLocale } from './locale';
|
||||||
import { FlowModel } from './models';
|
import { FlowModel } from './models';
|
||||||
import { ReactView } from './ReactView';
|
import { ReactView } from './ReactView';
|
||||||
import {
|
import {
|
||||||
@ -20,7 +21,6 @@ import {
|
|||||||
ModelConstructor,
|
ModelConstructor,
|
||||||
} from './types';
|
} from './types';
|
||||||
import { isInheritedFrom } from './utils';
|
import { isInheritedFrom } from './utils';
|
||||||
import { initFlowEngineLocale } from './locale';
|
|
||||||
|
|
||||||
interface ApplyFlowCacheEntry {
|
interface ApplyFlowCacheEntry {
|
||||||
status: 'pending' | 'resolved' | 'rejected';
|
status: 'pending' | 'resolved' | 'rejected';
|
||||||
@ -42,14 +42,26 @@ export class FlowEngine {
|
|||||||
private modelRepository: IFlowModelRepository | null = null;
|
private modelRepository: IFlowModelRepository | null = null;
|
||||||
private _applyFlowCache = new Map<string, ApplyFlowCacheEntry>();
|
private _applyFlowCache = new Map<string, ApplyFlowCacheEntry>();
|
||||||
|
|
||||||
reactView: ReactView;
|
/**
|
||||||
|
* 实验性 API:用于在 FlowEngine 中集成 React 视图渲染能力。
|
||||||
|
* 该属性未来可能发生重大变更或被移除,请谨慎依赖。
|
||||||
|
* @experimental
|
||||||
|
*/
|
||||||
|
public reactView: ReactView;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.reactView = new ReactView(this);
|
this.reactView = new ReactView(this);
|
||||||
this.flowSettings.registerScopes({ t: this.translate.bind(this) });
|
this.flowSettings.registerScopes({ t: this.translate.bind(this) });
|
||||||
}
|
}
|
||||||
// 注册默认的 FlowModel
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置模型仓库,用于持久化和查询模型实例。
|
||||||
|
* 如果之前已设置过模型仓库,将会覆盖原有设置,并输出警告。
|
||||||
|
*
|
||||||
|
* @param modelRepository 要设置的模型仓库实例,实现 IFlowModelRepository 接口。
|
||||||
|
* @example
|
||||||
|
* flowEngine.setModelRepository(new MyFlowModelRepository());
|
||||||
|
*/
|
||||||
setModelRepository(modelRepository: IFlowModelRepository) {
|
setModelRepository(modelRepository: IFlowModelRepository) {
|
||||||
if (this.modelRepository) {
|
if (this.modelRepository) {
|
||||||
console.warn('FlowEngine: Model repository is already set and will be overwritten.');
|
console.warn('FlowEngine: Model repository is already set and will be overwritten.');
|
||||||
@ -375,9 +387,9 @@ export class FlowEngine {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadModel<T extends FlowModel = FlowModel>(uid: string): Promise<T | null> {
|
async loadModel<T extends FlowModel = FlowModel>(options): Promise<T | null> {
|
||||||
if (!this.ensureModelRepository()) return;
|
if (!this.ensureModelRepository()) return;
|
||||||
const data = await this.modelRepository.findOne({ uid });
|
const data = await this.modelRepository.findOne(options);
|
||||||
return data?.uid ? this.createModel<T>(data as any) : null;
|
return data?.uid ? this.createModel<T>(data as any) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -901,7 +901,7 @@ export class FlowModel<Structure extends { parent?: any; subModels?: any } = Def
|
|||||||
const data = {
|
const data = {
|
||||||
uid: this.uid,
|
uid: this.uid,
|
||||||
..._.omit(this._options, ['flowEngine']),
|
..._.omit(this._options, ['flowEngine']),
|
||||||
props: this.props,
|
// props: this.props,
|
||||||
stepParams: this.stepParams,
|
stepParams: this.stepParams,
|
||||||
sortIndex: this.sortIndex,
|
sortIndex: this.sortIndex,
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user