mirror of
https://gitee.com/ByteDance/flowgram.ai.git
synced 2025-07-07 17:43:29 +08:00
fix: demo lint
This commit is contained in:
parent
e01601b733
commit
b362b85141
@ -7,4 +7,9 @@ module.exports = defineConfig({
|
|||||||
'no-console': 'off',
|
'no-console': 'off',
|
||||||
'react/prop-types': 'off',
|
'react/prop-types': 'off',
|
||||||
},
|
},
|
||||||
|
settings: {
|
||||||
|
react: {
|
||||||
|
version: 'detect', // 自动检测 React 版本
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { FlowMinimapService, MinimapRender } from '@flowgram.ai/minimap-plugin';
|
import { FlowMinimapService, MinimapRender } from '@flowgram.ai/minimap-plugin';
|
||||||
import { useService } from '@flowgram.ai/fixed-layout-editor';
|
import { useService } from '@flowgram.ai/fixed-layout-editor';
|
||||||
|
|
||||||
|
|
||||||
export const Minimap = () => {
|
export const Minimap = () => {
|
||||||
const minimapService = useService(FlowMinimapService);
|
const minimapService = useService(FlowMinimapService);
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
import { usePlaygroundTools, useClientContext } from '@flowgram.ai/fixed-layout-editor';
|
import { usePlaygroundTools, useClientContext } from '@flowgram.ai/fixed-layout-editor';
|
||||||
|
|
||||||
export function Tools() {
|
export function Tools() {
|
||||||
@ -15,13 +16,21 @@ export function Tools() {
|
|||||||
return () => disposable.dispose();
|
return () => disposable.dispose();
|
||||||
}, [history]);
|
}, [history]);
|
||||||
|
|
||||||
return <div style={{ position: 'absolute', zIndex: 10, bottom: 16, left: 16, display: 'flex', gap: 8 }}>
|
return (
|
||||||
|
<div
|
||||||
|
style={{ position: 'absolute', zIndex: 10, bottom: 16, left: 16, display: 'flex', gap: 8 }}
|
||||||
|
>
|
||||||
<button onClick={() => tools.zoomin()}>ZoomIn</button>
|
<button onClick={() => tools.zoomin()}>ZoomIn</button>
|
||||||
<button onClick={() => tools.zoomout()}>ZoomOut</button>
|
<button onClick={() => tools.zoomout()}>ZoomOut</button>
|
||||||
<button onClick={() => tools.fitView()}>Fitview</button>
|
<button onClick={() => tools.fitView()}>Fitview</button>
|
||||||
<button onClick={() => tools.changeLayout()}>ChangeLayout</button>
|
<button onClick={() => tools.changeLayout()}>ChangeLayout</button>
|
||||||
<button onClick={() => history.undo()} disabled={!canUndo}>Undo</button>
|
<button onClick={() => history.undo()} disabled={!canUndo}>
|
||||||
<button onClick={() => history.redo()} disabled={!canRedo}>Redo</button>
|
Undo
|
||||||
|
</button>
|
||||||
|
<button onClick={() => history.redo()} disabled={!canRedo}>
|
||||||
|
Redo
|
||||||
|
</button>
|
||||||
<span>{Math.floor(tools.zoom * 100)}%</span>
|
<span>{Math.floor(tools.zoom * 100)}%</span>
|
||||||
</div>
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
import { FixedLayoutEditorProvider, EditorRenderer } from '@flowgram.ai/fixed-layout-editor';
|
import { FixedLayoutEditorProvider, EditorRenderer } from '@flowgram.ai/fixed-layout-editor';
|
||||||
|
|
||||||
import '@flowgram.ai/fixed-layout-editor/index.css';
|
import '@flowgram.ai/fixed-layout-editor/index.css';
|
||||||
import './index.css'
|
import './index.css';
|
||||||
|
|
||||||
|
import { nodeRegistries } from './node-registries';
|
||||||
|
import { initialData } from './initial-data';
|
||||||
import { useEditorProps } from './hooks/use-editor-props';
|
import { useEditorProps } from './hooks/use-editor-props';
|
||||||
import { initialData } from './initial-data'
|
import { Tools } from './components/tools';
|
||||||
import { nodeRegistries } from './node-registries'
|
import { Minimap } from './components/minimap';
|
||||||
import { Tools } from './components/tools'
|
|
||||||
import { Minimap } from './components/minimap'
|
|
||||||
|
|
||||||
export const Editor = () => {
|
export const Editor = () => {
|
||||||
const editorProps = useEditorProps(initialData, nodeRegistries);
|
const editorProps = useEditorProps(initialData, nodeRegistries);
|
||||||
|
|||||||
@ -11,7 +11,7 @@ export const initialData: FlowDocumentJSON = {
|
|||||||
type: 'start',
|
type: 'start',
|
||||||
data: {
|
data: {
|
||||||
title: 'Start',
|
title: 'Start',
|
||||||
content: 'start content'
|
content: 'start content',
|
||||||
},
|
},
|
||||||
blocks: [],
|
blocks: [],
|
||||||
},
|
},
|
||||||
@ -20,7 +20,7 @@ export const initialData: FlowDocumentJSON = {
|
|||||||
id: 'condition_0',
|
id: 'condition_0',
|
||||||
type: 'condition',
|
type: 'condition',
|
||||||
data: {
|
data: {
|
||||||
title: 'Condition'
|
title: 'Condition',
|
||||||
},
|
},
|
||||||
blocks: [
|
blocks: [
|
||||||
{
|
{
|
||||||
@ -28,7 +28,7 @@ export const initialData: FlowDocumentJSON = {
|
|||||||
type: 'block',
|
type: 'block',
|
||||||
data: {
|
data: {
|
||||||
title: 'Branch 0',
|
title: 'Branch 0',
|
||||||
content: 'branch 1 content'
|
content: 'branch 1 content',
|
||||||
},
|
},
|
||||||
blocks: [
|
blocks: [
|
||||||
{
|
{
|
||||||
@ -36,7 +36,7 @@ export const initialData: FlowDocumentJSON = {
|
|||||||
type: 'custom',
|
type: 'custom',
|
||||||
data: {
|
data: {
|
||||||
title: 'Custom',
|
title: 'Custom',
|
||||||
content: 'custrom content'
|
content: 'custrom content',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -46,7 +46,7 @@ export const initialData: FlowDocumentJSON = {
|
|||||||
type: 'block',
|
type: 'block',
|
||||||
data: {
|
data: {
|
||||||
title: 'Branch 1',
|
title: 'Branch 1',
|
||||||
content: 'branch 1 content'
|
content: 'branch 1 content',
|
||||||
},
|
},
|
||||||
blocks: [],
|
blocks: [],
|
||||||
},
|
},
|
||||||
@ -58,9 +58,8 @@ export const initialData: FlowDocumentJSON = {
|
|||||||
type: 'end',
|
type: 'end',
|
||||||
data: {
|
data: {
|
||||||
title: 'End',
|
title: 'End',
|
||||||
content: 'end content'
|
content: 'end content',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { FlowNodeRegistry } from '@flowgram.ai/fixed-layout-editor';
|
|
||||||
import { nanoid } from 'nanoid';
|
import { nanoid } from 'nanoid';
|
||||||
|
import { FlowNodeRegistry } from '@flowgram.ai/fixed-layout-editor';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自定义节点注册
|
* 自定义节点注册
|
||||||
@ -67,9 +67,9 @@ export const nodeRegistries: FlowNodeRegistry[] = [
|
|||||||
type: 'custom',
|
type: 'custom',
|
||||||
data: {
|
data: {
|
||||||
title: 'Custom',
|
title: 'Custom',
|
||||||
content: 'this is custom content'
|
content: 'this is custom content',
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@ -7,4 +7,9 @@ module.exports = defineConfig({
|
|||||||
'no-console': 'off',
|
'no-console': 'off',
|
||||||
'react/prop-types': 'off',
|
'react/prop-types': 'off',
|
||||||
},
|
},
|
||||||
|
settings: {
|
||||||
|
react: {
|
||||||
|
version: 'detect', // 自动检测 React 版本
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import styled from 'styled-components';
|
|||||||
export const Container = styled.div<{ activated?: boolean; isVertical: boolean }>`
|
export const Container = styled.div<{ activated?: boolean; isVertical: boolean }>`
|
||||||
width: 28px;
|
width: 28px;
|
||||||
height: 18px;
|
height: 18px;
|
||||||
background: ${props => (props.activated ? '#82A7FC' : 'rgb(187, 191, 196)')};
|
background: ${(props) => (props.activated ? '#82A7FC' : 'rgb(187, 191, 196)')};
|
||||||
display: flex;
|
display: flex;
|
||||||
border-radius: 9px;
|
border-radius: 9px;
|
||||||
justify-content: space-evenly;
|
justify-content: space-evenly;
|
||||||
@ -11,7 +11,7 @@ export const Container = styled.div<{ activated?: boolean; isVertical: boolean }
|
|||||||
color: #fff;
|
color: #fff;
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
transform: ${props => (props.isVertical ? '' : 'rotate(90deg)')};
|
transform: ${(props) => (props.isVertical ? '' : 'rotate(90deg)')};
|
||||||
div {
|
div {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|||||||
@ -12,14 +12,14 @@ export interface PropsType {
|
|||||||
export function DragNode(props: PropsType): JSX.Element {
|
export function DragNode(props: PropsType): JSX.Element {
|
||||||
const { dragStart, dragNodes } = props;
|
const { dragStart, dragNodes } = props;
|
||||||
|
|
||||||
const icon = FlowNodeRegistries.find(registry => registry.type === dragStart?.flowNodeType)?.info
|
const icon = FlowNodeRegistries.find((registry) => registry.type === dragStart?.flowNodeType)
|
||||||
?.icon;
|
?.info?.icon;
|
||||||
|
|
||||||
const dragLength = (dragNodes || [])
|
const dragLength = (dragNodes || [])
|
||||||
.map(_node =>
|
.map((_node) =>
|
||||||
_node.allCollapsedChildren.length
|
_node.allCollapsedChildren.length
|
||||||
? _node.allCollapsedChildren.filter(_n => !_n.hidden).length
|
? _node.allCollapsedChildren.filter((_n) => !_n.hidden).length
|
||||||
: 1,
|
: 1
|
||||||
)
|
)
|
||||||
.reduce((acm, curr) => acm + curr, 0);
|
.reduce((acm, curr) => acm + curr, 0);
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,7 @@ const generateNewIdForChildren = (n: FlowNodeEntity): FlowNodeEntity => {
|
|||||||
return {
|
return {
|
||||||
...n,
|
...n,
|
||||||
id: generateNodeId(n),
|
id: generateNodeId(n),
|
||||||
blocks: n.blocks.map(b => generateNewIdForChildren(b)),
|
blocks: n.blocks.map((b) => generateNewIdForChildren(b)),
|
||||||
} as FlowNodeEntity;
|
} as FlowNodeEntity;
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
@ -39,7 +39,7 @@ export default function Adder(props: {
|
|||||||
|
|
||||||
const activated = useMemo(
|
const activated = useMemo(
|
||||||
() => props.hoverActivated && !playground.config.readonly,
|
() => props.hoverActivated && !playground.config.readonly,
|
||||||
[props.hoverActivated, playground.config.readonly],
|
[props.hoverActivated, playground.config.readonly]
|
||||||
);
|
);
|
||||||
|
|
||||||
const add = (addProps: any) => {
|
const add = (addProps: any) => {
|
||||||
@ -111,7 +111,7 @@ export default function Adder(props: {
|
|||||||
}
|
}
|
||||||
: {}
|
: {}
|
||||||
}
|
}
|
||||||
onMouseDown={e => e.stopPropagation()}
|
onMouseDown={(e) => e.stopPropagation()}
|
||||||
>
|
>
|
||||||
{props.hoverActivated ? (
|
{props.hoverActivated ? (
|
||||||
<IconPlusCircle
|
<IconPlusCircle
|
||||||
|
|||||||
@ -55,7 +55,7 @@ export function NodeList(props: { onSelect: (meta: any) => void; from: FlowNodeE
|
|||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<NodesWrap style={{ width: 80 * 2 + 20 }}>
|
<NodesWrap style={{ width: 80 * 2 + 20 }}>
|
||||||
{FlowNodeRegistries.map(registry => (
|
{FlowNodeRegistries.map((registry) => (
|
||||||
<Node
|
<Node
|
||||||
key={registry.type}
|
key={registry.type}
|
||||||
disabled={!(registry.canAdd?.(context, props.from) ?? true)}
|
disabled={!(registry.canAdd?.(context, props.from) ?? true)}
|
||||||
|
|||||||
@ -40,7 +40,7 @@ export const SelectorBoxPopover: FunctionComponent<SelectorBoxPopoverProps> = ({
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const findGroupInNodes = (nodes: FlowNodeEntity[]): boolean =>
|
const findGroupInNodes = (nodes: FlowNodeEntity[]): boolean =>
|
||||||
nodes.some(node => {
|
nodes.some((node) => {
|
||||||
if (node.flowNodeType === FlowNodeBaseType.GROUP) {
|
if (node.flowNodeType === FlowNodeBaseType.GROUP) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -63,7 +63,7 @@ export const SelectorBoxPopover: FunctionComponent<SelectorBoxPopoverProps> = ({
|
|||||||
top: bounds.top,
|
top: bounds.top,
|
||||||
transform: 'translate(-100%, -100%)',
|
transform: 'translate(-100%, -100%)',
|
||||||
}}
|
}}
|
||||||
onMouseDown={e => {
|
onMouseDown={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@ -78,7 +78,7 @@ export const SelectorBoxPopover: FunctionComponent<SelectorBoxPopoverProps> = ({
|
|||||||
icon={<IconHandle />}
|
icon={<IconHandle />}
|
||||||
type="primary"
|
type="primary"
|
||||||
theme="solid"
|
theme="solid"
|
||||||
onMouseDown={e => {
|
onMouseDown={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
startDrag(e, {
|
startDrag(e, {
|
||||||
dragStartEntity: selectNodes[0],
|
dragStartEntity: selectNodes[0],
|
||||||
@ -95,7 +95,7 @@ export const SelectorBoxPopover: FunctionComponent<SelectorBoxPopoverProps> = ({
|
|||||||
style={{ height: BUTTON_HEIGHT }}
|
style={{ height: BUTTON_HEIGHT }}
|
||||||
type="primary"
|
type="primary"
|
||||||
theme="solid"
|
theme="solid"
|
||||||
onMouseDown={e => {
|
onMouseDown={(e) => {
|
||||||
commandRegistry.executeCommand(FlowCommandId.COLLAPSE);
|
commandRegistry.executeCommand(FlowCommandId.COLLAPSE);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@ -107,7 +107,7 @@ export const SelectorBoxPopover: FunctionComponent<SelectorBoxPopoverProps> = ({
|
|||||||
style={{ height: BUTTON_HEIGHT }}
|
style={{ height: BUTTON_HEIGHT }}
|
||||||
type="primary"
|
type="primary"
|
||||||
theme="solid"
|
theme="solid"
|
||||||
onMouseDown={e => {
|
onMouseDown={(e) => {
|
||||||
commandRegistry.executeCommand(FlowCommandId.EXPAND);
|
commandRegistry.executeCommand(FlowCommandId.EXPAND);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@ -155,7 +155,7 @@ export const SelectorBoxPopover: FunctionComponent<SelectorBoxPopoverProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
style={{ cursor: draggable ? 'grab' : 'auto' }}
|
style={{ cursor: draggable ? 'grab' : 'auto' }}
|
||||||
onMouseDown={e => {
|
onMouseDown={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
startDrag(e, {
|
startDrag(e, {
|
||||||
dragStartEntity: selectNodes[0],
|
dragStartEntity: selectNodes[0],
|
||||||
|
|||||||
@ -1,10 +1,6 @@
|
|||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
|
|
||||||
import {
|
import { usePlayground, usePlaygroundTools, useRefresh } from '@flowgram.ai/fixed-layout-editor';
|
||||||
usePlayground,
|
|
||||||
usePlaygroundTools,
|
|
||||||
useRefresh,
|
|
||||||
} from '@flowgram.ai/fixed-layout-editor';
|
|
||||||
import { Tooltip, IconButton } from '@douyinfe/semi-ui';
|
import { Tooltip, IconButton } from '@douyinfe/semi-ui';
|
||||||
import { IconUndo, IconRedo } from '@douyinfe/semi-icons';
|
import { IconUndo, IconRedo } from '@douyinfe/semi-icons';
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,6 @@
|
|||||||
import { useState, useEffect, useCallback } from 'react';
|
import { useState, useEffect, useCallback } from 'react';
|
||||||
|
|
||||||
import {
|
import { useClientContext, getNodeForm, FlowNodeEntity } from '@flowgram.ai/fixed-layout-editor';
|
||||||
useClientContext,
|
|
||||||
getNodeForm,
|
|
||||||
FlowNodeEntity,
|
|
||||||
} from '@flowgram.ai/fixed-layout-editor';
|
|
||||||
import { Button, Badge } from '@douyinfe/semi-ui';
|
import { Button, Badge } from '@douyinfe/semi-ui';
|
||||||
|
|
||||||
export function Save(props: { disabled: boolean }) {
|
export function Save(props: { disabled: boolean }) {
|
||||||
@ -12,8 +8,8 @@ export function Save(props: { disabled: boolean }) {
|
|||||||
const clientContext = useClientContext();
|
const clientContext = useClientContext();
|
||||||
|
|
||||||
const updateValidateData = useCallback(() => {
|
const updateValidateData = useCallback(() => {
|
||||||
const allForms = clientContext.document.getAllNodes().map(node => getNodeForm(node));
|
const allForms = clientContext.document.getAllNodes().map((node) => getNodeForm(node));
|
||||||
const count = allForms.filter(form => form?.state.invalid).length;
|
const count = allForms.filter((form) => form?.state.invalid).length;
|
||||||
setErrorCount(count);
|
setErrorCount(count);
|
||||||
}, [clientContext]);
|
}, [clientContext]);
|
||||||
|
|
||||||
@ -21,8 +17,8 @@ export function Save(props: { disabled: boolean }) {
|
|||||||
* Validate all node and Save
|
* Validate all node and Save
|
||||||
*/
|
*/
|
||||||
const onSave = useCallback(async () => {
|
const onSave = useCallback(async () => {
|
||||||
const allForms = clientContext.document.getAllNodes().map(node => getNodeForm(node));
|
const allForms = clientContext.document.getAllNodes().map((node) => getNodeForm(node));
|
||||||
await Promise.all(allForms.map(async form => form?.validate()));
|
await Promise.all(allForms.map(async (form) => form?.validate()));
|
||||||
console.log('>>>>> save data: ', clientContext.document.toJSON());
|
console.log('>>>>> save data: ', clientContext.document.toJSON());
|
||||||
}, [clientContext]);
|
}, [clientContext]);
|
||||||
|
|
||||||
@ -37,9 +33,9 @@ export function Save(props: { disabled: boolean }) {
|
|||||||
node.onDispose(() => formValidateDispose.dispose());
|
node.onDispose(() => formValidateDispose.dispose());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
clientContext.document.getAllNodes().map(node => listenSingleNodeValidate(node));
|
clientContext.document.getAllNodes().map((node) => listenSingleNodeValidate(node));
|
||||||
const dispose = clientContext.document.onNodeCreate(({ node }) =>
|
const dispose = clientContext.document.onNodeCreate(({ node }) =>
|
||||||
listenSingleNodeValidate(node),
|
listenSingleNodeValidate(node)
|
||||||
);
|
);
|
||||||
return () => dispose.dispose();
|
return () => dispose.dispose();
|
||||||
}, [clientContext]);
|
}, [clientContext]);
|
||||||
|
|||||||
@ -19,7 +19,7 @@ const Warning = styled.span`
|
|||||||
export const Feedback = ({ errors, warnings }: StatePanelProps) => {
|
export const Feedback = ({ errors, warnings }: StatePanelProps) => {
|
||||||
const renderFeedbacks = (fs: FieldError[] | FieldWarning[] | undefined) => {
|
const renderFeedbacks = (fs: FieldError[] | FieldWarning[] | undefined) => {
|
||||||
if (!fs) return null;
|
if (!fs) return null;
|
||||||
return fs.map(f => <span key={f.name}>{f.message}</span>);
|
return fs.map((f) => <span key={f.name}>{f.message}</span>);
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@ -41,7 +41,7 @@ export function FormHeader() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Header
|
<Header
|
||||||
onMouseDown={e => {
|
onMouseDown={(e) => {
|
||||||
// trigger drag node
|
// trigger drag node
|
||||||
startDrag(e);
|
startDrag(e);
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@ -73,7 +73,7 @@ export function FormHeader() {
|
|||||||
size="small"
|
size="small"
|
||||||
theme="borderless"
|
theme="borderless"
|
||||||
icon={<IconMore />}
|
icon={<IconMore />}
|
||||||
onClick={e => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
/>
|
/>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</Operators>
|
</Operators>
|
||||||
|
|||||||
@ -18,7 +18,7 @@ export function FormInputs() {
|
|||||||
if (!properties) {
|
if (!properties) {
|
||||||
return <></>;
|
return <></>;
|
||||||
}
|
}
|
||||||
const content = Object.keys(properties).map(key => {
|
const content = Object.keys(properties).map((key) => {
|
||||||
const property = properties[key];
|
const property = properties[key];
|
||||||
return (
|
return (
|
||||||
<Field key={key} name={`inputsValues.${key}`} defaultValue={property.default}>
|
<Field key={key} name={`inputsValues.${key}`} defaultValue={property.default}>
|
||||||
|
|||||||
@ -32,7 +32,7 @@ export function FormItem({
|
|||||||
{required && <span style={{ color: '#f93920', paddingLeft: '2px' }}>*</span>}
|
{required && <span style={{ color: '#f93920', paddingLeft: '2px' }}>*</span>}
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
[],
|
[]
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|||||||
@ -10,7 +10,7 @@ export function FormOutputs() {
|
|||||||
{({ field }) => {
|
{({ field }) => {
|
||||||
const properties = field.value?.properties;
|
const properties = field.value?.properties;
|
||||||
if (properties) {
|
if (properties) {
|
||||||
const content = Object.keys(properties).map(key => {
|
const content = Object.keys(properties).map((key) => {
|
||||||
const property = properties[key];
|
const property = properties[key];
|
||||||
return <TypeTag key={key} name={key} type={property.type as string} />;
|
return <TypeTag key={key} name={key} type={property.type as string} />;
|
||||||
});
|
});
|
||||||
|
|||||||
@ -13,7 +13,7 @@ export interface PropertiesEditProps {
|
|||||||
useFx?: boolean;
|
useFx?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PropertiesEdit: React.FC<PropertiesEditProps> = props => {
|
export const PropertiesEdit: React.FC<PropertiesEditProps> = (props) => {
|
||||||
const value = (props.value || {}) as Record<string, JsonSchema>;
|
const value = (props.value || {}) as Record<string, JsonSchema>;
|
||||||
const { readonly } = useContext(NodeRenderContext);
|
const { readonly } = useContext(NodeRenderContext);
|
||||||
const [newProperty, updateNewPropertyFromCache] = useState<{ key: string; value: JsonSchema }>({
|
const [newProperty, updateNewPropertyFromCache] = useState<{ key: string; value: JsonSchema }>({
|
||||||
@ -28,7 +28,7 @@ export const PropertiesEdit: React.FC<PropertiesEditProps> = props => {
|
|||||||
const updateProperty = (
|
const updateProperty = (
|
||||||
propertyValue: JsonSchema,
|
propertyValue: JsonSchema,
|
||||||
propertyKey: string,
|
propertyKey: string,
|
||||||
newPropertyKey?: string,
|
newPropertyKey?: string
|
||||||
) => {
|
) => {
|
||||||
const newValue = { ...value };
|
const newValue = { ...value };
|
||||||
if (newPropertyKey) {
|
if (newPropertyKey) {
|
||||||
@ -42,7 +42,7 @@ export const PropertiesEdit: React.FC<PropertiesEditProps> = props => {
|
|||||||
const updateNewProperty = (
|
const updateNewProperty = (
|
||||||
propertyValue: JsonSchema,
|
propertyValue: JsonSchema,
|
||||||
propertyKey: string,
|
propertyKey: string,
|
||||||
newPropertyKey?: string,
|
newPropertyKey?: string
|
||||||
) => {
|
) => {
|
||||||
// const newValue = { ...value }
|
// const newValue = { ...value }
|
||||||
if (newPropertyKey) {
|
if (newPropertyKey) {
|
||||||
@ -59,7 +59,7 @@ export const PropertiesEdit: React.FC<PropertiesEditProps> = props => {
|
|||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{Object.keys(props.value || {}).map(key => {
|
{Object.keys(props.value || {}).map((key) => {
|
||||||
const property = (value[key] || {}) as JsonSchema;
|
const property = (value[key] || {}) as JsonSchema;
|
||||||
return (
|
return (
|
||||||
<PropertyEdit
|
<PropertyEdit
|
||||||
|
|||||||
@ -19,7 +19,7 @@ interface GroupNoteProps {
|
|||||||
enableTooltip?: boolean;
|
enableTooltip?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const GroupNote: FC<GroupNoteProps> = props => {
|
export const GroupNote: FC<GroupNoteProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
groupController,
|
groupController,
|
||||||
containerStyle = {},
|
containerStyle = {},
|
||||||
@ -65,14 +65,14 @@ export const GroupNote: FC<GroupNoteProps> = props => {
|
|||||||
>
|
>
|
||||||
<MultiLineEditor
|
<MultiLineEditor
|
||||||
value={editingValue}
|
value={editingValue}
|
||||||
onChange={note => {
|
onChange={(note) => {
|
||||||
setEditingValue(note || '');
|
setEditingValue(note || '');
|
||||||
}}
|
}}
|
||||||
readonly={playground.config.readonly}
|
readonly={playground.config.readonly}
|
||||||
placeholder="Please enter note"
|
placeholder="Please enter note"
|
||||||
style={textStyle}
|
style={textStyle}
|
||||||
autoSize={autoSize}
|
autoSize={autoSize}
|
||||||
onEditingChange={editingState => {
|
onEditingChange={(editingState) => {
|
||||||
if (editingState) {
|
if (editingState) {
|
||||||
setTooltipVisible(false);
|
setTooltipVisible(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,7 +29,7 @@ interface GroupToolsProps {
|
|||||||
|
|
||||||
const BUTTON_HEIGHT = 24;
|
const BUTTON_HEIGHT = 24;
|
||||||
|
|
||||||
export const GroupTools: FC<GroupToolsProps> = props => {
|
export const GroupTools: FC<GroupToolsProps> = (props) => {
|
||||||
const { groupNode, groupController, visible, style = {} } = props;
|
const { groupNode, groupController, visible, style = {} } = props;
|
||||||
|
|
||||||
const groupService = useService<FlowGroupService>(FlowGroupService);
|
const groupService = useService<FlowGroupService>(FlowGroupService);
|
||||||
@ -53,7 +53,7 @@ export const GroupTools: FC<GroupToolsProps> = props => {
|
|||||||
color: 'rgb(97, 69, 211)',
|
color: 'rgb(97, 69, 211)',
|
||||||
...style,
|
...style,
|
||||||
}}
|
}}
|
||||||
onMouseDown={e => {
|
onMouseDown={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@ -64,7 +64,7 @@ export const GroupTools: FC<GroupToolsProps> = props => {
|
|||||||
icon={<IconHandle />}
|
icon={<IconHandle />}
|
||||||
type="primary"
|
type="primary"
|
||||||
theme="borderless"
|
theme="borderless"
|
||||||
onMouseDown={e => {
|
onMouseDown={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
startDrag(e, {
|
startDrag(e, {
|
||||||
dragStartEntity: groupNode,
|
dragStartEntity: groupNode,
|
||||||
@ -80,7 +80,7 @@ export const GroupTools: FC<GroupToolsProps> = props => {
|
|||||||
icon={groupController?.collapsed ? <IconExpand /> : <IconShrink />}
|
icon={groupController?.collapsed ? <IconExpand /> : <IconShrink />}
|
||||||
type="primary"
|
type="primary"
|
||||||
theme="borderless"
|
theme="borderless"
|
||||||
onClick={e => {
|
onClick={(e) => {
|
||||||
if (!groupController) {
|
if (!groupController) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,7 +15,7 @@ interface Props {
|
|||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
const BaseTextarea: React.FC<Props> = props => {
|
const BaseTextarea: React.FC<Props> = (props) => {
|
||||||
const { value, onChange, onBlur, editing, onFocus, autoSize = true, ...rest } = props;
|
const { value, onChange, onBlur, editing, onFocus, autoSize = true, ...rest } = props;
|
||||||
|
|
||||||
const [data, setData] = useState(value);
|
const [data, setData] = useState(value);
|
||||||
@ -46,7 +46,7 @@ const BaseTextarea: React.FC<Props> = props => {
|
|||||||
{...rest}
|
{...rest}
|
||||||
ref={textareaRef}
|
ref={textareaRef}
|
||||||
value={data}
|
value={data}
|
||||||
onChange={v => {
|
onChange={(v) => {
|
||||||
setData(v);
|
setData(v);
|
||||||
}}
|
}}
|
||||||
onEnterPress={onSubmit}
|
onEnterPress={onSubmit}
|
||||||
|
|||||||
@ -21,7 +21,7 @@ interface Props {
|
|||||||
onEditingChange?: (editing: boolean) => void;
|
onEditingChange?: (editing: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MultiLineEditor: React.FC<Props> = props => {
|
const MultiLineEditor: React.FC<Props> = (props) => {
|
||||||
const {
|
const {
|
||||||
value,
|
value,
|
||||||
onChange,
|
onChange,
|
||||||
|
|||||||
@ -14,27 +14,27 @@ import { writeData } from './utils';
|
|||||||
import { FlowCommandId } from './constants';
|
import { FlowCommandId } from './constants';
|
||||||
|
|
||||||
type ShortcutGetter = (
|
type ShortcutGetter = (
|
||||||
ctx: FixedLayoutPluginContext,
|
ctx: FixedLayoutPluginContext
|
||||||
) => Parameters<ShortcutsRegistry['addHandlers']>[0];
|
) => Parameters<ShortcutsRegistry['addHandlers']>[0];
|
||||||
|
|
||||||
const copy: ShortcutGetter = ctx => {
|
const copy: ShortcutGetter = (ctx) => {
|
||||||
const selection = ctx.selection;
|
const selection = ctx.selection;
|
||||||
const clipboard = ctx.clipboard;
|
const clipboard = ctx.clipboard;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
commandId: FlowCommandId.COPY,
|
commandId: FlowCommandId.COPY,
|
||||||
shortcuts: ['meta c', 'ctrl c'],
|
shortcuts: ['meta c', 'ctrl c'],
|
||||||
isEnabled: node =>
|
isEnabled: (node) =>
|
||||||
(selection?.selection.length > 0 || node instanceof FlowNodeEntity) &&
|
(selection?.selection.length > 0 || node instanceof FlowNodeEntity) &&
|
||||||
!ctx.playground.config.readonlyOrDisabled,
|
!ctx.playground.config.readonlyOrDisabled,
|
||||||
execute: node => {
|
execute: (node) => {
|
||||||
const nodes =
|
const nodes =
|
||||||
node instanceof FlowNodeEntity
|
node instanceof FlowNodeEntity
|
||||||
? [node]
|
? [node]
|
||||||
: (selection.selection.filter(
|
: (selection.selection.filter(
|
||||||
_entity => _entity instanceof FlowNodeEntity,
|
(_entity) => _entity instanceof FlowNodeEntity
|
||||||
) as FlowNodeEntity[]);
|
) as FlowNodeEntity[]);
|
||||||
const originNodes = nodes.map(n => ({
|
const originNodes = nodes.map((n) => ({
|
||||||
...n.toJSON(),
|
...n.toJSON(),
|
||||||
id: `${n.flowNodeType}_${nanoid()}`,
|
id: `${n.flowNodeType}_${nanoid()}`,
|
||||||
}));
|
}));
|
||||||
@ -47,7 +47,7 @@ const copy: ShortcutGetter = ctx => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const cut: ShortcutGetter = ctx => {
|
const cut: ShortcutGetter = (ctx) => {
|
||||||
const selection = ctx.selection;
|
const selection = ctx.selection;
|
||||||
|
|
||||||
const commandRegistry = ctx.get<CommandRegistry>(CommandRegistry);
|
const commandRegistry = ctx.get<CommandRegistry>(CommandRegistry);
|
||||||
@ -75,7 +75,7 @@ const cut: ShortcutGetter = ctx => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const zoomIn: ShortcutGetter = ctx => {
|
const zoomIn: ShortcutGetter = (ctx) => {
|
||||||
const config = ctx.playground.config;
|
const config = ctx.playground.config;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -87,7 +87,7 @@ const zoomIn: ShortcutGetter = ctx => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const zoomOut: ShortcutGetter = ctx => {
|
const zoomOut: ShortcutGetter = (ctx) => {
|
||||||
const config = ctx.playground.config;
|
const config = ctx.playground.config;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -99,7 +99,7 @@ const zoomOut: ShortcutGetter = ctx => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const resetZoom: ShortcutGetter = ctx => ({
|
const resetZoom: ShortcutGetter = (ctx) => ({
|
||||||
commandId: FlowCommandId.RESET_ZOOM,
|
commandId: FlowCommandId.RESET_ZOOM,
|
||||||
commandDetail: {
|
commandDetail: {
|
||||||
label: 'Reset Zoom',
|
label: 'Reset Zoom',
|
||||||
@ -110,7 +110,7 @@ const resetZoom: ShortcutGetter = ctx => ({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const group: ShortcutGetter = ctx => ({
|
const group: ShortcutGetter = (ctx) => ({
|
||||||
commandId: FlowCommandId.GROUP,
|
commandId: FlowCommandId.GROUP,
|
||||||
commandDetail: {
|
commandDetail: {
|
||||||
label: 'Create Group',
|
label: 'Create Group',
|
||||||
@ -123,14 +123,14 @@ const group: ShortcutGetter = ctx => ({
|
|||||||
const selection = ctx.playground.selectionService;
|
const selection = ctx.playground.selectionService;
|
||||||
|
|
||||||
groupService.createGroup(
|
groupService.createGroup(
|
||||||
selection.selection.filter(_entity => _entity instanceof FlowNodeEntity) as FlowNodeEntity[],
|
selection.selection.filter((_entity) => _entity instanceof FlowNodeEntity) as FlowNodeEntity[]
|
||||||
);
|
);
|
||||||
|
|
||||||
ctx.playground.selectionService.selection = [];
|
ctx.playground.selectionService.selection = [];
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const selectAll: ShortcutGetter = ctx => ({
|
const selectAll: ShortcutGetter = (ctx) => ({
|
||||||
commandId: FlowCommandId.SELECT_ALL,
|
commandId: FlowCommandId.SELECT_ALL,
|
||||||
commandDetail: {
|
commandDetail: {
|
||||||
label: 'Select All',
|
label: 'Select All',
|
||||||
@ -139,14 +139,14 @@ const selectAll: ShortcutGetter = ctx => ({
|
|||||||
isEnabled: () => !ctx.playground.config.readonlyOrDisabled,
|
isEnabled: () => !ctx.playground.config.readonlyOrDisabled,
|
||||||
execute: () => {
|
execute: () => {
|
||||||
const allNodes = (ctx.document.root.children || []).filter(
|
const allNodes = (ctx.document.root.children || []).filter(
|
||||||
node => node.flowNodeType !== 'start' && node.flowNodeType !== 'end',
|
(node) => node.flowNodeType !== 'start' && node.flowNodeType !== 'end'
|
||||||
);
|
);
|
||||||
|
|
||||||
ctx.playground.selectionService.selection = allNodes;
|
ctx.playground.selectionService.selection = allNodes;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const cancelSelect: ShortcutGetter = ctx => ({
|
const cancelSelect: ShortcutGetter = (ctx) => ({
|
||||||
commandId: FlowCommandId.CANCEL_SELECT,
|
commandId: FlowCommandId.CANCEL_SELECT,
|
||||||
commandDetail: {
|
commandDetail: {
|
||||||
label: 'Cancel Select',
|
label: 'Cancel Select',
|
||||||
@ -157,7 +157,7 @@ const cancelSelect: ShortcutGetter = ctx => ({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const collapse: ShortcutGetter = ctx => ({
|
const collapse: ShortcutGetter = (ctx) => ({
|
||||||
commandId: FlowCommandId.COLLAPSE,
|
commandId: FlowCommandId.COLLAPSE,
|
||||||
commandDetail: {
|
commandDetail: {
|
||||||
label: 'Collapse',
|
label: 'Collapse',
|
||||||
@ -168,19 +168,19 @@ const collapse: ShortcutGetter = ctx => ({
|
|||||||
const selection = ctx.selection;
|
const selection = ctx.selection;
|
||||||
|
|
||||||
const selectNodes = selection.selection.filter(
|
const selectNodes = selection.selection.filter(
|
||||||
_entity => _entity instanceof FlowNodeEntity,
|
(_entity) => _entity instanceof FlowNodeEntity
|
||||||
) as FlowNodeEntity[];
|
) as FlowNodeEntity[];
|
||||||
|
|
||||||
selectNodes
|
selectNodes
|
||||||
.map(_node => [_node, ..._node.allCollapsedChildren])
|
.map((_node) => [_node, ..._node.allCollapsedChildren])
|
||||||
.flat()
|
.flat()
|
||||||
.forEach(node => {
|
.forEach((node) => {
|
||||||
const renderData = node.getData(FlowNodeRenderData);
|
const renderData = node.getData(FlowNodeRenderData);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
node.firstChild &&
|
node.firstChild &&
|
||||||
[FlowNodeBaseType.BLOCK_ICON, FlowNodeBaseType.BLOCK_ORDER_ICON].includes(
|
[FlowNodeBaseType.BLOCK_ICON, FlowNodeBaseType.BLOCK_ORDER_ICON].includes(
|
||||||
node.firstChild.flowNodeType as FlowNodeBaseType,
|
node.firstChild.flowNodeType as FlowNodeBaseType
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
node.collapsed = true;
|
node.collapsed = true;
|
||||||
@ -191,7 +191,7 @@ const collapse: ShortcutGetter = ctx => ({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const expand: ShortcutGetter = ctx => ({
|
const expand: ShortcutGetter = (ctx) => ({
|
||||||
commandId: FlowCommandId.EXPAND,
|
commandId: FlowCommandId.EXPAND,
|
||||||
commandDetail: {
|
commandDetail: {
|
||||||
label: 'Expand',
|
label: 'Expand',
|
||||||
@ -202,19 +202,19 @@ const expand: ShortcutGetter = ctx => ({
|
|||||||
const selection = ctx.selection;
|
const selection = ctx.selection;
|
||||||
|
|
||||||
const selectNodes = selection.selection.filter(
|
const selectNodes = selection.selection.filter(
|
||||||
_entity => _entity instanceof FlowNodeEntity,
|
(_entity) => _entity instanceof FlowNodeEntity
|
||||||
) as FlowNodeEntity[];
|
) as FlowNodeEntity[];
|
||||||
|
|
||||||
selectNodes
|
selectNodes
|
||||||
.map(_node => [_node, ..._node.allCollapsedChildren])
|
.map((_node) => [_node, ..._node.allCollapsedChildren])
|
||||||
.flat()
|
.flat()
|
||||||
.forEach(node => {
|
.forEach((node) => {
|
||||||
const renderData = node.getData(FlowNodeRenderData);
|
const renderData = node.getData(FlowNodeRenderData);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
node.firstChild &&
|
node.firstChild &&
|
||||||
[FlowNodeBaseType.BLOCK_ICON, FlowNodeBaseType.BLOCK_ORDER_ICON].includes(
|
[FlowNodeBaseType.BLOCK_ICON, FlowNodeBaseType.BLOCK_ORDER_ICON].includes(
|
||||||
node.firstChild.flowNodeType as FlowNodeBaseType,
|
node.firstChild.flowNodeType as FlowNodeBaseType
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
node.collapsed = false;
|
node.collapsed = false;
|
||||||
|
|||||||
@ -7,4 +7,9 @@ module.exports = defineConfig({
|
|||||||
'no-console': 'off',
|
'no-console': 'off',
|
||||||
'react/prop-types': 'off',
|
'react/prop-types': 'off',
|
||||||
},
|
},
|
||||||
|
settings: {
|
||||||
|
react: {
|
||||||
|
version: 'detect', // 自动检测 React 版本
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { FlowMinimapService, MinimapRender } from '@flowgram.ai/minimap-plugin';
|
import { FlowMinimapService, MinimapRender } from '@flowgram.ai/minimap-plugin';
|
||||||
import { useService } from '@flowgram.ai/free-layout-editor';
|
import { useService } from '@flowgram.ai/free-layout-editor';
|
||||||
|
|
||||||
|
|
||||||
export const Minimap = () => {
|
export const Minimap = () => {
|
||||||
const minimapService = useService(FlowMinimapService);
|
const minimapService = useService(FlowMinimapService);
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -4,21 +4,23 @@ import { WorkflowDragService, useService } from '@flowgram.ai/free-layout-editor
|
|||||||
|
|
||||||
const cardkeys = ['Node1', 'Node2'];
|
const cardkeys = ['Node1', 'Node2'];
|
||||||
|
|
||||||
export const NodeAddPanel: React.FC = props => {
|
export const NodeAddPanel: React.FC = (props) => {
|
||||||
const startDragSerivce = useService<WorkflowDragService>(WorkflowDragService);
|
const startDragSerivce = useService<WorkflowDragService>(WorkflowDragService);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="demo-free-sidebar">
|
<div className="demo-free-sidebar">
|
||||||
{cardkeys.map(nodeType => (
|
{cardkeys.map((nodeType) => (
|
||||||
<div
|
<div
|
||||||
key={nodeType}
|
key={nodeType}
|
||||||
className="demo-free-card"
|
className="demo-free-card"
|
||||||
onMouseDown={e => startDragSerivce.startDragCard(nodeType, e, {
|
onMouseDown={(e) =>
|
||||||
|
startDragSerivce.startDragCard(nodeType, e, {
|
||||||
data: {
|
data: {
|
||||||
title: `New ${nodeType}`,
|
title: `New ${nodeType}`,
|
||||||
content: 'xxxx'
|
content: 'xxxx',
|
||||||
|
},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})}
|
|
||||||
>
|
>
|
||||||
{nodeType}
|
{nodeType}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
import { usePlaygroundTools, useClientContext } from '@flowgram.ai/free-layout-editor';
|
import { usePlaygroundTools, useClientContext } from '@flowgram.ai/free-layout-editor';
|
||||||
|
|
||||||
export function Tools() {
|
export function Tools() {
|
||||||
@ -15,13 +16,21 @@ export function Tools() {
|
|||||||
return () => disposable.dispose();
|
return () => disposable.dispose();
|
||||||
}, [history]);
|
}, [history]);
|
||||||
|
|
||||||
return <div style={{ position: 'absolute', zIndex: 10, bottom: 16, left: 226, display: 'flex', gap: 8 }}>
|
return (
|
||||||
|
<div
|
||||||
|
style={{ position: 'absolute', zIndex: 10, bottom: 16, left: 226, display: 'flex', gap: 8 }}
|
||||||
|
>
|
||||||
<button onClick={() => tools.zoomin()}>ZoomIn</button>
|
<button onClick={() => tools.zoomin()}>ZoomIn</button>
|
||||||
<button onClick={() => tools.zoomout()}>ZoomOut</button>
|
<button onClick={() => tools.zoomout()}>ZoomOut</button>
|
||||||
<button onClick={() => tools.fitView()}>Fitview</button>
|
<button onClick={() => tools.fitView()}>Fitview</button>
|
||||||
<button onClick={() => tools.autoLayout()}>AutoLayout</button>
|
<button onClick={() => tools.autoLayout()}>AutoLayout</button>
|
||||||
<button onClick={() => history.undo()} disabled={!canUndo}>Undo</button>
|
<button onClick={() => history.undo()} disabled={!canUndo}>
|
||||||
<button onClick={() => history.redo()} disabled={!canRedo}>Redo</button>
|
Undo
|
||||||
|
</button>
|
||||||
|
<button onClick={() => history.redo()} disabled={!canRedo}>
|
||||||
|
Redo
|
||||||
|
</button>
|
||||||
<span>{Math.floor(tools.zoom * 100)}%</span>
|
<span>{Math.floor(tools.zoom * 100)}%</span>
|
||||||
</div>
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,17 +1,14 @@
|
|||||||
import {
|
import { EditorRenderer, FreeLayoutEditorProvider } from '@flowgram.ai/free-layout-editor';
|
||||||
EditorRenderer,
|
|
||||||
FreeLayoutEditorProvider,
|
|
||||||
} from '@flowgram.ai/free-layout-editor';
|
|
||||||
|
|
||||||
|
import { useEditorProps } from './hooks/use-editor-props';
|
||||||
|
import { Tools } from './components/tools';
|
||||||
import { NodeAddPanel } from './components/node-add-panel';
|
import { NodeAddPanel } from './components/node-add-panel';
|
||||||
import { Tools } from './components/tools'
|
import { Minimap } from './components/minimap';
|
||||||
import { Minimap } from './components/minimap'
|
|
||||||
import { useEditorProps } from './hooks/use-editor-props'
|
|
||||||
import '@flowgram.ai/free-layout-editor/index.css';
|
import '@flowgram.ai/free-layout-editor/index.css';
|
||||||
import './index.css';
|
import './index.css';
|
||||||
|
|
||||||
export const Editor = () => {
|
export const Editor = () => {
|
||||||
const editorProps = useEditorProps()
|
const editorProps = useEditorProps();
|
||||||
return (
|
return (
|
||||||
<FreeLayoutEditorProvider {...editorProps}>
|
<FreeLayoutEditorProvider {...editorProps}>
|
||||||
<div className="demo-free-container">
|
<div className="demo-free-container">
|
||||||
@ -23,5 +20,5 @@ export const Editor = () => {
|
|||||||
<Minimap />
|
<Minimap />
|
||||||
</div>
|
</div>
|
||||||
</FreeLayoutEditorProvider>
|
</FreeLayoutEditorProvider>
|
||||||
)
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,19 +1,20 @@
|
|||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
|
import { createMinimapPlugin } from '@flowgram.ai/minimap-plugin';
|
||||||
|
import { createFreeSnapPlugin } from '@flowgram.ai/free-snap-plugin';
|
||||||
import {
|
import {
|
||||||
FreeLayoutProps,
|
FreeLayoutProps,
|
||||||
WorkflowNodeProps,
|
WorkflowNodeProps,
|
||||||
WorkflowNodeRenderer,
|
WorkflowNodeRenderer,
|
||||||
Field,
|
Field,
|
||||||
useNodeRender
|
useNodeRender,
|
||||||
} from '@flowgram.ai/free-layout-editor';
|
} from '@flowgram.ai/free-layout-editor';
|
||||||
import { createMinimapPlugin } from '@flowgram.ai/minimap-plugin';
|
|
||||||
import { createFreeSnapPlugin } from '@flowgram.ai/free-snap-plugin';
|
|
||||||
|
|
||||||
|
import { nodeRegistries } from '../node-registries';
|
||||||
import { initialData } from '../initial-data';
|
import { initialData } from '../initial-data';
|
||||||
import { nodeRegistries } from '../node-registries'
|
|
||||||
|
|
||||||
export const useEditorProps = () => useMemo<FreeLayoutProps>(
|
export const useEditorProps = () =>
|
||||||
|
useMemo<FreeLayoutProps>(
|
||||||
() => ({
|
() => ({
|
||||||
/**
|
/**
|
||||||
* Whether to enable the background
|
* Whether to enable the background
|
||||||
@ -47,7 +48,8 @@ export const useEditorProps = () => useMemo<FreeLayoutProps>(
|
|||||||
/**
|
/**
|
||||||
* Render form
|
* Render form
|
||||||
*/
|
*/
|
||||||
render: () => <>
|
render: () => (
|
||||||
|
<>
|
||||||
<Field<string> name="title">
|
<Field<string> name="title">
|
||||||
{({ field }) => <div className="demo-free-node-title">{field.value}</div>}
|
{({ field }) => <div className="demo-free-node-title">{field.value}</div>}
|
||||||
</Field>
|
</Field>
|
||||||
@ -57,7 +59,8 @@ export const useEditorProps = () => useMemo<FreeLayoutProps>(
|
|||||||
</Field>
|
</Field>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
}
|
),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
materials: {
|
materials: {
|
||||||
@ -65,12 +68,12 @@ export const useEditorProps = () => useMemo<FreeLayoutProps>(
|
|||||||
* Render Node
|
* Render Node
|
||||||
*/
|
*/
|
||||||
renderDefaultNode: (props: WorkflowNodeProps) => {
|
renderDefaultNode: (props: WorkflowNodeProps) => {
|
||||||
const { form } = useNodeRender()
|
const { form } = useNodeRender();
|
||||||
return (
|
return (
|
||||||
<WorkflowNodeRenderer className="demo-free-node" node={props.node}>
|
<WorkflowNodeRenderer className="demo-free-node" node={props.node}>
|
||||||
{form?.render()}
|
{form?.render()}
|
||||||
</WorkflowNodeRenderer>
|
</WorkflowNodeRenderer>
|
||||||
)
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
@ -95,7 +98,7 @@ export const useEditorProps = () => useMemo<FreeLayoutProps>(
|
|||||||
/**
|
/**
|
||||||
* Playground init
|
* Playground init
|
||||||
*/
|
*/
|
||||||
onInit: ctx => {},
|
onInit: (ctx) => {},
|
||||||
/**
|
/**
|
||||||
* Playground render
|
* Playground render
|
||||||
*/
|
*/
|
||||||
@ -146,7 +149,7 @@ export const useEditorProps = () => useMemo<FreeLayoutProps>(
|
|||||||
alignLineWidth: 1,
|
alignLineWidth: 1,
|
||||||
alignCrossWidth: 8,
|
alignCrossWidth: 8,
|
||||||
}),
|
}),
|
||||||
]
|
],
|
||||||
}),
|
}),
|
||||||
[],
|
[]
|
||||||
);
|
);
|
||||||
|
|||||||
@ -10,7 +10,7 @@ export const initialData: WorkflowJSON = {
|
|||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
title: 'Start',
|
title: 'Start',
|
||||||
content: 'Start content'
|
content: 'Start content',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -21,7 +21,7 @@ export const initialData: WorkflowJSON = {
|
|||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
title: 'Custom',
|
title: 'Custom',
|
||||||
content: 'Custom node content'
|
content: 'Custom node content',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -32,7 +32,7 @@ export const initialData: WorkflowJSON = {
|
|||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
title: 'End',
|
title: 'End',
|
||||||
content: 'End content'
|
content: 'End content',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -47,4 +47,3 @@ export const initialData: WorkflowJSON = {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -24,8 +24,7 @@ export const nodeRegistries: WorkflowNodeRegistry[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'custom',
|
type: 'custom',
|
||||||
meta: {
|
meta: {},
|
||||||
},
|
|
||||||
defaultPorts: [{ type: 'output' }, { type: 'input' }], // A normal node has two ports
|
defaultPorts: [{ type: 'output' }, { type: 'input' }], // A normal node has two ports
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@ -7,4 +7,9 @@ module.exports = defineConfig({
|
|||||||
'no-console': 'off',
|
'no-console': 'off',
|
||||||
'react/prop-types': 'off',
|
'react/prop-types': 'off',
|
||||||
},
|
},
|
||||||
|
settings: {
|
||||||
|
react: {
|
||||||
|
version: 'detect', // 自动检测 React 版本
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -22,7 +22,7 @@ export const SelectorBoxPopover: FunctionComponent<SelectorBoxPopoverProps> = ({
|
|||||||
top: bounds.top,
|
top: bounds.top,
|
||||||
transform: 'translate(-100%, -100%)',
|
transform: 'translate(-100%, -100%)',
|
||||||
}}
|
}}
|
||||||
onMouseDown={e => {
|
onMouseDown={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@ -36,7 +36,7 @@ export const SelectorBoxPopover: FunctionComponent<SelectorBoxPopoverProps> = ({
|
|||||||
style={{ height: BUTTON_HEIGHT }}
|
style={{ height: BUTTON_HEIGHT }}
|
||||||
type="primary"
|
type="primary"
|
||||||
theme="solid"
|
theme="solid"
|
||||||
onMouseDown={e => {
|
onMouseDown={(e) => {
|
||||||
commandRegistry.executeCommand(FlowCommandId.COLLAPSE);
|
commandRegistry.executeCommand(FlowCommandId.COLLAPSE);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@ -48,7 +48,7 @@ export const SelectorBoxPopover: FunctionComponent<SelectorBoxPopoverProps> = ({
|
|||||||
style={{ height: BUTTON_HEIGHT }}
|
style={{ height: BUTTON_HEIGHT }}
|
||||||
type="primary"
|
type="primary"
|
||||||
theme="solid"
|
theme="solid"
|
||||||
onMouseDown={e => {
|
onMouseDown={(e) => {
|
||||||
commandRegistry.executeCommand(FlowCommandId.EXPAND);
|
commandRegistry.executeCommand(FlowCommandId.EXPAND);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -4,6 +4,9 @@ import {
|
|||||||
usePlaygroundTools,
|
usePlaygroundTools,
|
||||||
type InteractiveType as IdeInteractiveType,
|
type InteractiveType as IdeInteractiveType,
|
||||||
} from '@flowgram.ai/free-layout-editor';
|
} from '@flowgram.ai/free-layout-editor';
|
||||||
|
import { Tooltip, Popover } from '@douyinfe/semi-ui';
|
||||||
|
|
||||||
|
import { MousePadSelector } from './mouse-pad-selector';
|
||||||
|
|
||||||
export const CACHE_KEY = 'workflow_prefer_interactive_type';
|
export const CACHE_KEY = 'workflow_prefer_interactive_type';
|
||||||
export const SHOW_KEY = 'show_workflow_interactive_type_guide';
|
export const SHOW_KEY = 'show_workflow_interactive_type_guide';
|
||||||
@ -25,9 +28,6 @@ export enum InteractiveType {
|
|||||||
Mouse = 'MOUSE',
|
Mouse = 'MOUSE',
|
||||||
Pad = 'PAD',
|
Pad = 'PAD',
|
||||||
}
|
}
|
||||||
import { Tooltip, Popover } from '@douyinfe/semi-ui';
|
|
||||||
|
|
||||||
import { MousePadSelector } from './mouse-pad-selector';
|
|
||||||
|
|
||||||
export const Interactive = () => {
|
export const Interactive = () => {
|
||||||
const tools = usePlaygroundTools();
|
const tools = usePlaygroundTools();
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import { EditorRenderer, FreeLayoutEditorProvider } from '@flowgram.ai/free-layout-editor';
|
import { EditorRenderer, FreeLayoutEditorProvider } from '@flowgram.ai/free-layout-editor';
|
||||||
|
|
||||||
import { DemoTools } from './components/tools';
|
|
||||||
import '@flowgram.ai/free-layout-editor/index.css';
|
import '@flowgram.ai/free-layout-editor/index.css';
|
||||||
import './styles/index.css';
|
import './styles/index.css';
|
||||||
import { nodeRegistries } from './nodes';
|
import { nodeRegistries } from './nodes';
|
||||||
import { initialData } from './initial-data';
|
import { initialData } from './initial-data';
|
||||||
import { useEditorProps } from './hooks';
|
import { useEditorProps } from './hooks';
|
||||||
|
import { DemoTools } from './components/tools';
|
||||||
|
|
||||||
export const Editor = () => {
|
export const Editor = () => {
|
||||||
const editorProps = useEditorProps(initialData, nodeRegistries);
|
const editorProps = useEditorProps(initialData, nodeRegistries);
|
||||||
|
|||||||
@ -20,7 +20,7 @@ const Warning = styled.span`
|
|||||||
export const Feedback = ({ errors, warnings, invalid }: StatePanelProps) => {
|
export const Feedback = ({ errors, warnings, invalid }: StatePanelProps) => {
|
||||||
const renderFeedbacks = (fs: FieldError[] | FieldWarning[] | undefined) => {
|
const renderFeedbacks = (fs: FieldError[] | FieldWarning[] | undefined) => {
|
||||||
if (!fs) return null;
|
if (!fs) return null;
|
||||||
return fs.map(f => <span key={f.name}>{f.message}</span>);
|
return fs.map((f) => <span key={f.name}>{f.message}</span>);
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@ -71,7 +71,7 @@ export function FormHeader() {
|
|||||||
size="small"
|
size="small"
|
||||||
theme="borderless"
|
theme="borderless"
|
||||||
icon={<IconMore />}
|
icon={<IconMore />}
|
||||||
onClick={e => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
/>
|
/>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</Operators>
|
</Operators>
|
||||||
|
|||||||
@ -18,7 +18,7 @@ export function FormInputs() {
|
|||||||
if (!properties) {
|
if (!properties) {
|
||||||
return <></>;
|
return <></>;
|
||||||
}
|
}
|
||||||
const content = Object.keys(properties).map(key => {
|
const content = Object.keys(properties).map((key) => {
|
||||||
const property = properties[key];
|
const property = properties[key];
|
||||||
return (
|
return (
|
||||||
<Field key={key} name={`inputsValues.${key}`} defaultValue={property.default}>
|
<Field key={key} name={`inputsValues.${key}`} defaultValue={property.default}>
|
||||||
|
|||||||
@ -32,7 +32,7 @@ export function FormItem({
|
|||||||
{required && <span style={{ color: '#f93920', paddingLeft: '2px' }}>*</span>}
|
{required && <span style={{ color: '#f93920', paddingLeft: '2px' }}>*</span>}
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
[],
|
[]
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|||||||
@ -10,7 +10,7 @@ export function FormOutputs() {
|
|||||||
{({ field }) => {
|
{({ field }) => {
|
||||||
const properties = field.value?.properties;
|
const properties = field.value?.properties;
|
||||||
if (properties) {
|
if (properties) {
|
||||||
const content = Object.keys(properties).map(key => {
|
const content = Object.keys(properties).map((key) => {
|
||||||
const property = properties[key];
|
const property = properties[key];
|
||||||
return <TypeTag key={key} name={key} type={property.type as string} />;
|
return <TypeTag key={key} name={key} type={property.type as string} />;
|
||||||
});
|
});
|
||||||
|
|||||||
@ -13,7 +13,7 @@ export interface PropertiesEditProps {
|
|||||||
useFx?: boolean;
|
useFx?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PropertiesEdit: React.FC<PropertiesEditProps> = props => {
|
export const PropertiesEdit: React.FC<PropertiesEditProps> = (props) => {
|
||||||
const value = (props.value || {}) as Record<string, JsonSchema>;
|
const value = (props.value || {}) as Record<string, JsonSchema>;
|
||||||
const { readonly } = useContext(NodeRenderContext);
|
const { readonly } = useContext(NodeRenderContext);
|
||||||
const [newProperty, updateNewPropertyFromCache] = useState<{ key: string; value: JsonSchema }>({
|
const [newProperty, updateNewPropertyFromCache] = useState<{ key: string; value: JsonSchema }>({
|
||||||
@ -28,7 +28,7 @@ export const PropertiesEdit: React.FC<PropertiesEditProps> = props => {
|
|||||||
const updateProperty = (
|
const updateProperty = (
|
||||||
propertyValue: JsonSchema,
|
propertyValue: JsonSchema,
|
||||||
propertyKey: string,
|
propertyKey: string,
|
||||||
newPropertyKey?: string,
|
newPropertyKey?: string
|
||||||
) => {
|
) => {
|
||||||
const newValue = { ...value };
|
const newValue = { ...value };
|
||||||
if (newPropertyKey) {
|
if (newPropertyKey) {
|
||||||
@ -42,7 +42,7 @@ export const PropertiesEdit: React.FC<PropertiesEditProps> = props => {
|
|||||||
const updateNewProperty = (
|
const updateNewProperty = (
|
||||||
propertyValue: JsonSchema,
|
propertyValue: JsonSchema,
|
||||||
propertyKey: string,
|
propertyKey: string,
|
||||||
newPropertyKey?: string,
|
newPropertyKey?: string
|
||||||
) => {
|
) => {
|
||||||
// const newValue = { ...value }
|
// const newValue = { ...value }
|
||||||
if (newPropertyKey) {
|
if (newPropertyKey) {
|
||||||
@ -59,7 +59,7 @@ export const PropertiesEdit: React.FC<PropertiesEditProps> = props => {
|
|||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{Object.keys(props.value || {}).map(key => {
|
{Object.keys(props.value || {}).map((key) => {
|
||||||
const property = (value[key] || {}) as JsonSchema;
|
const property = (value[key] || {}) as JsonSchema;
|
||||||
return (
|
return (
|
||||||
<PropertyEdit
|
<PropertyEdit
|
||||||
|
|||||||
@ -29,7 +29,7 @@ export function ConditionInputs() {
|
|||||||
<FormItem name="if" type="boolean" required={true} labelWidth={40}>
|
<FormItem name="if" type="boolean" required={true} labelWidth={40}>
|
||||||
<FxExpression
|
<FxExpression
|
||||||
value={childField.value.value}
|
value={childField.value.value}
|
||||||
onChange={v => childField.onChange({ key: childField.value.key, value: v })}
|
onChange={(v) => childField.onChange({ key: childField.value.key, value: v })}
|
||||||
icon={
|
icon={
|
||||||
<Button
|
<Button
|
||||||
theme="borderless"
|
theme="borderless"
|
||||||
|
|||||||
@ -25,7 +25,7 @@ export function shortcuts(shortcutsRegistry: ShortcutsRegistry, ctx: FreeLayoutP
|
|||||||
shortcutsRegistry.addHandlers({
|
shortcutsRegistry.addHandlers({
|
||||||
commandId: FlowCommandId.COPY,
|
commandId: FlowCommandId.COPY,
|
||||||
shortcuts: ['meta c', 'ctrl c'],
|
shortcuts: ['meta c', 'ctrl c'],
|
||||||
execute: async e => {
|
execute: async (e) => {
|
||||||
const document = ctx.get<WorkflowDocument>(WorkflowDocument);
|
const document = ctx.get<WorkflowDocument>(WorkflowDocument);
|
||||||
const selectService = ctx.get<WorkflowSelectService>(WorkflowSelectService);
|
const selectService = ctx.get<WorkflowSelectService>(WorkflowSelectService);
|
||||||
|
|
||||||
@ -45,30 +45,30 @@ export function shortcuts(shortcutsRegistry: ShortcutsRegistry, ctx: FreeLayoutP
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const nodeEntities = selectedNodes.filter(
|
const nodeEntities = selectedNodes.filter(
|
||||||
n => n.flowNodeType !== 'start' && n.flowNodeType !== 'end',
|
(n) => n.flowNodeType !== 'start' && n.flowNodeType !== 'end'
|
||||||
);
|
);
|
||||||
const nodes = await Promise.all(
|
const nodes = await Promise.all(
|
||||||
nodeEntities.map(async nodeEntity => {
|
nodeEntities.map(async (nodeEntity) => {
|
||||||
const nodeJSON = await document.toNodeJSON(nodeEntity);
|
const nodeJSON = await document.toNodeJSON(nodeEntity);
|
||||||
return {
|
return {
|
||||||
nodeJSON,
|
nodeJSON,
|
||||||
nodeType: nodeEntity.flowNodeType,
|
nodeType: nodeEntity.flowNodeType,
|
||||||
};
|
};
|
||||||
}),
|
})
|
||||||
);
|
);
|
||||||
navigator.clipboard
|
navigator.clipboard
|
||||||
.writeText(
|
.writeText(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
nodes,
|
nodes,
|
||||||
fromHost: window.location.host,
|
fromHost: window.location.host,
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
Toast.success({
|
Toast.success({
|
||||||
content: 'Nodes copied',
|
content: 'Nodes copied',
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch((err) => {
|
||||||
Toast.error({
|
Toast.error({
|
||||||
content: 'Failed to copy nodes',
|
content: 'Failed to copy nodes',
|
||||||
});
|
});
|
||||||
@ -86,16 +86,16 @@ export function shortcuts(shortcutsRegistry: ShortcutsRegistry, ctx: FreeLayoutP
|
|||||||
|
|
||||||
if (selectedNodes && Array.isArray(selectedNodes)) {
|
if (selectedNodes && Array.isArray(selectedNodes)) {
|
||||||
const newNodes = await Promise.all(
|
const newNodes = await Promise.all(
|
||||||
selectedNodes.map(async node => {
|
selectedNodes.map(async (node) => {
|
||||||
const nodeJSON = await document.toNodeJSON(node);
|
const nodeJSON = await document.toNodeJSON(node);
|
||||||
return document.copyNodeFromJSON(
|
return document.copyNodeFromJSON(
|
||||||
nodeJSON.type as string,
|
nodeJSON.type as string,
|
||||||
nodeJSON,
|
nodeJSON,
|
||||||
'',
|
'',
|
||||||
nodeJSON.meta?.position,
|
nodeJSON.meta?.position,
|
||||||
node.parent?.id,
|
node.parent?.id
|
||||||
);
|
);
|
||||||
}),
|
})
|
||||||
);
|
);
|
||||||
return newNodes;
|
return newNodes;
|
||||||
}
|
}
|
||||||
@ -137,7 +137,7 @@ export function shortcuts(shortcutsRegistry: ShortcutsRegistry, ctx: FreeLayoutP
|
|||||||
? dragService.adjustSubNodePosition(
|
? dragService.adjustSubNodePosition(
|
||||||
nodeJSON.type as string,
|
nodeJSON.type as string,
|
||||||
containerNode,
|
containerNode,
|
||||||
nodeJSON.meta?.position,
|
nodeJSON.meta?.position
|
||||||
)
|
)
|
||||||
: nodeJSON.meta?.position;
|
: nodeJSON.meta?.position;
|
||||||
return document.copyNodeFromJSON(
|
return document.copyNodeFromJSON(
|
||||||
@ -145,9 +145,9 @@ export function shortcuts(shortcutsRegistry: ShortcutsRegistry, ctx: FreeLayoutP
|
|||||||
nodeJSON,
|
nodeJSON,
|
||||||
'',
|
'',
|
||||||
position,
|
position,
|
||||||
containerNode?.id,
|
containerNode?.id
|
||||||
);
|
);
|
||||||
}),
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
if (nodes.length > 0) {
|
if (nodes.length > 0) {
|
||||||
@ -171,10 +171,10 @@ export function shortcuts(shortcutsRegistry: ShortcutsRegistry, ctx: FreeLayoutP
|
|||||||
const selection = ctx.selection;
|
const selection = ctx.selection;
|
||||||
|
|
||||||
const selectNodes = selection.selection.filter(
|
const selectNodes = selection.selection.filter(
|
||||||
_entity => _entity instanceof FlowNodeEntity,
|
(_entity) => _entity instanceof FlowNodeEntity
|
||||||
) as FlowNodeEntity[];
|
) as FlowNodeEntity[];
|
||||||
|
|
||||||
selectNodes.forEach(node => {
|
selectNodes.forEach((node) => {
|
||||||
node.renderData.expanded = false;
|
node.renderData.expanded = false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -191,10 +191,10 @@ export function shortcuts(shortcutsRegistry: ShortcutsRegistry, ctx: FreeLayoutP
|
|||||||
const selection = ctx.selection;
|
const selection = ctx.selection;
|
||||||
|
|
||||||
const selectNodes = selection.selection.filter(
|
const selectNodes = selection.selection.filter(
|
||||||
_entity => _entity instanceof FlowNodeEntity,
|
(_entity) => _entity instanceof FlowNodeEntity
|
||||||
) as FlowNodeEntity[];
|
) as FlowNodeEntity[];
|
||||||
|
|
||||||
selectNodes.forEach(node => {
|
selectNodes.forEach((node) => {
|
||||||
node.renderData.expanded = true;
|
node.renderData.expanded = true;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
@ -7,4 +7,9 @@ module.exports = defineConfig({
|
|||||||
'no-console': 'off',
|
'no-console': 'off',
|
||||||
'react/prop-types': 'off',
|
'react/prop-types': 'off',
|
||||||
},
|
},
|
||||||
|
settings: {
|
||||||
|
react: {
|
||||||
|
version: 'detect', // 自动检测 React 版本
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -251,6 +251,14 @@
|
|||||||
"enableParallelism": true,
|
"enableParallelism": true,
|
||||||
"safeForSimultaneousRushProcesses": true
|
"safeForSimultaneousRushProcesses": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "lint:fix",
|
||||||
|
"commandKind": "bulk",
|
||||||
|
"summary": "⭐️️ Run eslint fix in packages",
|
||||||
|
"ignoreMissingScript": true,
|
||||||
|
"enableParallelism": true,
|
||||||
|
"safeForSimultaneousRushProcesses": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "dev:demo-fixed-layout",
|
"name": "dev:demo-fixed-layout",
|
||||||
"commandKind": "global",
|
"commandKind": "global",
|
||||||
|
|||||||
3
common/config/rush/pnpm-lock.yaml
generated
3
common/config/rush/pnpm-lock.yaml
generated
@ -524,6 +524,9 @@ importers:
|
|||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^18
|
specifier: ^18
|
||||||
version: 18.19.68
|
version: 18.19.68
|
||||||
|
react:
|
||||||
|
specifier: ^18
|
||||||
|
version: 18.3.1
|
||||||
typescript:
|
typescript:
|
||||||
specifier: ^5.0.4
|
specifier: ^5.0.4
|
||||||
version: 5.0.4
|
version: 5.0.4
|
||||||
|
|||||||
@ -7,4 +7,9 @@ const { defineConfig } = require(path.resolve(__dirname, main));
|
|||||||
module.exports = defineConfig({
|
module.exports = defineConfig({
|
||||||
packageRoot: __dirname,
|
packageRoot: __dirname,
|
||||||
preset: 'node',
|
preset: 'node',
|
||||||
|
settings: {
|
||||||
|
react: {
|
||||||
|
version: 'detect', // 自动检测 React 版本
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -8,7 +8,6 @@
|
|||||||
"build": "tsc -b --force",
|
"build": "tsc -b --force",
|
||||||
"dev": "npm run build -- -w",
|
"dev": "npm run build -- -w",
|
||||||
"lint": "eslint ./src --cache",
|
"lint": "eslint ./src --cache",
|
||||||
"lint:fix": "eslint --fix ../../packages",
|
|
||||||
"test": "exit",
|
"test": "exit",
|
||||||
"test:cov": "exit"
|
"test:cov": "exit"
|
||||||
},
|
},
|
||||||
@ -38,6 +37,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@flowgram.ai/ts-config": "workspace:*",
|
"@flowgram.ai/ts-config": "workspace:*",
|
||||||
"@types/node": "^18",
|
"@types/node": "^18",
|
||||||
|
"react": "^18",
|
||||||
"typescript": "^5.0.4"
|
"typescript": "^5.0.4"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user