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