mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-26 17:16:52 +08:00
### What problem does this PR solve? Fix: Optimized variable node display and Agent template multi-language support #3221 - Modified the VariableNode component to add parent label and icon properties - Updated the VariablePickerMenuPlugin to support displaying parent labels and icons - Adjusted useBuildNodeOutputOptions and useBuildBeginVariableOptions to pass new properties - Optimized the Agent TemplateCard component to switch the title and description based on the language ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
@ -10,7 +10,6 @@ import { HeadingNode, QuoteNode } from '@lexical/rich-text';
|
||||
import {
|
||||
$getRoot,
|
||||
$getSelection,
|
||||
$nodesOfType,
|
||||
EditorState,
|
||||
Klass,
|
||||
LexicalNode,
|
||||
@ -135,9 +134,8 @@ export function PromptEditor({
|
||||
const onValueChange = useCallback(
|
||||
(editorState: EditorState) => {
|
||||
editorState?.read(() => {
|
||||
const listNodes = $nodesOfType(VariableNode); // to be removed
|
||||
// const listNodes = $nodesOfType(VariableNode); // to be removed
|
||||
// const allNodes = $dfs();
|
||||
console.log('🚀 ~ onChange ~ allNodes:', listNodes);
|
||||
|
||||
const text = $getRoot().getTextContent();
|
||||
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import i18n from '@/locales/config';
|
||||
import { BeginId } from '@/pages/flow/constant';
|
||||
import { DecoratorNode, LexicalNode, NodeKey } from 'lexical';
|
||||
import { ReactNode } from 'react';
|
||||
@ -7,19 +6,36 @@ const prefix = BeginId + '@';
|
||||
export class VariableNode extends DecoratorNode<ReactNode> {
|
||||
__value: string;
|
||||
__label: string;
|
||||
key?: NodeKey;
|
||||
__parentLabel?: string | ReactNode;
|
||||
__icon?: ReactNode;
|
||||
|
||||
static getType(): string {
|
||||
return 'variable';
|
||||
}
|
||||
|
||||
static clone(node: VariableNode): VariableNode {
|
||||
return new VariableNode(node.__value, node.__label, node.__key);
|
||||
return new VariableNode(
|
||||
node.__value,
|
||||
node.__label,
|
||||
node.__key,
|
||||
node.__parentLabel,
|
||||
node.__icon,
|
||||
);
|
||||
}
|
||||
|
||||
constructor(value: string, label: string, key?: NodeKey) {
|
||||
constructor(
|
||||
value: string,
|
||||
label: string,
|
||||
key?: NodeKey,
|
||||
parent?: string | ReactNode,
|
||||
icon?: ReactNode,
|
||||
) {
|
||||
super(key);
|
||||
this.__value = value;
|
||||
this.__label = label;
|
||||
this.__parentLabel = parent;
|
||||
this.__icon = icon;
|
||||
}
|
||||
|
||||
createDOM(): HTMLElement {
|
||||
@ -35,17 +51,20 @@ export class VariableNode extends DecoratorNode<ReactNode> {
|
||||
|
||||
decorate(): ReactNode {
|
||||
let content: ReactNode = (
|
||||
<span className="text-blue-600">{this.__label}</span>
|
||||
<div className="text-blue-600">{this.__label}</div>
|
||||
);
|
||||
if (this.__value?.startsWith(prefix)) {
|
||||
if (this.__parentLabel) {
|
||||
content = (
|
||||
<div>
|
||||
<span>{i18n.t(`flow.begin`)}</span> / {content}
|
||||
<div className="flex items-center gap-1 text-text-primary ">
|
||||
<div>{this.__icon}</div>
|
||||
<div>{this.__parentLabel}</div>
|
||||
<div className="text-text-disabled mr-1">/</div>
|
||||
{content}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div className="bg-gray-200 dark:bg-gray-400 text-primary inline-flex items-center rounded-md px-2 py-0">
|
||||
<div className="bg-gray-200 dark:bg-gray-400 text-sm inline-flex items-center rounded-md px-2 py-1">
|
||||
{content}
|
||||
</div>
|
||||
);
|
||||
@ -59,8 +78,10 @@ export class VariableNode extends DecoratorNode<ReactNode> {
|
||||
export function $createVariableNode(
|
||||
value: string,
|
||||
label: string,
|
||||
parentLabel: string | ReactNode,
|
||||
icon?: ReactNode,
|
||||
): VariableNode {
|
||||
return new VariableNode(value, label);
|
||||
return new VariableNode(value, label, undefined, parentLabel, icon);
|
||||
}
|
||||
|
||||
export function $isVariableNode(
|
||||
|
||||
@ -20,7 +20,13 @@ import {
|
||||
$isRangeSelection,
|
||||
TextNode,
|
||||
} from 'lexical';
|
||||
import React, { ReactElement, useCallback, useEffect, useRef } from 'react';
|
||||
import React, {
|
||||
ReactElement,
|
||||
ReactNode,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useRef,
|
||||
} from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
|
||||
import { $createVariableNode } from './variable-node';
|
||||
@ -31,11 +37,20 @@ import './index.css';
|
||||
class VariableInnerOption extends MenuOption {
|
||||
label: string;
|
||||
value: string;
|
||||
parentLabel: string | JSX.Element;
|
||||
icon?: ReactNode;
|
||||
|
||||
constructor(label: string, value: string) {
|
||||
constructor(
|
||||
label: string,
|
||||
value: string,
|
||||
parentLabel: string | JSX.Element,
|
||||
icon?: ReactNode,
|
||||
) {
|
||||
super(value);
|
||||
this.label = label;
|
||||
this.value = value;
|
||||
this.parentLabel = parentLabel;
|
||||
this.icon = icon;
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,7 +126,6 @@ export default function VariablePickerMenuPlugin({
|
||||
|
||||
const buildNextOptions = useCallback(() => {
|
||||
let filteredOptions = options;
|
||||
|
||||
if (queryString) {
|
||||
const lowerQuery = queryString.toLowerCase();
|
||||
filteredOptions = options
|
||||
@ -131,23 +145,28 @@ export default function VariablePickerMenuPlugin({
|
||||
new VariableOption(
|
||||
x.label,
|
||||
x.title,
|
||||
x.options.map((y) => new VariableInnerOption(y.label, y.value)),
|
||||
x.options.map((y) => {
|
||||
return new VariableInnerOption(y.label, y.value, x.label, y.icon);
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
return nextOptions;
|
||||
}, [options, queryString]);
|
||||
|
||||
const findLabelByValue = useCallback(
|
||||
const findItemByValue = useCallback(
|
||||
(value: string) => {
|
||||
const children = options.reduce<Array<{ label: string; value: string }>>(
|
||||
(pre, cur) => {
|
||||
return pre.concat(cur.options);
|
||||
},
|
||||
[],
|
||||
);
|
||||
const children = options.reduce<
|
||||
Array<{
|
||||
label: string;
|
||||
value: string;
|
||||
parentLabel?: string | ReactNode;
|
||||
icon?: ReactNode;
|
||||
}>
|
||||
>((pre, cur) => {
|
||||
return pre.concat(cur.options);
|
||||
}, []);
|
||||
|
||||
return children.find((x) => x.value === value)?.label;
|
||||
return children.find((x) => x.value === value);
|
||||
},
|
||||
[options],
|
||||
);
|
||||
@ -168,13 +187,13 @@ export default function VariablePickerMenuPlugin({
|
||||
if (nodeToRemove) {
|
||||
nodeToRemove.remove();
|
||||
}
|
||||
|
||||
selection.insertNodes([
|
||||
$createVariableNode(
|
||||
(selectedOption as VariableInnerOption).value,
|
||||
selectedOption.label as string,
|
||||
),
|
||||
]);
|
||||
const variableNode = $createVariableNode(
|
||||
(selectedOption as VariableInnerOption).value,
|
||||
selectedOption.label as string,
|
||||
selectedOption.parentLabel as string | ReactNode,
|
||||
selectedOption.icon as ReactNode,
|
||||
);
|
||||
selection.insertNodes([variableNode]);
|
||||
|
||||
closeMenu();
|
||||
});
|
||||
@ -190,7 +209,6 @@ export default function VariablePickerMenuPlugin({
|
||||
const regex = /{([^}]*)}/g;
|
||||
let match;
|
||||
let lastIndex = 0;
|
||||
|
||||
while ((match = regex.exec(text)) !== null) {
|
||||
const { 1: content, index, 0: template } = match;
|
||||
|
||||
@ -202,9 +220,17 @@ export default function VariablePickerMenuPlugin({
|
||||
}
|
||||
|
||||
// Add variable node or text node
|
||||
const label = findLabelByValue(content);
|
||||
if (label) {
|
||||
paragraph.append($createVariableNode(content, label));
|
||||
const nodeItem = findItemByValue(content);
|
||||
|
||||
if (nodeItem) {
|
||||
paragraph.append(
|
||||
$createVariableNode(
|
||||
content,
|
||||
nodeItem.label,
|
||||
nodeItem.parentLabel,
|
||||
nodeItem.icon,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
paragraph.append($createTextNode(template));
|
||||
}
|
||||
@ -225,7 +251,7 @@ export default function VariablePickerMenuPlugin({
|
||||
$getRoot().selectEnd();
|
||||
}
|
||||
},
|
||||
[findLabelByValue],
|
||||
[findItemByValue],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
Reference in New Issue
Block a user