Compare commits

...

6 Commits

Author SHA1 Message Date
archer 5cc5506a39
rewrite editor 2025-11-04 22:32:38 +08:00
archer 140b392ae2
Editor breakline 2025-11-04 21:58:27 +08:00
archer 57b26c0992
fix: editor 2025-11-04 21:40:50 +08:00
archer 819206b525
fix: prompt editor 2025-11-04 18:43:22 +08:00
archer cc094f9d2e
fix: workflow start check 2025-10-21 11:58:34 +08:00
archer d475c2a93d
fix: variables refresh 2025-10-21 11:58:33 +08:00
2 changed files with 106 additions and 30 deletions

View File

@ -42,28 +42,11 @@ export type TextEditorNode = BaseEditorNode & {
export type LineBreakEditorNode = BaseEditorNode & {
type: 'linebreak';
};
export type VariableLabelEditorNode = BaseEditorNode & {
type: 'variableLabel';
variableKey: string;
};
export type VariableEditorNode = BaseEditorNode & {
type: 'Variable';
variableKey: string;
};
export type TabEditorNode = BaseEditorNode & {
type: 'tab';
};
export type ChildEditorNode =
| TextEditorNode
| LineBreakEditorNode
| VariableLabelEditorNode
| VariableEditorNode
| TabEditorNode;
// Rich text
export type ParagraphEditorNode = BaseEditorNode & {
type: 'paragraph';
children: ChildEditorNode[];
@ -72,15 +55,33 @@ export type ParagraphEditorNode = BaseEditorNode & {
indent: number;
};
// ListItem 节点的 children 可以包含嵌套的 list 节点
export type ListItemChildEditorNode =
| TextEditorNode
| LineBreakEditorNode
| TabEditorNode
| VariableLabelEditorNode
| VariableEditorNode;
export type ListItemEditorNode = BaseEditorNode & {
type: 'listitem';
children: Array<ChildEditorNode | ListEditorNode>;
children: (ListItemChildEditorNode | ListEditorNode)[];
direction: string | null;
format: string;
indent: number;
value: number;
};
// Custom variable node types
export type VariableLabelEditorNode = BaseEditorNode & {
type: 'variableLabel';
variableKey: string;
};
export type VariableEditorNode = BaseEditorNode & {
type: 'Variable';
variableKey: string;
};
export type ListEditorNode = BaseEditorNode & {
type: 'list';
children: ListItemEditorNode[];
@ -92,10 +93,20 @@ export type ListEditorNode = BaseEditorNode & {
tag: 'ul' | 'ol';
};
export type ChildEditorNode =
| TextEditorNode
| LineBreakEditorNode
| TabEditorNode
| ParagraphEditorNode
| ListEditorNode
| ListItemEditorNode
| VariableLabelEditorNode
| VariableEditorNode;
export type EditorState = {
root: {
type: 'root';
children: Array<ParagraphEditorNode | ListEditorNode>;
children: ChildEditorNode[];
direction: string;
format: string;
indent: number;

View File

@ -17,7 +17,8 @@ import type {
ListEditorNode,
ParagraphEditorNode,
EditorState,
ListItemInfo
ListItemInfo,
ChildEditorNode
} from './type';
export function registerLexicalTextEntity<T extends TextNode | VariableLabelNode | VariableNode>(
@ -472,6 +473,74 @@ export const editorStateToText = (editor: LexicalEditor) => {
const editorState = editor.getEditorState().toJSON() as EditorState;
const paragraphs = editorState.root.children;
const extractText = (node: ChildEditorNode): string => {
if (!node) return '';
// Handle line break nodes
if (node.type === 'linebreak') {
return '\n';
}
// Handle tab nodes
if (node.type === 'tab') {
return ' ';
}
// Handle text nodes
if (node.type === 'text') {
return node.text || '';
}
// Handle custom variable nodes
if (node.type === 'variableLabel' || node.type === 'Variable') {
return node.variableKey || '';
}
// Handle paragraph nodes - recursively process children
if (node.type === 'paragraph') {
if (!node.children || node.children.length === 0) {
return '';
}
return node.children.map(extractText).join('');
}
// Handle list item nodes - recursively process children (excluding nested lists)
if (node.type === 'listitem') {
if (!node.children || node.children.length === 0) {
return '';
}
// Filter out nested list nodes as they are handled separately
return node.children
.filter((child) => child.type !== 'list')
.map(extractText)
.join('');
}
// Handle list nodes - recursively process children
if (node.type === 'list') {
if (!node.children || node.children.length === 0) {
return '';
}
return node.children.map(extractText).join('');
}
// Unknown node type - return the raw text content if available
console.warn('Unknown node type in extractText:', (node as any).type, node);
// Try to extract text content from unknown node types
if ('text' in node && typeof (node as any).text === 'string') {
return (node as any).text;
}
// Try to recursively extract from children if present
if ('children' in node && Array.isArray((node as any).children)) {
return (node as any).children.map(extractText).join('');
}
// Fallback to stringifying the node content
return JSON.stringify(node);
};
paragraphs.forEach((paragraph) => {
if (paragraph.type === 'list') {
const listResults = processList({ list: paragraph });
@ -483,19 +552,15 @@ export const editorStateToText = (editor: LexicalEditor) => {
const indentSpaces = ' '.repeat(paragraph.indent || 0);
children.forEach((child) => {
if (child.type === 'linebreak') {
paragraphText.push('\n');
} else if (child.type === 'text') {
paragraphText.push(child.text);
} else if (child.type === 'tab') {
paragraphText.push(' ');
} else if (child.type === 'variableLabel' || child.type === 'Variable') {
paragraphText.push(child.variableKey);
}
const val = extractText(child);
paragraphText.push(val);
});
const finalText = paragraphText.join('');
editorStateTextString.push(indentSpaces + finalText);
} else {
const text = extractText(paragraph);
editorStateTextString.push(text);
}
});
return editorStateTextString.join('\n');