mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-26 17:16:52 +08:00
### What problem does this PR solve? Feat: Set the return value of the webhook to a string. #10427 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
@ -2006,28 +2006,28 @@ Important structured information may include: names, dates, locations, events, k
|
|||||||
schema: 'Schema',
|
schema: 'Schema',
|
||||||
response: 'Response',
|
response: 'Response',
|
||||||
executionMode: 'Execution mode',
|
executionMode: 'Execution mode',
|
||||||
authMethods: 'Authentication Methods',
|
authMethods: 'Authentication methods',
|
||||||
authType: 'Authentication Type',
|
authType: 'Authentication type',
|
||||||
limit: 'Request Limit',
|
limit: 'Request limit',
|
||||||
per: 'Time Period',
|
per: 'Time period',
|
||||||
maxBodySize: 'Maximum Body Size',
|
maxBodySize: 'Maximum body size',
|
||||||
ipWhitelist: 'IP Whitelist',
|
ipWhitelist: 'Ip whitelist',
|
||||||
tokenHeader: 'Token Header',
|
tokenHeader: 'Token header',
|
||||||
tokenValue: 'Token Value',
|
tokenValue: 'Token value',
|
||||||
username: 'Username',
|
username: 'Username',
|
||||||
password: 'Password',
|
password: 'Password',
|
||||||
algorithm: 'Algorithm',
|
algorithm: 'Algorithm',
|
||||||
secret: 'Secret',
|
secret: 'Secret',
|
||||||
issuer: 'Issuer',
|
issuer: 'Issuer',
|
||||||
audience: 'Audience',
|
audience: 'Audience',
|
||||||
requiredClaims: 'Required Claims',
|
requiredClaims: 'Required claims',
|
||||||
header: 'Header',
|
header: 'Header',
|
||||||
status: 'Status',
|
status: 'Status',
|
||||||
headersTemplate: 'Headers Template',
|
headersTemplate: 'Headers template',
|
||||||
bodyTemplate: 'Body Template',
|
bodyTemplate: 'Body template',
|
||||||
basic: 'Basic',
|
basic: 'Basic',
|
||||||
bearer: 'Bearer',
|
bearer: 'Bearer',
|
||||||
apiKey: 'Api Key',
|
apiKey: 'Api key',
|
||||||
queryParameters: 'Query parameters',
|
queryParameters: 'Query parameters',
|
||||||
headerParameters: 'Header parameters',
|
headerParameters: 'Header parameters',
|
||||||
requestBodyParameters: 'Request body parameters',
|
requestBodyParameters: 'Request body parameters',
|
||||||
|
|||||||
@ -1037,3 +1037,9 @@ export enum WebhookRequestParameters {
|
|||||||
Number = TypesWithArray.Number,
|
Number = TypesWithArray.Number,
|
||||||
Boolean = TypesWithArray.Boolean,
|
Boolean = TypesWithArray.Boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum WebhookStatus {
|
||||||
|
Testing = 'testing',
|
||||||
|
Live = 'live',
|
||||||
|
Stopped = 'stopped',
|
||||||
|
}
|
||||||
|
|||||||
@ -83,7 +83,7 @@ function BeginForm({ node }: INextOperatorForm) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="px-5 space-y-5">
|
<section className="px-5 space-y-5 pb-4">
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
|
|||||||
@ -69,10 +69,10 @@ export const BeginFormSchema = z.object({
|
|||||||
response: z
|
response: z
|
||||||
.object({
|
.object({
|
||||||
status: z.number(),
|
status: z.number(),
|
||||||
headers_template: z.array(
|
// headers_template: z.array(
|
||||||
z.object({ key: z.string(), value: z.string() }),
|
// z.object({ key: z.string(), value: z.string() }),
|
||||||
),
|
// ),
|
||||||
body_template: z.array(z.object({ key: z.string(), value: z.string() })),
|
body_template: z.string().optional(),
|
||||||
})
|
})
|
||||||
.optional(),
|
.optional(),
|
||||||
execution_mode: z.string().optional(),
|
execution_mode: z.string().optional(),
|
||||||
|
|||||||
@ -15,7 +15,9 @@ const initialFormValuesMap = {
|
|||||||
schema: {},
|
schema: {},
|
||||||
'security.auth_type': WebhookSecurityAuthType.Basic,
|
'security.auth_type': WebhookSecurityAuthType.Basic,
|
||||||
'security.rate_limit.per': RateLimitPerList[0],
|
'security.rate_limit.per': RateLimitPerList[0],
|
||||||
|
'security.rate_limit.limit': 10,
|
||||||
'security.max_body_size': WebhookMaxBodySize[0],
|
'security.max_body_size': WebhookMaxBodySize[0],
|
||||||
|
'response.status': 200,
|
||||||
execution_mode: WebhookExecutionMode.Immediately,
|
execution_mode: WebhookExecutionMode.Immediately,
|
||||||
content_types: WebhookContentType.ApplicationJson,
|
content_types: WebhookContentType.ApplicationJson,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -9,8 +9,12 @@ import { loader } from '@monaco-editor/react';
|
|||||||
import { omit } from 'lodash';
|
import { omit } from 'lodash';
|
||||||
import { X } from 'lucide-react';
|
import { X } from 'lucide-react';
|
||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
import { useFieldArray, useFormContext } from 'react-hook-form';
|
import { useFieldArray, useFormContext, useWatch } from 'react-hook-form';
|
||||||
import { TypesWithArray, WebhookRequestParameters } from '../../../constant';
|
import {
|
||||||
|
TypesWithArray,
|
||||||
|
WebhookContentType,
|
||||||
|
WebhookRequestParameters,
|
||||||
|
} from '../../../constant';
|
||||||
import { DynamicFormHeader } from '../../components/dynamic-fom-header';
|
import { DynamicFormHeader } from '../../components/dynamic-fom-header';
|
||||||
|
|
||||||
loader.config({ paths: { vs: '/vs' } });
|
loader.config({ paths: { vs: '/vs' } });
|
||||||
@ -44,6 +48,12 @@ export function DynamicRequest({
|
|||||||
isObject = false,
|
isObject = false,
|
||||||
}: SelectKeysProps) {
|
}: SelectKeysProps) {
|
||||||
const form = useFormContext();
|
const form = useFormContext();
|
||||||
|
const contentType = useWatch({
|
||||||
|
name: 'content_types',
|
||||||
|
control: form.control,
|
||||||
|
});
|
||||||
|
const isFormDataContentType =
|
||||||
|
contentType === WebhookContentType.MultipartFormData;
|
||||||
|
|
||||||
const { fields, remove, append } = useFieldArray({
|
const { fields, remove, append } = useFieldArray({
|
||||||
name: name,
|
name: name,
|
||||||
@ -84,7 +94,9 @@ export function DynamicRequest({
|
|||||||
onChange={(val) => {
|
onChange={(val) => {
|
||||||
field.onChange(val);
|
field.onChange(val);
|
||||||
}}
|
}}
|
||||||
options={buildParametersOptions(isObject)}
|
options={buildParametersOptions(
|
||||||
|
isObject && isFormDataContentType,
|
||||||
|
)}
|
||||||
></SelectWithSearch>
|
></SelectWithSearch>
|
||||||
)}
|
)}
|
||||||
</RAGFlowFormItem>
|
</RAGFlowFormItem>
|
||||||
|
|||||||
@ -11,13 +11,9 @@ import { Editor, loader } from '@monaco-editor/react';
|
|||||||
import { X } from 'lucide-react';
|
import { X } from 'lucide-react';
|
||||||
import { ReactNode, useCallback } from 'react';
|
import { ReactNode, useCallback } from 'react';
|
||||||
import { useFieldArray, useFormContext } from 'react-hook-form';
|
import { useFieldArray, useFormContext } from 'react-hook-form';
|
||||||
import { InputMode, TypesWithArray } from '../../../constant';
|
import { TypesWithArray } from '../../../constant';
|
||||||
import {
|
import { buildConversationVariableSelectOptions } from '../../../utils';
|
||||||
InputModeOptions,
|
|
||||||
buildConversationVariableSelectOptions,
|
|
||||||
} from '../../../utils';
|
|
||||||
import { DynamicFormHeader } from '../../components/dynamic-fom-header';
|
import { DynamicFormHeader } from '../../components/dynamic-fom-header';
|
||||||
import { QueryVariable } from '../../components/query-variable';
|
|
||||||
|
|
||||||
loader.config({ paths: { vs: '/vs' } });
|
loader.config({ paths: { vs: '/vs' } });
|
||||||
|
|
||||||
@ -33,8 +29,6 @@ type SelectKeysProps = {
|
|||||||
|
|
||||||
const VariableTypeOptions = buildConversationVariableSelectOptions();
|
const VariableTypeOptions = buildConversationVariableSelectOptions();
|
||||||
|
|
||||||
const modeField = 'input_mode';
|
|
||||||
|
|
||||||
const ConstantValueMap = {
|
const ConstantValueMap = {
|
||||||
[TypesWithArray.Boolean]: true,
|
[TypesWithArray.Boolean]: true,
|
||||||
[TypesWithArray.Number]: 0,
|
[TypesWithArray.Number]: 0,
|
||||||
@ -63,71 +57,46 @@ export function DynamicResponse({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const initializeValue = useCallback(
|
const initializeValue = useCallback(
|
||||||
(mode: string, variableType: string, valueFieldAlias: string) => {
|
(variableType: string, valueFieldAlias: string) => {
|
||||||
if (mode === InputMode.Variable) {
|
const val = ConstantValueMap[variableType as TypesWithArray];
|
||||||
form.setValue(valueFieldAlias, '', { shouldDirty: true });
|
form.setValue(valueFieldAlias, val, { shouldDirty: true });
|
||||||
} else {
|
|
||||||
const val = ConstantValueMap[variableType as TypesWithArray];
|
|
||||||
form.setValue(valueFieldAlias, val, { shouldDirty: true });
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
[form],
|
[form],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleModeChange = useCallback(
|
|
||||||
(mode: string, valueFieldAlias: string, operatorFieldAlias: string) => {
|
|
||||||
const variableType = form.getValues(operatorFieldAlias);
|
|
||||||
initializeValue(mode, variableType, valueFieldAlias);
|
|
||||||
},
|
|
||||||
[form, initializeValue],
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleVariableTypeChange = useCallback(
|
const handleVariableTypeChange = useCallback(
|
||||||
(variableType: string, valueFieldAlias: string, modeFieldAlias: string) => {
|
(variableType: string, valueFieldAlias: string) => {
|
||||||
const mode = form.getValues(modeFieldAlias);
|
initializeValue(variableType, valueFieldAlias);
|
||||||
|
|
||||||
initializeValue(mode, variableType, valueFieldAlias);
|
|
||||||
},
|
},
|
||||||
[form, initializeValue],
|
[initializeValue],
|
||||||
);
|
);
|
||||||
|
|
||||||
const renderParameter = useCallback(
|
const renderParameter = useCallback(
|
||||||
(operatorFieldName: string, modeFieldName: string) => {
|
(operatorFieldName: string) => {
|
||||||
const mode = form.getValues(modeFieldName);
|
|
||||||
const logicalOperator = form.getValues(operatorFieldName);
|
const logicalOperator = form.getValues(operatorFieldName);
|
||||||
|
|
||||||
if (mode === InputMode.Constant) {
|
if (logicalOperator === TypesWithArray.Boolean) {
|
||||||
if (logicalOperator === TypesWithArray.Boolean) {
|
return <BoolSegmented></BoolSegmented>;
|
||||||
return <BoolSegmented></BoolSegmented>;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (logicalOperator === TypesWithArray.Number) {
|
if (logicalOperator === TypesWithArray.Number) {
|
||||||
return <Input className="w-full" type="number"></Input>;
|
return <Input className="w-full" type="number"></Input>;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (logicalOperator === TypesWithArray.String) {
|
if (logicalOperator === TypesWithArray.String) {
|
||||||
return <Textarea></Textarea>;
|
return <Textarea></Textarea>;
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Editor
|
|
||||||
height={300}
|
|
||||||
theme={isDarkTheme ? 'vs-dark' : 'vs'}
|
|
||||||
language={'json'}
|
|
||||||
options={{
|
|
||||||
minimap: { enabled: false },
|
|
||||||
automaticLayout: true,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<QueryVariable
|
<Editor
|
||||||
types={[logicalOperator]}
|
height={300}
|
||||||
hideLabel
|
theme={isDarkTheme ? 'vs-dark' : 'vs'}
|
||||||
pureQuery
|
language={'json'}
|
||||||
></QueryVariable>
|
options={{
|
||||||
|
minimap: { enabled: false },
|
||||||
|
automaticLayout: true,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
[form, isDarkTheme],
|
[form, isDarkTheme],
|
||||||
@ -142,7 +111,6 @@ export function DynamicResponse({
|
|||||||
append({
|
append({
|
||||||
[keyField]: '',
|
[keyField]: '',
|
||||||
[valueField]: '',
|
[valueField]: '',
|
||||||
[modeField]: InputMode.Constant,
|
|
||||||
[operatorField]: TypesWithArray.String,
|
[operatorField]: TypesWithArray.String,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -152,7 +120,6 @@ export function DynamicResponse({
|
|||||||
const keyFieldAlias = `${name}.${index}.${keyField}`;
|
const keyFieldAlias = `${name}.${index}.${keyField}`;
|
||||||
const valueFieldAlias = `${name}.${index}.${valueField}`;
|
const valueFieldAlias = `${name}.${index}.${valueField}`;
|
||||||
const operatorFieldAlias = `${name}.${index}.${operatorField}`;
|
const operatorFieldAlias = `${name}.${index}.${operatorField}`;
|
||||||
const modeFieldAlias = `${name}.${index}.${modeField}`;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section key={field.id} className="flex gap-2">
|
<section key={field.id} className="flex gap-2">
|
||||||
@ -167,11 +134,7 @@ export function DynamicResponse({
|
|||||||
<SelectWithSearch
|
<SelectWithSearch
|
||||||
value={field.value}
|
value={field.value}
|
||||||
onChange={(val) => {
|
onChange={(val) => {
|
||||||
handleVariableTypeChange(
|
handleVariableTypeChange(val, valueFieldAlias);
|
||||||
val,
|
|
||||||
valueFieldAlias,
|
|
||||||
modeFieldAlias,
|
|
||||||
);
|
|
||||||
field.onChange(val);
|
field.onChange(val);
|
||||||
}}
|
}}
|
||||||
options={VariableTypeOptions}
|
options={VariableTypeOptions}
|
||||||
@ -179,25 +142,9 @@ export function DynamicResponse({
|
|||||||
)}
|
)}
|
||||||
</RAGFlowFormItem>
|
</RAGFlowFormItem>
|
||||||
<Separator className="w-2" />
|
<Separator className="w-2" />
|
||||||
<RAGFlowFormItem name={modeFieldAlias} className="flex-1">
|
|
||||||
{(field) => (
|
|
||||||
<SelectWithSearch
|
|
||||||
value={field.value}
|
|
||||||
onChange={(val) => {
|
|
||||||
handleModeChange(
|
|
||||||
val,
|
|
||||||
valueFieldAlias,
|
|
||||||
operatorFieldAlias,
|
|
||||||
);
|
|
||||||
field.onChange(val);
|
|
||||||
}}
|
|
||||||
options={InputModeOptions}
|
|
||||||
></SelectWithSearch>
|
|
||||||
)}
|
|
||||||
</RAGFlowFormItem>
|
|
||||||
</div>
|
</div>
|
||||||
<RAGFlowFormItem name={valueFieldAlias} className="w-full">
|
<RAGFlowFormItem name={valueFieldAlias} className="w-full">
|
||||||
{renderParameter(operatorFieldAlias, modeFieldAlias)}
|
{renderParameter(operatorFieldAlias)}
|
||||||
</RAGFlowFormItem>
|
</RAGFlowFormItem>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -1,16 +1,15 @@
|
|||||||
import { Collapse } from '@/components/collapse';
|
import { Collapse } from '@/components/collapse';
|
||||||
|
import CopyToClipboard from '@/components/copy-to-clipboard';
|
||||||
import { SelectWithSearch } from '@/components/originui/select-with-search';
|
import { SelectWithSearch } from '@/components/originui/select-with-search';
|
||||||
import { RAGFlowFormItem } from '@/components/ragflow-form';
|
import { RAGFlowFormItem } from '@/components/ragflow-form';
|
||||||
import { Input } from '@/components/ui/input';
|
import { Input } from '@/components/ui/input';
|
||||||
import { MultiSelect } from '@/components/ui/multi-select';
|
import { MultiSelect } from '@/components/ui/multi-select';
|
||||||
import { Textarea } from '@/components/ui/textarea';
|
import { Textarea } from '@/components/ui/textarea';
|
||||||
import { buildOptions } from '@/utils/form';
|
import { buildOptions } from '@/utils/form';
|
||||||
import { useFormContext, useWatch } from 'react-hook-form';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { useParams } from 'umi';
|
||||||
import {
|
import {
|
||||||
RateLimitPerList,
|
RateLimitPerList,
|
||||||
WebhookContentType,
|
|
||||||
WebhookExecutionMode,
|
|
||||||
WebhookMaxBodySize,
|
WebhookMaxBodySize,
|
||||||
WebhookMethod,
|
WebhookMethod,
|
||||||
WebhookSecurityAuthType,
|
WebhookSecurityAuthType,
|
||||||
@ -24,15 +23,16 @@ const RateLimitPerOptions = buildOptions(RateLimitPerList);
|
|||||||
|
|
||||||
export function WebHook() {
|
export function WebHook() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const form = useFormContext();
|
const { id } = useParams();
|
||||||
|
|
||||||
const executionMode = useWatch({
|
const text = `${location.protocol}//${location.host}/api/v1/webhook/${id}`;
|
||||||
control: form.control,
|
|
||||||
name: 'execution_mode',
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<div className="bg-bg-card p-1 rounded-md flex gap-2">
|
||||||
|
<span className="flex-1 truncate">{text}</span>
|
||||||
|
<CopyToClipboard text={text}></CopyToClipboard>
|
||||||
|
</div>
|
||||||
<RAGFlowFormItem name="methods" label={t('flow.webhook.methods')}>
|
<RAGFlowFormItem name="methods" label={t('flow.webhook.methods')}>
|
||||||
{(field) => (
|
{(field) => (
|
||||||
<MultiSelect
|
<MultiSelect
|
||||||
@ -45,14 +45,7 @@ export function WebHook() {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</RAGFlowFormItem>
|
</RAGFlowFormItem>
|
||||||
<RAGFlowFormItem
|
|
||||||
name="content_types"
|
|
||||||
label={t('flow.webhook.contentTypes')}
|
|
||||||
>
|
|
||||||
<SelectWithSearch
|
|
||||||
options={buildOptions(WebhookContentType)}
|
|
||||||
></SelectWithSearch>
|
|
||||||
</RAGFlowFormItem>
|
|
||||||
<Collapse title={<div>Security</div>}>
|
<Collapse title={<div>Security</div>}>
|
||||||
<section className="space-y-4">
|
<section className="space-y-4">
|
||||||
<RAGFlowFormItem
|
<RAGFlowFormItem
|
||||||
@ -98,17 +91,8 @@ export function WebHook() {
|
|||||||
>
|
>
|
||||||
<Textarea></Textarea>
|
<Textarea></Textarea>
|
||||||
</RAGFlowFormItem>
|
</RAGFlowFormItem>
|
||||||
<RAGFlowFormItem
|
|
||||||
name="execution_mode"
|
<WebhookResponse></WebhookResponse>
|
||||||
label={t('flow.webhook.executionMode')}
|
|
||||||
>
|
|
||||||
<SelectWithSearch
|
|
||||||
options={buildOptions(WebhookExecutionMode)}
|
|
||||||
></SelectWithSearch>
|
|
||||||
</RAGFlowFormItem>
|
|
||||||
{executionMode === WebhookExecutionMode.Immediately && (
|
|
||||||
<WebhookResponse></WebhookResponse>
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,8 @@
|
|||||||
import { Collapse } from '@/components/collapse';
|
import { Collapse } from '@/components/collapse';
|
||||||
|
import { SelectWithSearch } from '@/components/originui/select-with-search';
|
||||||
|
import { RAGFlowFormItem } from '@/components/ragflow-form';
|
||||||
|
import { WebhookContentType } from '@/pages/agent/constant';
|
||||||
|
import { buildOptions } from '@/utils/form';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { DynamicRequest } from './dynamic-request';
|
import { DynamicRequest } from './dynamic-request';
|
||||||
|
|
||||||
@ -8,6 +12,14 @@ export function WebhookRequestSchema() {
|
|||||||
return (
|
return (
|
||||||
<Collapse title={<div>{t('flow.webhook.schema')}</div>}>
|
<Collapse title={<div>{t('flow.webhook.schema')}</div>}>
|
||||||
<section className="space-y-4">
|
<section className="space-y-4">
|
||||||
|
<RAGFlowFormItem
|
||||||
|
name="content_types"
|
||||||
|
label={t('flow.webhook.contentTypes')}
|
||||||
|
>
|
||||||
|
<SelectWithSearch
|
||||||
|
options={buildOptions(WebhookContentType)}
|
||||||
|
></SelectWithSearch>
|
||||||
|
</RAGFlowFormItem>
|
||||||
<DynamicRequest
|
<DynamicRequest
|
||||||
name="schema.query"
|
name="schema.query"
|
||||||
label={t('flow.webhook.queryParameters')}
|
label={t('flow.webhook.queryParameters')}
|
||||||
|
|||||||
@ -1,29 +1,58 @@
|
|||||||
import { Collapse } from '@/components/collapse';
|
import { Collapse } from '@/components/collapse';
|
||||||
|
import { SelectWithSearch } from '@/components/originui/select-with-search';
|
||||||
import { RAGFlowFormItem } from '@/components/ragflow-form';
|
import { RAGFlowFormItem } from '@/components/ragflow-form';
|
||||||
import { Input } from '@/components/ui/input';
|
import { Input } from '@/components/ui/input';
|
||||||
|
import { Textarea } from '@/components/ui/textarea';
|
||||||
|
import { WebhookExecutionMode } from '@/pages/agent/constant';
|
||||||
|
import { buildOptions } from '@/utils/form';
|
||||||
|
import { useFormContext, useWatch } from 'react-hook-form';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { DynamicResponse } from './dynamic-response';
|
|
||||||
|
|
||||||
export function WebhookResponse() {
|
export function WebhookResponse() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const form = useFormContext();
|
||||||
|
|
||||||
|
const executionMode = useWatch({
|
||||||
|
control: form.control,
|
||||||
|
name: 'execution_mode',
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Collapse title={<div>Response</div>}>
|
<Collapse title={<div>Response</div>}>
|
||||||
<section className="space-y-4">
|
<section className="space-y-4">
|
||||||
<RAGFlowFormItem
|
<RAGFlowFormItem
|
||||||
name={'response.status'}
|
name="execution_mode"
|
||||||
label={t('flow.webhook.status')}
|
label={t('flow.webhook.executionMode')}
|
||||||
>
|
>
|
||||||
<Input type="number"></Input>
|
<SelectWithSearch
|
||||||
|
options={buildOptions(WebhookExecutionMode)}
|
||||||
|
></SelectWithSearch>
|
||||||
</RAGFlowFormItem>
|
</RAGFlowFormItem>
|
||||||
<DynamicResponse
|
{executionMode === WebhookExecutionMode.Immediately && (
|
||||||
name="response.headers_template"
|
<>
|
||||||
label={t('flow.webhook.headersTemplate')}
|
<RAGFlowFormItem
|
||||||
></DynamicResponse>
|
name={'response.status'}
|
||||||
<DynamicResponse
|
label={t('flow.webhook.status')}
|
||||||
name="response.body_template"
|
>
|
||||||
label={t('flow.webhook.bodyTemplate')}
|
<Input type="number"></Input>
|
||||||
></DynamicResponse>
|
</RAGFlowFormItem>
|
||||||
|
{/* <DynamicResponse
|
||||||
|
name="response.headers_template"
|
||||||
|
label={t('flow.webhook.headersTemplate')}
|
||||||
|
></DynamicResponse> */}
|
||||||
|
{/* <DynamicResponse
|
||||||
|
name="response.body_template"
|
||||||
|
label={t('flow.webhook.bodyTemplate')}
|
||||||
|
></DynamicResponse> */}
|
||||||
|
<RAGFlowFormItem
|
||||||
|
name="response.body_template"
|
||||||
|
label={t('flow.webhook.bodyTemplate')}
|
||||||
|
>
|
||||||
|
<Textarea></Textarea>
|
||||||
|
</RAGFlowFormItem>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</section>
|
</section>
|
||||||
</Collapse>
|
</Collapse>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -355,13 +355,6 @@ function transformBeginParams(params: BeginFormSchemaType) {
|
|||||||
...params.security,
|
...params.security,
|
||||||
ip_whitelist: params.security?.ip_whitelist.map((x) => x.value),
|
ip_whitelist: params.security?.ip_whitelist.map((x) => x.value),
|
||||||
},
|
},
|
||||||
response: {
|
|
||||||
...params.response,
|
|
||||||
headers_template: transformArrayToObject(
|
|
||||||
params.response?.headers_template,
|
|
||||||
),
|
|
||||||
body_template: transformArrayToObject(params.response?.body_template),
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user