Feat: Translate operator names and allow mailboxes to reference operator names #3221 (#9118)

### What problem does this PR solve?

Feat: Translate operator names and allow mailboxes to reference operator
names #3221

### Type of change


- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu
2025-07-30 16:16:47 +08:00
committed by GitHub
parent ffff5c2e8c
commit 840abd5239
9 changed files with 91 additions and 42 deletions

View File

@ -46,7 +46,7 @@ const Nodes: Array<Klass<LexicalNode>> = [
VariableNode,
];
type PromptContentProps = { showToolbar?: boolean };
type PromptContentProps = { showToolbar?: boolean; multiLine?: boolean };
type IProps = {
value?: string;
@ -54,7 +54,10 @@ type IProps = {
placeholder?: ReactNode;
} & PromptContentProps;
function PromptContent({ showToolbar = true }: PromptContentProps) {
function PromptContent({
showToolbar = true,
multiLine = true,
}: PromptContentProps) {
const [editor] = useLexicalComposerContext();
const [isBlur, setIsBlur] = useState(false);
const { t } = useTranslation();
@ -100,7 +103,9 @@ function PromptContent({ showToolbar = true }: PromptContentProps) {
</div>
)}
<ContentEditable
className="min-h-40 relative px-2 py-1 focus-visible:outline-none"
className={cn('relative px-2 py-1 focus-visible:outline-none', {
'min-h-40': multiLine,
})}
onBlur={handleBlur}
onFocus={handleFocus}
/>
@ -113,6 +118,7 @@ export function PromptEditor({
onChange,
placeholder,
showToolbar,
multiLine = true,
}: IProps) {
const { t } = useTranslation();
const initialConfig: InitialConfigType = {
@ -142,14 +148,22 @@ export function PromptEditor({
<LexicalComposer initialConfig={initialConfig}>
<RichTextPlugin
contentEditable={
<PromptContent showToolbar={showToolbar}></PromptContent>
<PromptContent
showToolbar={showToolbar}
multiLine={multiLine}
></PromptContent>
}
placeholder={
<div
className="absolute top-10 left-2 text-text-sub-title"
className={cn(
'absolute top-1 left-2 text-text-sub-title pointer-events-none',
{
'truncate w-[90%]': !multiLine,
},
)}
data-xxx
>
{placeholder || t('common.pleaseInput')}
{placeholder || t('common.promptPlaceholder')}
</div>
}
ErrorBoundary={LexicalErrorBoundary}

View File

@ -20,6 +20,7 @@ import { INextOperatorForm } from '../../interface';
import { buildOutputList } from '../../utils/build-output-list';
import { FormWrapper } from '../components/form-wrapper';
import { Output } from '../components/output';
import { PromptEditor } from '../components/prompt-editor';
interface InputFormFieldProps {
name: string;
@ -47,6 +48,29 @@ function InputFormField({ name, label, type }: InputFormFieldProps) {
);
}
function PromptFormField({ name, label }: InputFormFieldProps) {
const form = useFormContext();
return (
<FormField
control={form.control}
name={name}
render={({ field }) => (
<FormItem>
<FormLabel>{label}</FormLabel>
<FormControl>
<PromptEditor
{...field}
showToolbar={false}
multiLine={false}
></PromptEditor>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
);
}
export function EmailFormWidgets() {
const { t } = useTranslate('flow');
@ -108,10 +132,22 @@ const EmailForm = ({ node }: INextOperatorForm) => {
<Form {...form}>
<FormWrapper>
<FormContainer>
<InputFormField name="to_email" label={t('toEmail')}></InputFormField>
<InputFormField name="cc_email" label={t('ccEmail')}></InputFormField>
<InputFormField name="content" label={t('content')}></InputFormField>
<InputFormField name="subject" label={t('subject')}></InputFormField>
<PromptFormField
name="to_email"
label={t('toEmail')}
></PromptFormField>
<PromptFormField
name="cc_email"
label={t('ccEmail')}
></PromptFormField>
<PromptFormField
name="content"
label={t('content')}
></PromptFormField>
<PromptFormField
name="subject"
label={t('subject')}
></PromptFormField>
<EmailFormWidgets></EmailFormWidgets>
</FormContainer>
</FormWrapper>

View File

@ -23,7 +23,9 @@ import { initialInvokeValues } from '../../constant';
import { useFormValues } from '../../hooks/use-form-values';
import { useWatchFormChange } from '../../hooks/use-watch-form-change';
import { INextOperatorForm } from '../../interface';
import { buildOutputList } from '../../utils/build-output-list';
import { FormWrapper } from '../components/form-wrapper';
import { Output } from '../components/output';
import { FormSchema, FormSchemaType } from './schema';
import { useEditVariableRecord } from './use-edit-variable';
import { VariableDialog } from './variable-dialog';
@ -56,6 +58,8 @@ const TimeoutInput = ({ value, onChange }: TimeoutInputProps) => {
);
};
const outputList = buildOutputList(initialInvokeValues.outputs);
function InvokeForm({ node }: INextOperatorForm) {
const { t } = useTranslation();
const defaultValues = useFormValues(initialInvokeValues, node);
@ -212,6 +216,9 @@ function InvokeForm({ node }: INextOperatorForm) {
></VariableDialog>
)}
</FormWrapper>
<div className="p-5">
<Output list={outputList}></Output>
</div>
</Form>
);
}