V4.8.17 feature (#3485)

* feat: add third party account config (#3443)

* temp

* editor workflow variable style

* add team to dispatch

* i18n

* delete console

* change openai account position

* fix

* fix

* fix

* fix

* fix

* 4.8.17 test (#3461)

* perf: external provider config

* perf: ui

* feat: add template config (#3434)

* change template position

* template config

* delete console

* delete

* fix

* fix

* perf: Mongo visutal field (#3464)

* remve invalid code

* perf: team member visutal code

* perf: virtual search; perf: search test data

* fix: ts

* fix: image response headers

* perf: template code

* perf: auth layout;perf: auto save (#3472)

* perf: auth layout

* perf: auto save

* perf: auto save

* fix: template guide display & http input support external variables (#3475)

* fix: template guide display

* http editor support external workflow variables

* perf: auto save;fix: ifelse checker line break; (#3478)

* perf: auto save

* perf: auto save

* fix: ifelse checker line break

* perf: doc

* perf: doc

* fix: update var type error

* 4.8.17 test (#3479)

* perf: auto save

* perf: auto save

* perf: template code

* 4.8.17 test (#3480)

* perf: auto save

* perf: auto save

* perf: model price model

* feat: add react memo

* perf: model provider filter

* fix: ts (#3481)

* perf: auto save

* perf: auto save

* fix: ts

* simple app tool select (#3473)

* workflow plugin userguide & simple tool ui

* simple tool filter

* reuse component

* change component to hook

* fix

* perf: too selector modal (#3484)

* perf: auto save

* perf: auto save

* perf: markdown render

* perf: too selector

* fix: app version require tmbId

* perf: templates refresh

* perf: templates refresh

* hide auto save error tip

* perf: toolkit guide

---------

Co-authored-by: heheer <heheer@sealos.io>
This commit is contained in:
Archer
2024-12-27 20:05:12 +08:00
committed by GitHub
parent a209856d48
commit b520988c64
207 changed files with 2943 additions and 1378 deletions

View File

@@ -20,31 +20,22 @@ export default function VariableLabel({
<Box
display="inline-flex"
alignItems="center"
m={'2px'}
mx={'2px'}
rounded={'4px'}
px={1.5}
py={'1px'}
bg={parentLabel !== 'undefined' ? 'primary.50' : 'red.50'}
color={parentLabel !== 'undefined' ? 'myGray.900' : 'red.600'}
transform={parentLabel !== 'undefined' ? 'translateY(3px)' : ''}
>
{parentLabel !== 'undefined' ? (
<Flex alignItems={'center'} color={'myGray.600'}>
<Avatar
src={nodeAvatar as any}
w={'1rem'}
mr={1}
borderRadius={'xs'}
display={'inline-flex'}
verticalAlign={'middle'}
/>
<Flex alignItems={'center'} color={'myGray.600'} fontSize={'sm'}>
<Avatar src={nodeAvatar as any} w={'1rem'} mr={1} borderRadius={'xs'} />
{parentLabel}
<ChevronRightIcon color={'myGray.500'} />
{childLabel}
</Flex>
) : (
<>
<Box>{t('common:invalid_variable')}</Box>
</>
<Box>{t('common:invalid_variable')}</Box>
)}
</Box>
</>

View File

@@ -0,0 +1,28 @@
import { Box, Flex } from '@chakra-ui/react';
import { useTranslation } from 'next-i18next';
export default function Variable({ variableLabel }: { variableLabel: string }) {
const { t } = useTranslation();
return (
<>
<Box
display="inline-flex"
alignItems="center"
mx={'2px'}
rounded={'4px'}
px={1.5}
py={'1px'}
{...(variableLabel
? { bg: 'primary.50', color: 'primary.600' }
: { bg: 'red.50', color: 'red.600' })}
>
{variableLabel ? (
<Flex alignItems={'center'}>{variableLabel}</Flex>
) : (
<Box>{t('common:invalid_variable')}</Box>
)}
</Box>
</>
);
}

View File

@@ -5,8 +5,8 @@ import { useCallback, useEffect, useMemo } from 'react';
import { getHashtagRegexString } from './utils';
import { registerLexicalTextEntity } from '../../utils';
import { $createVariableNode, VariableNode } from './node';
import { EditorVariablePickerType } from '../../type';
import { $createVariableNode, VariableNode } from './node';
const REGEX = new RegExp(getHashtagRegexString(), 'i');
@@ -22,7 +22,11 @@ export default function VariablePlugin({ variables }: { variables: EditorVariabl
}, [variables]);
const createVariableNode = useCallback((textNode: TextNode): VariableNode => {
return $createVariableNode(textNode.getTextContent());
const currentVariable = variables.find(
(item) => item.key === textNode.getTextContent().replace(/[{}]/g, '')
);
const variableLabel = currentVariable?.label;
return $createVariableNode(textNode.getTextContent(), variableLabel || '');
}, []);
const getVariableMatch = useCallback((text: string) => {

View File

@@ -1,49 +0,0 @@
import type { NodeKey, EditorConfig, LexicalNode, SerializedTextNode } from 'lexical';
import { TextNode, $applyNodeReplacement } from 'lexical';
import { addClassNamesToElement } from '@lexical/utils';
import styles from '../../index.module.scss';
export class VariableNode extends TextNode {
static getType(): string {
return 'variable';
}
static clone(node: VariableNode): VariableNode {
return new VariableNode(node.__text, node.__key);
}
constructor(text: string, key?: NodeKey) {
super(text, key);
}
createDOM(config: EditorConfig): HTMLElement {
const element = super.createDOM(config);
addClassNamesToElement(element, styles.variable);
return element;
}
static importJSON(serializedNode: SerializedTextNode): TextNode {
const node = $createVariableNode(serializedNode.text);
node.setFormat(serializedNode.format);
node.setDetail(serializedNode.detail);
node.setMode(serializedNode.mode);
node.setStyle(serializedNode.style);
return node;
}
exportJSON(): SerializedTextNode {
return {
...super.exportJSON(),
type: 'variable'
};
}
}
export function $createVariableNode(text: string): VariableNode {
return $applyNodeReplacement(new VariableNode(text));
}
export function $isVariableNode(node: LexicalNode | null | undefined): node is VariableNode {
return node instanceof VariableNode;
}

View File

@@ -0,0 +1,105 @@
import {
DecoratorNode,
DOMConversionMap,
DOMExportOutput,
EditorConfig,
LexicalEditor,
LexicalNode,
NodeKey,
SerializedLexicalNode,
Spread,
TextFormatType
} from 'lexical';
import Variable from './components/Variable';
export type SerializedVariableNode = Spread<
{
variableKey: string;
variableLabel: string;
format: number | TextFormatType;
},
SerializedLexicalNode
>;
export class VariableNode extends DecoratorNode<JSX.Element> {
__format: number | TextFormatType;
__variableKey: string;
__variableLabel: string;
static getType(): string {
return 'Variable';
}
static clone(node: VariableNode): VariableNode {
return new VariableNode(node.__variableKey, node.__variableLabel, node.__format, node.__key);
}
constructor(
variableKey: string,
variableLabel: string,
format?: number | TextFormatType,
key?: NodeKey
) {
super(key);
this.__variableKey = variableKey;
this.__format = format || 0;
this.__variableLabel = variableLabel;
}
static importJSON(serializedNode: SerializedVariableNode): VariableNode {
const node = $createVariableNode(serializedNode.variableKey, serializedNode.variableLabel);
node.setFormat(serializedNode.format);
return node;
}
setFormat(format: number | TextFormatType): void {
const self = this.getWritable();
self.__format = format;
}
getFormat(): number | TextFormatType {
return this.__format;
}
exportJSON(): SerializedVariableNode {
return {
format: this.__format || 0,
type: 'Variable',
version: 1,
variableKey: this.getVariableKey(),
variableLabel: this.__variableLabel
};
}
createDOM(): HTMLElement {
const element = document.createElement('span');
return element;
}
exportDOM(): DOMExportOutput {
const element = document.createElement('span');
return { element };
}
static importDOM(): DOMConversionMap | null {
return {};
}
updateDOM(): false {
return false;
}
getVariableKey(): string {
return this.__variableKey;
}
getTextContent(
_includeInert?: boolean | undefined,
_includeDirectionless?: false | undefined
): string {
return `${this.__variableKey}`;
}
decorate(_editor: LexicalEditor, config: EditorConfig): JSX.Element {
return <Variable variableLabel={this.__variableLabel} />;
}
}
export function $createVariableNode(variableKey: string, variableLabel: string): VariableNode {
return new VariableNode(variableKey, variableLabel);
}
export function $isVariableNode(
node: VariableNode | LexicalNode | null | undefined
): node is VariableNode {
return node instanceof VariableNode;
}

View File

@@ -11,8 +11,9 @@ import type { EntityMatch } from '@lexical/text';
import { $createTextNode, $getRoot, $isTextNode, TextNode } from 'lexical';
import { useCallback } from 'react';
import { VariableLabelNode } from './plugins/VariableLabelPlugin/node';
import { VariableNode } from './plugins/VariablePlugin/node';
export function registerLexicalTextEntity<T extends TextNode | VariableLabelNode>(
export function registerLexicalTextEntity<T extends TextNode | VariableLabelNode | VariableNode>(
editor: LexicalEditor,
getMatch: (text: string) => null | EntityMatch,
targetNode: Klass<T>,
@@ -22,7 +23,7 @@ export function registerLexicalTextEntity<T extends TextNode | VariableLabelNode
return node instanceof targetNode;
};
const replaceWithSimpleText = (node: TextNode | VariableLabelNode): void => {
const replaceWithSimpleText = (node: TextNode | VariableLabelNode | VariableNode): void => {
const textNode = $createTextNode(node.getTextContent());
textNode.setFormat(node.getFormat());
node.replace(textNode);
@@ -228,6 +229,8 @@ export function editorStateToText(editor: LexicalEditor) {
paragraphText.push(child.text);
} else if (child.type === 'variableLabel') {
paragraphText.push(child.variableKey);
} else if (child.type === 'Variable') {
paragraphText.push(child.variableKey);
}
});
editorStateTextString.push(paragraphText.join(''));