feat: manually mirror opencoze's code from bytedance
Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { nanoid } from 'nanoid';
|
||||
import { ValueExpressionType, ViewVariableType } from '@coze-workflow/variable';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { CONVERSATION_NAME } from '../constants';
|
||||
|
||||
export const FIELD_CONFIG = {
|
||||
conversationName: {
|
||||
description: I18n.t('wf_chatflow_24'),
|
||||
name: CONVERSATION_NAME,
|
||||
required: true,
|
||||
type: 'string',
|
||||
},
|
||||
};
|
||||
|
||||
export const DEFAULT_CONVERSATION_VALUE = [
|
||||
{
|
||||
name: CONVERSATION_NAME,
|
||||
input: {
|
||||
type: ValueExpressionType.REF,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export const DEFAULT_OUTPUTS = [
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'isSuccess',
|
||||
type: ViewVariableType.Boolean,
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
ValidateTrigger,
|
||||
type FormMetaV2,
|
||||
} from '@flowgram-adapter/free-layout-editor';
|
||||
import { type InputValueVO } from '@coze-workflow/base';
|
||||
|
||||
import { fireNodeTitleChange } from '@/nodes-v2/materials/fire-node-title-change';
|
||||
import { createValueExpressionInputValidate } from '@/nodes-v2/materials/create-value-expression-input-validate';
|
||||
|
||||
import { transformOnSubmit } from '../transform-on-submit';
|
||||
import { createTransformOnInit } from '../transform-on-init';
|
||||
import { syncConversationNameEffect } from '../sync-conversation-name-effect';
|
||||
import { provideNodeOutputVariablesEffect } from '../../materials/provide-node-output-variables';
|
||||
import FormRender from './form-render';
|
||||
import { DEFAULT_CONVERSATION_VALUE, DEFAULT_OUTPUTS } from './constants';
|
||||
|
||||
interface FormData {
|
||||
inputParameters: InputValueVO[];
|
||||
}
|
||||
|
||||
export const CLEAR_CONTEXT_FORM_META: FormMetaV2<FormData> = {
|
||||
// 节点表单渲染
|
||||
render: () => <FormRender />,
|
||||
|
||||
// 验证触发时机
|
||||
validateTrigger: ValidateTrigger.onChange,
|
||||
|
||||
// 验证规则
|
||||
validate: {
|
||||
// 必填
|
||||
'inputParameters.0.input': createValueExpressionInputValidate({
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
|
||||
// 副作用管理
|
||||
effect: {
|
||||
nodeMeta: fireNodeTitleChange,
|
||||
outputs: provideNodeOutputVariablesEffect,
|
||||
inputParameters: syncConversationNameEffect,
|
||||
},
|
||||
|
||||
// 节点后端数据 -> 前端表单数据
|
||||
formatOnInit: createTransformOnInit(
|
||||
DEFAULT_CONVERSATION_VALUE,
|
||||
DEFAULT_OUTPUTS,
|
||||
),
|
||||
|
||||
// 前端表单数据 -> 节点后端数据
|
||||
formatOnSubmit: transformOnSubmit,
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { useReadonly } from '@/nodes-v2/hooks/use-readonly';
|
||||
|
||||
import { createFormRender } from '../create-form-render';
|
||||
import {
|
||||
FIELD_CONFIG,
|
||||
DEFAULT_CONVERSATION_VALUE,
|
||||
DEFAULT_OUTPUTS,
|
||||
} from './constants';
|
||||
|
||||
const Render = () => {
|
||||
const readonly = useReadonly();
|
||||
|
||||
return createFormRender({
|
||||
defaultInputValue: DEFAULT_CONVERSATION_VALUE,
|
||||
defaultOutputValue: DEFAULT_OUTPUTS,
|
||||
fieldConfig: FIELD_CONFIG,
|
||||
readonly,
|
||||
inputTooltip: I18n.t('wf_chatflow_23'),
|
||||
outputTooltip: I18n.t('wf_chatflow_25'),
|
||||
});
|
||||
};
|
||||
|
||||
export default Render;
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** 清空会话历史节点 */
|
||||
|
||||
export { CLEAR_CONTEXT_NODE_REGISTRY } from './node-registry';
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { StandardNodeType } from '@coze-workflow/base';
|
||||
|
||||
import { createNodeRegistry } from '../create-node-registry';
|
||||
import { test } from './node-test';
|
||||
import { CLEAR_CONTEXT_FORM_META } from './form-meta';
|
||||
import { FIELD_CONFIG } from './constants';
|
||||
|
||||
export const CLEAR_CONTEXT_NODE_REGISTRY = createNodeRegistry(
|
||||
StandardNodeType.ClearContext,
|
||||
CLEAR_CONTEXT_FORM_META,
|
||||
FIELD_CONFIG,
|
||||
{ test },
|
||||
);
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { FlowNodeFormData } from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
import {
|
||||
generateParametersToProperties,
|
||||
generateEnvToRelatedContextProperties,
|
||||
} from '@/test-run-kit';
|
||||
import { type NodeTestMeta } from '@/test-run-kit';
|
||||
|
||||
export const test: NodeTestMeta = {
|
||||
generateRelatedContext(node, context) {
|
||||
const { isInProject } = context;
|
||||
if (isInProject) {
|
||||
return {};
|
||||
}
|
||||
return generateEnvToRelatedContextProperties({
|
||||
isNeedBot: true,
|
||||
});
|
||||
},
|
||||
generateFormInputProperties(node) {
|
||||
const formData = node
|
||||
.getData(FlowNodeFormData)
|
||||
.formModel.getFormItemValueByPath('/');
|
||||
return generateParametersToProperties(formData?.inputParameters, { node });
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
export const CONVERSATION_NAME = 'conversationName';
|
||||
|
||||
export const PARAMS_COLUMNS = [
|
||||
{
|
||||
title: I18n.t('workflow_detail_node_parameter_name'),
|
||||
style: { width: 180 },
|
||||
},
|
||||
{
|
||||
title: I18n.t('workflow_detail_node_parameter_value'),
|
||||
style: { flex: '1' },
|
||||
},
|
||||
];
|
||||
|
||||
export const INPUT_COLUMNS_NARROW = [
|
||||
{
|
||||
title: I18n.t('workflow_detail_node_parameter_name'),
|
||||
style: { width: 140 },
|
||||
},
|
||||
{
|
||||
title: I18n.t('workflow_detail_node_parameter_value'),
|
||||
style: { flex: '1' },
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { nanoid } from 'nanoid';
|
||||
import { ValueExpressionType, ViewVariableType } from '@coze-workflow/variable';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { CONVERSATION_NAME } from '../constants';
|
||||
|
||||
export const FIELD_CONFIG = {
|
||||
conversationName: {
|
||||
description: I18n.t('wf_chatflow_14'),
|
||||
name: CONVERSATION_NAME,
|
||||
required: true,
|
||||
type: 'string',
|
||||
},
|
||||
};
|
||||
|
||||
export const DEFAULT_CONVERSATION_VALUE = [
|
||||
{
|
||||
name: CONVERSATION_NAME,
|
||||
input: {
|
||||
type: ValueExpressionType.REF,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export const DEFAULT_OUTPUTS = [
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'isSuccess',
|
||||
type: ViewVariableType.Boolean,
|
||||
},
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'isExisted',
|
||||
type: ViewVariableType.Boolean,
|
||||
},
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'conversationId',
|
||||
type: ViewVariableType.String,
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
ValidateTrigger,
|
||||
type FormMetaV2,
|
||||
} from '@flowgram-adapter/free-layout-editor';
|
||||
import { type InputValueVO } from '@coze-workflow/base';
|
||||
|
||||
import { fireNodeTitleChange } from '@/nodes-v2/materials/fire-node-title-change';
|
||||
import { createValueExpressionInputValidate } from '@/nodes-v2/materials/create-value-expression-input-validate';
|
||||
|
||||
import { transformOnSubmit } from '../transform-on-submit';
|
||||
import { createTransformOnInit } from '../transform-on-init';
|
||||
import { provideNodeOutputVariablesEffect } from '../../materials/provide-node-output-variables';
|
||||
import FormRender from './form-render';
|
||||
import { DEFAULT_CONVERSATION_VALUE, DEFAULT_OUTPUTS } from './constants';
|
||||
|
||||
interface FormData {
|
||||
inputParameters: InputValueVO[];
|
||||
}
|
||||
|
||||
export const CREATE_CONVERSATION_FORM_META: FormMetaV2<FormData> = {
|
||||
// 节点表单渲染
|
||||
render: () => <FormRender />,
|
||||
|
||||
// 验证触发时机
|
||||
validateTrigger: ValidateTrigger.onChange,
|
||||
|
||||
// 验证规则
|
||||
validate: {
|
||||
// 必填
|
||||
'inputParameters.0.input': createValueExpressionInputValidate({
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
|
||||
// 副作用管理
|
||||
effect: {
|
||||
nodeMeta: fireNodeTitleChange,
|
||||
outputs: provideNodeOutputVariablesEffect,
|
||||
},
|
||||
|
||||
// 节点后端数据 -> 前端表单数据
|
||||
formatOnInit: createTransformOnInit(
|
||||
DEFAULT_CONVERSATION_VALUE,
|
||||
DEFAULT_OUTPUTS,
|
||||
),
|
||||
|
||||
// 前端表单数据 -> 节点后端数据
|
||||
formatOnSubmit: transformOnSubmit,
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { useReadonly } from '@/nodes-v2/hooks/use-readonly';
|
||||
|
||||
import { createFormRender } from '../create-form-render';
|
||||
import {
|
||||
FIELD_CONFIG,
|
||||
DEFAULT_CONVERSATION_VALUE,
|
||||
DEFAULT_OUTPUTS,
|
||||
} from './constants';
|
||||
|
||||
const Render = () => {
|
||||
const readonly = useReadonly();
|
||||
|
||||
return createFormRender({
|
||||
defaultInputValue: DEFAULT_CONVERSATION_VALUE,
|
||||
defaultOutputValue: DEFAULT_OUTPUTS,
|
||||
fieldConfig: FIELD_CONFIG,
|
||||
readonly,
|
||||
inputTooltip: I18n.t('wf_chatflow_13'),
|
||||
outputTooltip: I18n.t('wf_chatflow_15'),
|
||||
});
|
||||
};
|
||||
|
||||
export default Render;
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** 创建会话节点 */
|
||||
|
||||
export { CREATE_CONVERSATION_NODE_REGISTRY } from './node-registry';
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { StandardNodeType } from '@coze-workflow/base';
|
||||
|
||||
import { createNodeRegistry } from '../create-node-registry';
|
||||
import { test } from './node-test';
|
||||
import { CREATE_CONVERSATION_FORM_META } from './form-meta';
|
||||
import { FIELD_CONFIG } from './constants';
|
||||
|
||||
export const CREATE_CONVERSATION_NODE_REGISTRY = createNodeRegistry(
|
||||
StandardNodeType.CreateConversation,
|
||||
CREATE_CONVERSATION_FORM_META,
|
||||
FIELD_CONFIG,
|
||||
{ test },
|
||||
);
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { FlowNodeFormData } from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
import {
|
||||
generateParametersToProperties,
|
||||
generateEnvToRelatedContextProperties,
|
||||
} from '@/test-run-kit';
|
||||
import { type NodeTestMeta } from '@/test-run-kit';
|
||||
|
||||
export const test: NodeTestMeta = {
|
||||
generateRelatedContext(node, context) {
|
||||
const { isInProject } = context;
|
||||
if (isInProject) {
|
||||
return {};
|
||||
}
|
||||
return generateEnvToRelatedContextProperties({
|
||||
isNeedBot: true,
|
||||
hasConversationNode: true,
|
||||
disableBot: true,
|
||||
disableBotTooltip: I18n.t('wf_chatflow_141'),
|
||||
});
|
||||
},
|
||||
generateFormInputProperties(node) {
|
||||
const formData = node
|
||||
.getData(FlowNodeFormData)
|
||||
.formModel.getFormItemValueByPath('/');
|
||||
return generateParametersToProperties(formData?.inputParameters, { node });
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import {
|
||||
ValidateTrigger,
|
||||
type FormMetaV2,
|
||||
} from '@flowgram-adapter/free-layout-editor';
|
||||
import { type InputValueVO } from '@coze-workflow/base';
|
||||
|
||||
import { fireNodeTitleChange } from '@/nodes-v2/materials/fire-node-title-change';
|
||||
import { createValueExpressionInputValidate } from '@/nodes-v2/materials/create-value-expression-input-validate';
|
||||
|
||||
import { provideNodeOutputVariablesEffect } from '../materials/provide-node-output-variables';
|
||||
import { transformOnSubmit } from './transform-on-submit';
|
||||
import { createTransformOnInit } from './transform-on-init';
|
||||
import { syncConversationNameEffect } from './sync-conversation-name-effect';
|
||||
|
||||
interface ChatFormData {
|
||||
inputParameters: InputValueVO[];
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export const createFormMeta = ({
|
||||
fieldConfig,
|
||||
needSyncConversationName,
|
||||
defaultInputValue,
|
||||
defaultOutputValue,
|
||||
formRenderComponent,
|
||||
customValidators = {},
|
||||
}): FormMetaV2<ChatFormData> => {
|
||||
// 定义首字母大写的变量引用组件
|
||||
const FormRender = formRenderComponent;
|
||||
|
||||
const formMeta = {
|
||||
// 节点表单渲染
|
||||
render: () => <FormRender />,
|
||||
|
||||
// 验证触发时机
|
||||
validateTrigger: ValidateTrigger.onChange,
|
||||
|
||||
// 验证规则
|
||||
validate: {
|
||||
// 必填
|
||||
'inputParameters.*.input': createValueExpressionInputValidate({
|
||||
required: ({ name }) => {
|
||||
const fieldName = name
|
||||
.replace('inputParameters.', '')
|
||||
.replace('.input', '');
|
||||
|
||||
return Boolean(fieldConfig[fieldName]?.required);
|
||||
},
|
||||
}),
|
||||
...customValidators,
|
||||
},
|
||||
|
||||
// 副作用管理
|
||||
effect: {
|
||||
nodeMeta: fireNodeTitleChange,
|
||||
outputs: provideNodeOutputVariablesEffect,
|
||||
},
|
||||
|
||||
// 节点后端数据 -> 前端表单数据
|
||||
formatOnInit: createTransformOnInit(defaultInputValue, defaultOutputValue),
|
||||
|
||||
// 前端表单数据 -> 节点后端数据
|
||||
formatOnSubmit: transformOnSubmit,
|
||||
};
|
||||
|
||||
// 需要同步联动 CONVERSATION_NAME 字段的值
|
||||
if (needSyncConversationName) {
|
||||
Object.assign(formMeta.effect, {
|
||||
inputParameters: syncConversationNameEffect,
|
||||
});
|
||||
}
|
||||
|
||||
return formMeta;
|
||||
};
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Field } from '@flowgram-adapter/free-layout-editor';
|
||||
import { PublicScopeProvider } from '@coze-workflow/variable';
|
||||
import {
|
||||
type InputValueVO,
|
||||
type ViewVariableTreeNode,
|
||||
} from '@coze-workflow/base';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { Outputs } from '@/nodes-v2/components/outputs';
|
||||
|
||||
import NodeMeta from '../components/node-meta';
|
||||
import FixedInputParameters from '../components/fixed-input-parameters';
|
||||
import { INPUT_COLUMNS_NARROW } from './constants';
|
||||
export interface FormRenderProps {
|
||||
defaultInputValue: InputValueVO[] | undefined;
|
||||
defaultOutputValue: ViewVariableTreeNode[] | undefined;
|
||||
fieldConfig: Record<
|
||||
string,
|
||||
{
|
||||
description: string;
|
||||
name: string;
|
||||
required: boolean;
|
||||
type: string;
|
||||
optionsList?: {
|
||||
label: string;
|
||||
value: string;
|
||||
}[];
|
||||
}
|
||||
>;
|
||||
readonly: boolean;
|
||||
inputTooltip: string;
|
||||
outputTooltip: string;
|
||||
hasInputs?: boolean;
|
||||
}
|
||||
|
||||
export const createFormRender = ({
|
||||
defaultInputValue,
|
||||
defaultOutputValue,
|
||||
fieldConfig,
|
||||
readonly,
|
||||
inputTooltip = '',
|
||||
outputTooltip = '',
|
||||
hasInputs = true,
|
||||
}: FormRenderProps) => (
|
||||
<PublicScopeProvider>
|
||||
<>
|
||||
<NodeMeta fieldName="nodeMeta" />
|
||||
|
||||
{hasInputs ? (
|
||||
<FixedInputParameters
|
||||
fieldName="inputParameters"
|
||||
defaultValue={defaultInputValue}
|
||||
headerTitle={I18n.t('workflow_detail_node_parameter_input')}
|
||||
headerTootip={inputTooltip}
|
||||
columns={INPUT_COLUMNS_NARROW}
|
||||
fieldConfig={fieldConfig}
|
||||
readonly={readonly}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
<Field name="outputs" defaultValue={defaultOutputValue}>
|
||||
{({ field, fieldState }) => (
|
||||
<Outputs
|
||||
id={'create-conversation-node-output'}
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
titleTooltip={outputTooltip}
|
||||
readonly
|
||||
needErrorBody={false}
|
||||
errors={fieldState?.errors}
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
</>
|
||||
</PublicScopeProvider>
|
||||
);
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { nanoid } from 'nanoid';
|
||||
import { ValueExpressionType, ViewVariableType } from '@coze-workflow/variable';
|
||||
import { type InputValueVO, VariableTypeDTO } from '@coze-workflow/base';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { CONVERSATION_NAME } from '../constants';
|
||||
|
||||
export const FIELD_CONFIG = {
|
||||
conversationName: {
|
||||
description: I18n.t('workflow_250407_005'),
|
||||
name: CONVERSATION_NAME,
|
||||
required: true,
|
||||
type: VariableTypeDTO.string,
|
||||
},
|
||||
|
||||
role: {
|
||||
description: I18n.t('workflow_250407_006'),
|
||||
name: 'role',
|
||||
required: true,
|
||||
type: VariableTypeDTO.string,
|
||||
|
||||
// 选项默认值
|
||||
defaultValue: 'user',
|
||||
|
||||
// 选项列表
|
||||
optionsList: [
|
||||
{ label: 'user', value: 'user' },
|
||||
{ label: 'assistant', value: 'assistant' },
|
||||
],
|
||||
},
|
||||
|
||||
content: {
|
||||
description: I18n.t('workflow_250407_007'),
|
||||
name: 'content',
|
||||
required: true,
|
||||
type: VariableTypeDTO.string,
|
||||
},
|
||||
};
|
||||
|
||||
export const DEFAULT_CONVERSATION_VALUE: InputValueVO[] = Object.keys(
|
||||
FIELD_CONFIG,
|
||||
).map(fieldName => {
|
||||
// 针对 role 字段,需要设置字面量默认值
|
||||
if (fieldName === 'role') {
|
||||
return {
|
||||
name: fieldName,
|
||||
input: {
|
||||
type: ValueExpressionType.LITERAL,
|
||||
content: FIELD_CONFIG[fieldName].defaultValue,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
name: fieldName,
|
||||
input: {
|
||||
type: ValueExpressionType.REF,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
export const DEFAULT_OUTPUTS = [
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'isSuccess',
|
||||
type: ViewVariableType.Boolean,
|
||||
},
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'message',
|
||||
type: ViewVariableType.Object,
|
||||
children: [
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'messageId',
|
||||
type: ViewVariableType.String,
|
||||
},
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'role',
|
||||
type: ViewVariableType.String,
|
||||
},
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'contentType',
|
||||
type: ViewVariableType.String,
|
||||
},
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'content',
|
||||
type: ViewVariableType.String,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type FormMetaV2 } from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
import { createFormMeta } from '../create-form-meta';
|
||||
import FormRender from './form-render';
|
||||
import {
|
||||
DEFAULT_CONVERSATION_VALUE,
|
||||
DEFAULT_OUTPUTS,
|
||||
FIELD_CONFIG,
|
||||
} from './constants';
|
||||
|
||||
export const FORM_META: FormMetaV2 = createFormMeta({
|
||||
fieldConfig: FIELD_CONFIG,
|
||||
needSyncConversationName: true,
|
||||
defaultInputValue: DEFAULT_CONVERSATION_VALUE,
|
||||
defaultOutputValue: DEFAULT_OUTPUTS,
|
||||
formRenderComponent: FormRender,
|
||||
});
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { useReadonly } from '@/nodes-v2/hooks/use-readonly';
|
||||
|
||||
import { createFormRender } from '../create-form-render';
|
||||
import {
|
||||
FIELD_CONFIG,
|
||||
DEFAULT_CONVERSATION_VALUE,
|
||||
DEFAULT_OUTPUTS,
|
||||
} from './constants';
|
||||
|
||||
const Render = () => {
|
||||
const readonly = useReadonly();
|
||||
|
||||
return createFormRender({
|
||||
defaultInputValue: DEFAULT_CONVERSATION_VALUE,
|
||||
defaultOutputValue: DEFAULT_OUTPUTS,
|
||||
fieldConfig: FIELD_CONFIG,
|
||||
readonly,
|
||||
inputTooltip: I18n.t('Input'),
|
||||
outputTooltip: I18n.t('Output'),
|
||||
});
|
||||
};
|
||||
|
||||
export default Render;
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** 创建消息节点 */
|
||||
|
||||
export { CREATE_MESSAGE_NODE_REGISTRY } from './node-registry';
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { StandardNodeType } from '@coze-workflow/base';
|
||||
|
||||
import { createNodeRegistry } from '../create-node-registry';
|
||||
import { test } from './node-test';
|
||||
import { FORM_META } from './form-meta';
|
||||
import { FIELD_CONFIG } from './constants';
|
||||
|
||||
export const CREATE_MESSAGE_NODE_REGISTRY = createNodeRegistry(
|
||||
StandardNodeType.CreateMessage,
|
||||
FORM_META,
|
||||
FIELD_CONFIG,
|
||||
{ test },
|
||||
);
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { FlowNodeFormData } from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
import {
|
||||
generateParametersToProperties,
|
||||
generateEnvToRelatedContextProperties,
|
||||
} from '@/test-run-kit';
|
||||
import { type NodeTestMeta } from '@/test-run-kit';
|
||||
|
||||
export const test: NodeTestMeta = {
|
||||
generateRelatedContext(node, context) {
|
||||
const { isInProject } = context;
|
||||
if (isInProject) {
|
||||
return {};
|
||||
}
|
||||
return generateEnvToRelatedContextProperties({
|
||||
isNeedBot: true,
|
||||
});
|
||||
},
|
||||
generateFormInputProperties(node) {
|
||||
const formData = node
|
||||
.getData(FlowNodeFormData)
|
||||
.formModel.getFormItemValueByPath('/');
|
||||
return generateParametersToProperties(formData?.inputParameters, { node });
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { get, set } from 'lodash-es';
|
||||
import { type WorkflowNodeFormMeta } from '@flowgram-adapter/free-layout-editor';
|
||||
import { variableUtils } from '@coze-workflow/variable';
|
||||
import {
|
||||
DEFAULT_NODE_META_PATH,
|
||||
DEFAULT_NODE_SIZE,
|
||||
type WorkflowNodeRegistry,
|
||||
} from '@coze-workflow/nodes';
|
||||
import {
|
||||
StandardNodeType,
|
||||
ValueExpression,
|
||||
type VariableTypeDTO,
|
||||
ViewVariableType,
|
||||
type NodeMeta,
|
||||
type InputValueDTO,
|
||||
type RefExpressionContent,
|
||||
} from '@coze-workflow/base';
|
||||
const NODE_WIDTH = DEFAULT_NODE_SIZE.width;
|
||||
const NODE_HEIGHT = 113;
|
||||
const INPUT_PATH = '/inputParameters';
|
||||
|
||||
const helpLinkMap = {
|
||||
[StandardNodeType.ClearContext]:
|
||||
'/open/docs/guides/clear_conversation_history',
|
||||
[StandardNodeType.CreateConversation]:
|
||||
'/open/docs/guides/create_conversation',
|
||||
[StandardNodeType.QueryMessageList]: '/open/docs/guides/query_message_list',
|
||||
[StandardNodeType.UpdateConversation]: '/open/docs/guides/edit_conversation',
|
||||
[StandardNodeType.DeleteConversation]:
|
||||
'/open/docs/guides/delete_conversation',
|
||||
[StandardNodeType.QueryConversationList]:
|
||||
'/open/docs/guides/query_conversation_list',
|
||||
[StandardNodeType.QueryConversationHistory]:
|
||||
'/open/docs/guides/query_conversation_history',
|
||||
[StandardNodeType.CreateMessage]: '/open/docs/guides/create_message',
|
||||
[StandardNodeType.UpdateMessage]: '/open/docs/guides/edit_message',
|
||||
[StandardNodeType.DeleteMessage]: '/open/docs/guides/delete_message',
|
||||
};
|
||||
|
||||
export const createNodeRegistry = (
|
||||
nodeType: StandardNodeType,
|
||||
formMeta: WorkflowNodeFormMeta,
|
||||
fieldConfig: Record<
|
||||
string,
|
||||
{
|
||||
description: string;
|
||||
name: string;
|
||||
required: boolean;
|
||||
type: string;
|
||||
}
|
||||
>,
|
||||
nodeMeta?: Partial<NodeMeta>,
|
||||
// eslint-disable-next-line max-params
|
||||
): WorkflowNodeRegistry => ({
|
||||
type: nodeType,
|
||||
meta: {
|
||||
nodeDTOType: nodeType,
|
||||
style: {
|
||||
width: NODE_WIDTH,
|
||||
},
|
||||
size: { width: NODE_WIDTH, height: NODE_HEIGHT },
|
||||
nodeMetaPath: DEFAULT_NODE_META_PATH,
|
||||
inputParametersPath: INPUT_PATH, // 入参路径,试运行等功能依赖该路径提取参数
|
||||
getInputVariableTag(name, input, extra) {
|
||||
const field = fieldConfig[name || ''];
|
||||
|
||||
let invalid = false;
|
||||
|
||||
if (field?.required) {
|
||||
const content = input?.content as RefExpressionContent;
|
||||
const isRef = content?.keyPath?.length > 0;
|
||||
|
||||
// 初始化流程时,可能变量模块还没有初始化,这里会获取不到变量...
|
||||
const variable = extra?.variableService.getWorkflowVariableByKeyPath(
|
||||
content?.keyPath,
|
||||
{ node: extra?.node, checkScope: true },
|
||||
);
|
||||
|
||||
// 必填场景,如果:
|
||||
// 1. 为空,报错
|
||||
// 2. 不为空
|
||||
// 2.1 引用变量,且变量不存在,报错
|
||||
invalid = ValueExpression.isEmpty(input) || (isRef && !variable);
|
||||
}
|
||||
|
||||
return {
|
||||
label: name,
|
||||
type: field?.type
|
||||
? variableUtils.DTOTypeToViewType(field.type as VariableTypeDTO)
|
||||
: ViewVariableType.String,
|
||||
invalid,
|
||||
};
|
||||
},
|
||||
helpLink: helpLinkMap[nodeType],
|
||||
...nodeMeta,
|
||||
},
|
||||
beforeNodeSubmit: nodeData => {
|
||||
const inputParameters = get(
|
||||
nodeData,
|
||||
'data.inputs.inputParameters',
|
||||
[],
|
||||
) as InputValueDTO[];
|
||||
|
||||
// 对于固定参数类型,需要将 type 字段设置为预定义的类型,而不是右侧填入的变量类型
|
||||
inputParameters.forEach(param => {
|
||||
const config = fieldConfig[param.name || ''];
|
||||
if (config && param.input.type) {
|
||||
set(param, 'input.type', config.type);
|
||||
}
|
||||
});
|
||||
|
||||
return nodeData;
|
||||
},
|
||||
formMeta,
|
||||
});
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { nanoid } from 'nanoid';
|
||||
import { ValueExpressionType, ViewVariableType } from '@coze-workflow/variable';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { CONVERSATION_NAME } from '../constants';
|
||||
|
||||
export const FIELD_CONFIG = {
|
||||
conversationName: {
|
||||
description: I18n.t('workflow_250407_023'),
|
||||
name: CONVERSATION_NAME,
|
||||
required: true,
|
||||
type: 'string',
|
||||
},
|
||||
};
|
||||
|
||||
export const DEFAULT_CONVERSATION_VALUE = Object.keys(FIELD_CONFIG).map(
|
||||
fieldName => ({
|
||||
name: fieldName,
|
||||
input: {
|
||||
type: ValueExpressionType.REF,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
export const DEFAULT_OUTPUTS = [
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'isSuccess',
|
||||
type: ViewVariableType.Boolean,
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type FormMetaV2 } from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
import { createFormMeta } from '../create-form-meta';
|
||||
import FormRender from './form-render';
|
||||
import {
|
||||
DEFAULT_CONVERSATION_VALUE,
|
||||
DEFAULT_OUTPUTS,
|
||||
FIELD_CONFIG,
|
||||
} from './constants';
|
||||
|
||||
export const FORM_META: FormMetaV2 = createFormMeta({
|
||||
fieldConfig: FIELD_CONFIG,
|
||||
needSyncConversationName: false,
|
||||
defaultInputValue: DEFAULT_CONVERSATION_VALUE,
|
||||
defaultOutputValue: DEFAULT_OUTPUTS,
|
||||
formRenderComponent: FormRender,
|
||||
});
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { useReadonly } from '@/nodes-v2/hooks/use-readonly';
|
||||
|
||||
import { createFormRender } from '../create-form-render';
|
||||
import {
|
||||
FIELD_CONFIG,
|
||||
DEFAULT_CONVERSATION_VALUE,
|
||||
DEFAULT_OUTPUTS,
|
||||
} from './constants';
|
||||
|
||||
const Render = () => {
|
||||
const readonly = useReadonly();
|
||||
|
||||
return createFormRender({
|
||||
defaultInputValue: DEFAULT_CONVERSATION_VALUE,
|
||||
defaultOutputValue: DEFAULT_OUTPUTS,
|
||||
fieldConfig: FIELD_CONFIG,
|
||||
readonly,
|
||||
inputTooltip: I18n.t('Input'),
|
||||
outputTooltip: I18n.t('Output'),
|
||||
});
|
||||
};
|
||||
|
||||
export default Render;
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** 删除会话节点 */
|
||||
|
||||
export { DELETE_CONVERSATION_NODE_REGISTRY } from './node-registry';
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { StandardNodeType } from '@coze-workflow/base';
|
||||
|
||||
import { createNodeRegistry } from '../create-node-registry';
|
||||
import { test } from './node-test';
|
||||
import { FORM_META } from './form-meta';
|
||||
import { FIELD_CONFIG } from './constants';
|
||||
|
||||
export const DELETE_CONVERSATION_NODE_REGISTRY = createNodeRegistry(
|
||||
StandardNodeType.DeleteConversation,
|
||||
FORM_META,
|
||||
FIELD_CONFIG,
|
||||
{ test },
|
||||
);
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { FlowNodeFormData } from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
import {
|
||||
generateParametersToProperties,
|
||||
generateEnvToRelatedContextProperties,
|
||||
} from '@/test-run-kit';
|
||||
import { type NodeTestMeta } from '@/test-run-kit';
|
||||
|
||||
export const test: NodeTestMeta = {
|
||||
generateRelatedContext(node, context) {
|
||||
const { isInProject } = context;
|
||||
if (isInProject) {
|
||||
return {};
|
||||
}
|
||||
return generateEnvToRelatedContextProperties({
|
||||
isNeedBot: true,
|
||||
hasConversationNode: true,
|
||||
disableBot: true,
|
||||
disableBotTooltip: I18n.t('wf_chatflow_141'),
|
||||
});
|
||||
},
|
||||
generateFormInputProperties(node) {
|
||||
const formData = node
|
||||
.getData(FlowNodeFormData)
|
||||
.formModel.getFormItemValueByPath('/');
|
||||
return generateParametersToProperties(formData?.inputParameters, { node });
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { nanoid } from 'nanoid';
|
||||
import { ValueExpressionType, ViewVariableType } from '@coze-workflow/variable';
|
||||
import { VariableTypeDTO } from '@coze-workflow/base';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { CONVERSATION_NAME } from '../constants';
|
||||
|
||||
export const FIELD_CONFIG = {
|
||||
conversationName: {
|
||||
description: I18n.t('workflow_250407_015'),
|
||||
name: CONVERSATION_NAME,
|
||||
required: true,
|
||||
type: VariableTypeDTO.string,
|
||||
},
|
||||
|
||||
messageId: {
|
||||
description: I18n.t('workflow_250407_016'),
|
||||
name: 'messageId',
|
||||
required: true,
|
||||
type: VariableTypeDTO.string,
|
||||
},
|
||||
};
|
||||
|
||||
export const DEFAULT_CONVERSATION_VALUE = Object.keys(FIELD_CONFIG).map(
|
||||
fieldName => ({
|
||||
name: fieldName,
|
||||
input: {
|
||||
type: ValueExpressionType.REF,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
export const DEFAULT_OUTPUTS = [
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'isSuccess',
|
||||
type: ViewVariableType.Boolean,
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type FormMetaV2 } from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
import { createFormMeta } from '../create-form-meta';
|
||||
import FormRender from './form-render';
|
||||
import {
|
||||
DEFAULT_CONVERSATION_VALUE,
|
||||
DEFAULT_OUTPUTS,
|
||||
FIELD_CONFIG,
|
||||
} from './constants';
|
||||
|
||||
export const FORM_META: FormMetaV2 = createFormMeta({
|
||||
fieldConfig: FIELD_CONFIG,
|
||||
needSyncConversationName: true,
|
||||
defaultInputValue: DEFAULT_CONVERSATION_VALUE,
|
||||
defaultOutputValue: DEFAULT_OUTPUTS,
|
||||
formRenderComponent: FormRender,
|
||||
});
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { useReadonly } from '@/nodes-v2/hooks/use-readonly';
|
||||
|
||||
import { createFormRender } from '../create-form-render';
|
||||
import {
|
||||
FIELD_CONFIG,
|
||||
DEFAULT_CONVERSATION_VALUE,
|
||||
DEFAULT_OUTPUTS,
|
||||
} from './constants';
|
||||
|
||||
const Render = () => {
|
||||
const readonly = useReadonly();
|
||||
|
||||
return createFormRender({
|
||||
defaultInputValue: DEFAULT_CONVERSATION_VALUE,
|
||||
defaultOutputValue: DEFAULT_OUTPUTS,
|
||||
fieldConfig: FIELD_CONFIG,
|
||||
readonly,
|
||||
inputTooltip: I18n.t('Input'),
|
||||
outputTooltip: I18n.t('Output'),
|
||||
});
|
||||
};
|
||||
|
||||
export default Render;
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** 删除消息节点 */
|
||||
|
||||
export { DELETE_MESSAGE_NODE_REGISTRY } from './node-registry';
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { StandardNodeType } from '@coze-workflow/base';
|
||||
|
||||
import { createNodeRegistry } from '../create-node-registry';
|
||||
import { test } from './node-test';
|
||||
import { FORM_META } from './form-meta';
|
||||
import { FIELD_CONFIG } from './constants';
|
||||
|
||||
export const DELETE_MESSAGE_NODE_REGISTRY = createNodeRegistry(
|
||||
StandardNodeType.DeleteMessage,
|
||||
FORM_META,
|
||||
FIELD_CONFIG,
|
||||
{ test },
|
||||
);
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { FlowNodeFormData } from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
import {
|
||||
generateParametersToProperties,
|
||||
generateEnvToRelatedContextProperties,
|
||||
} from '@/test-run-kit';
|
||||
import { type NodeTestMeta } from '@/test-run-kit';
|
||||
|
||||
export const test: NodeTestMeta = {
|
||||
generateRelatedContext(node, context) {
|
||||
const { isInProject } = context;
|
||||
if (isInProject) {
|
||||
return {};
|
||||
}
|
||||
return generateEnvToRelatedContextProperties({
|
||||
isNeedBot: true,
|
||||
});
|
||||
},
|
||||
generateFormInputProperties(node) {
|
||||
const formData = node
|
||||
.getData(FlowNodeFormData)
|
||||
.formModel.getFormItemValueByPath('/');
|
||||
return generateParametersToProperties(formData?.inputParameters, { node });
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { QUERY_MESSAGE_LIST_NODE_REGISTRY } from './query-message-list';
|
||||
export { CREATE_CONVERSATION_NODE_REGISTRY } from './create-conversation';
|
||||
export { CLEAR_CONTEXT_NODE_REGISTRY } from './clear-conversation-history';
|
||||
export { UPDATE_CONVERSATION_NODE_REGISTRY } from './update-conversation';
|
||||
export { DELETE_CONVERSATION_NODE_REGISTRY } from './delete-conversation';
|
||||
export { QUERY_CONVERSATION_LIST_NODE_REGISTRY } from './query-conversation-list';
|
||||
export { QUERY_CONVERSATION_HISTORY_NODE_REGISTRY } from './query-conversation-history';
|
||||
export { CREATE_MESSAGE_NODE_REGISTRY } from './create-message';
|
||||
export { UPDATE_MESSAGE_NODE_REGISTRY } from './update-message';
|
||||
export { DELETE_MESSAGE_NODE_REGISTRY } from './delete-message';
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { nanoid } from 'nanoid';
|
||||
import { ValueExpressionType, ViewVariableType } from '@coze-workflow/variable';
|
||||
import { VariableTypeDTO } from '@coze-workflow/base';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { CONVERSATION_NAME } from '../constants';
|
||||
|
||||
export const FIELD_CONFIG = {
|
||||
conversationName: {
|
||||
description: I18n.t('workflow_250407_028'),
|
||||
name: CONVERSATION_NAME,
|
||||
required: true,
|
||||
type: VariableTypeDTO.string,
|
||||
},
|
||||
rounds: {
|
||||
description: I18n.t('workflow_250407_029'),
|
||||
name: 'rounds',
|
||||
required: true,
|
||||
type: VariableTypeDTO.integer,
|
||||
},
|
||||
};
|
||||
|
||||
export const DEFAULT_CONVERSATION_VALUE = Object.keys(FIELD_CONFIG).map(
|
||||
fieldName => ({
|
||||
name: fieldName,
|
||||
input: {
|
||||
type: ValueExpressionType.REF,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
export const DEFAULT_OUTPUTS = [
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'messageList',
|
||||
type: ViewVariableType.ArrayObject,
|
||||
children: [
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'role',
|
||||
type: ViewVariableType.String,
|
||||
},
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'content',
|
||||
type: ViewVariableType.String,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type FormMetaV2 } from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
import { createFormMeta } from '../create-form-meta';
|
||||
import FormRender from './form-render';
|
||||
import {
|
||||
DEFAULT_CONVERSATION_VALUE,
|
||||
DEFAULT_OUTPUTS,
|
||||
FIELD_CONFIG,
|
||||
} from './constants';
|
||||
|
||||
export const FORM_META: FormMetaV2 = createFormMeta({
|
||||
fieldConfig: FIELD_CONFIG,
|
||||
needSyncConversationName: true,
|
||||
defaultInputValue: DEFAULT_CONVERSATION_VALUE,
|
||||
defaultOutputValue: DEFAULT_OUTPUTS,
|
||||
formRenderComponent: FormRender,
|
||||
});
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { useReadonly } from '@/nodes-v2/hooks/use-readonly';
|
||||
|
||||
import { createFormRender } from '../create-form-render';
|
||||
import {
|
||||
FIELD_CONFIG,
|
||||
DEFAULT_CONVERSATION_VALUE,
|
||||
DEFAULT_OUTPUTS,
|
||||
} from './constants';
|
||||
|
||||
const Render = () => {
|
||||
const readonly = useReadonly();
|
||||
|
||||
return createFormRender({
|
||||
defaultInputValue: DEFAULT_CONVERSATION_VALUE,
|
||||
defaultOutputValue: DEFAULT_OUTPUTS,
|
||||
fieldConfig: FIELD_CONFIG,
|
||||
readonly,
|
||||
inputTooltip: I18n.t('Input'),
|
||||
outputTooltip: I18n.t('Output'),
|
||||
});
|
||||
};
|
||||
|
||||
export default Render;
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** 查询会话历史节点 */
|
||||
|
||||
export { QUERY_CONVERSATION_HISTORY_NODE_REGISTRY } from './node-registry';
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { StandardNodeType } from '@coze-workflow/base';
|
||||
|
||||
import { createNodeRegistry } from '../create-node-registry';
|
||||
import { test } from './node-test';
|
||||
import { FORM_META } from './form-meta';
|
||||
import { FIELD_CONFIG } from './constants';
|
||||
|
||||
export const QUERY_CONVERSATION_HISTORY_NODE_REGISTRY = createNodeRegistry(
|
||||
StandardNodeType.QueryConversationHistory,
|
||||
FORM_META,
|
||||
FIELD_CONFIG,
|
||||
{ test },
|
||||
);
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { FlowNodeFormData } from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
import {
|
||||
generateParametersToProperties,
|
||||
generateEnvToRelatedContextProperties,
|
||||
} from '@/test-run-kit';
|
||||
import { type NodeTestMeta } from '@/test-run-kit';
|
||||
|
||||
export const test: NodeTestMeta = {
|
||||
generateRelatedContext(node, context) {
|
||||
const { isInProject } = context;
|
||||
if (isInProject) {
|
||||
return {};
|
||||
}
|
||||
return generateEnvToRelatedContextProperties({
|
||||
isNeedBot: true,
|
||||
});
|
||||
},
|
||||
generateFormInputProperties(node) {
|
||||
const formData = node
|
||||
.getData(FlowNodeFormData)
|
||||
.formModel.getFormItemValueByPath('/');
|
||||
return generateParametersToProperties(formData?.inputParameters, { node });
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { nanoid } from 'nanoid';
|
||||
import { ViewVariableType } from '@coze-workflow/variable';
|
||||
|
||||
export const DEFAULT_OUTPUTS = [
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'conversationList',
|
||||
type: ViewVariableType.ArrayObject,
|
||||
children: [
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'conversationName',
|
||||
type: ViewVariableType.String,
|
||||
},
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'conversationId',
|
||||
type: ViewVariableType.String,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type FormMetaV2 } from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
import { createFormMeta } from '../create-form-meta';
|
||||
import FormRender from './form-render';
|
||||
import { DEFAULT_OUTPUTS } from './constants';
|
||||
|
||||
export const FORM_META: FormMetaV2 = createFormMeta({
|
||||
fieldConfig: {},
|
||||
needSyncConversationName: false,
|
||||
defaultInputValue: [],
|
||||
defaultOutputValue: DEFAULT_OUTPUTS,
|
||||
formRenderComponent: FormRender,
|
||||
});
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { useReadonly } from '@/nodes-v2/hooks/use-readonly';
|
||||
|
||||
import { createFormRender } from '../create-form-render';
|
||||
import { DEFAULT_OUTPUTS } from './constants';
|
||||
|
||||
const Render = () => {
|
||||
const readonly = useReadonly();
|
||||
|
||||
return createFormRender({
|
||||
defaultInputValue: [],
|
||||
defaultOutputValue: DEFAULT_OUTPUTS,
|
||||
fieldConfig: {},
|
||||
readonly,
|
||||
inputTooltip: I18n.t('Input'),
|
||||
outputTooltip: I18n.t('Output'),
|
||||
hasInputs: false,
|
||||
});
|
||||
};
|
||||
|
||||
export default Render;
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** 查询会话列表 */
|
||||
|
||||
export { QUERY_CONVERSATION_LIST_NODE_REGISTRY } from './node-registry';
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { StandardNodeType } from '@coze-workflow/base';
|
||||
|
||||
import { createNodeRegistry } from '../create-node-registry';
|
||||
import { test } from './node-test';
|
||||
import { FORM_META } from './form-meta';
|
||||
|
||||
export const QUERY_CONVERSATION_LIST_NODE_REGISTRY = createNodeRegistry(
|
||||
StandardNodeType.QueryConversationList,
|
||||
FORM_META,
|
||||
{},
|
||||
{ test },
|
||||
);
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { generateEnvToRelatedContextProperties } from '@/test-run-kit';
|
||||
import { type NodeTestMeta } from '@/test-run-kit';
|
||||
|
||||
export const test: NodeTestMeta = {
|
||||
generateRelatedContext(node, context) {
|
||||
const { isInProject } = context;
|
||||
if (isInProject) {
|
||||
return {};
|
||||
}
|
||||
return generateEnvToRelatedContextProperties({
|
||||
isNeedBot: true,
|
||||
hasConversationNode: true,
|
||||
disableBot: true,
|
||||
disableBotTooltip: I18n.t('wf_chatflow_141'),
|
||||
});
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { nanoid } from 'nanoid';
|
||||
import { ValueExpressionType, ViewVariableType } from '@coze-workflow/variable';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { CONVERSATION_NAME } from '../constants';
|
||||
|
||||
export const FIELD_CONFIG = {
|
||||
[CONVERSATION_NAME]: {
|
||||
description: I18n.t('wf_chatflow_24'),
|
||||
name: CONVERSATION_NAME,
|
||||
required: true,
|
||||
type: 'string',
|
||||
},
|
||||
limit: {
|
||||
description: I18n.t('wf_chatflow_34'),
|
||||
name: 'limit',
|
||||
required: false,
|
||||
type: 'integer',
|
||||
},
|
||||
beforeId: {
|
||||
description: I18n.t('wf_chatflow_35'),
|
||||
name: 'beforeId',
|
||||
required: false,
|
||||
type: 'string',
|
||||
},
|
||||
afterId: {
|
||||
description: I18n.t('wf_chatflow_36'),
|
||||
name: 'afterId',
|
||||
required: false,
|
||||
type: 'string',
|
||||
},
|
||||
};
|
||||
|
||||
export const DEFAULT_CONVERSATION_VALUE = [
|
||||
{
|
||||
name: CONVERSATION_NAME,
|
||||
input: {
|
||||
type: ValueExpressionType.REF,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'limit',
|
||||
input: {
|
||||
type: ValueExpressionType.REF,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'beforeId',
|
||||
input: {
|
||||
type: ValueExpressionType.REF,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'afterId',
|
||||
input: {
|
||||
type: ValueExpressionType.REF,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export const DEFAULT_OUTPUTS = [
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'messageList',
|
||||
type: ViewVariableType.ArrayObject,
|
||||
children: [
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'messageId',
|
||||
type: ViewVariableType.String,
|
||||
},
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'role',
|
||||
type: ViewVariableType.String,
|
||||
},
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'contentType',
|
||||
type: ViewVariableType.String,
|
||||
},
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'content',
|
||||
type: ViewVariableType.String,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'firstId',
|
||||
type: ViewVariableType.String,
|
||||
},
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'lastId',
|
||||
type: ViewVariableType.String,
|
||||
},
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'hasMore',
|
||||
type: ViewVariableType.Boolean,
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
ValidateTrigger,
|
||||
type FormMetaV2,
|
||||
} from '@flowgram-adapter/free-layout-editor';
|
||||
import { type InputValueVO } from '@coze-workflow/base';
|
||||
|
||||
import { fireNodeTitleChange } from '@/nodes-v2/materials/fire-node-title-change';
|
||||
import { createValueExpressionInputValidate } from '@/nodes-v2/materials/create-value-expression-input-validate';
|
||||
|
||||
import { transformOnSubmit } from '../transform-on-submit';
|
||||
import { createTransformOnInit } from '../transform-on-init';
|
||||
import { syncConversationNameEffect } from '../sync-conversation-name-effect';
|
||||
import { provideNodeOutputVariablesEffect } from '../../materials/provide-node-output-variables';
|
||||
import FormRender from './form-render';
|
||||
import { DEFAULT_CONVERSATION_VALUE, DEFAULT_OUTPUTS } from './constants';
|
||||
|
||||
interface FormData {
|
||||
inputParameters: InputValueVO[];
|
||||
}
|
||||
|
||||
export const QUERY_MESSAGE_LIST_FORM_META: FormMetaV2<FormData> = {
|
||||
// 节点表单渲染
|
||||
render: props => <FormRender {...props} />,
|
||||
|
||||
// 验证触发时机
|
||||
validateTrigger: ValidateTrigger.onChange,
|
||||
|
||||
// 验证规则
|
||||
validate: {
|
||||
// 必填
|
||||
'inputParameters.0.input': createValueExpressionInputValidate({
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
|
||||
// 副作用管理
|
||||
effect: {
|
||||
nodeMeta: fireNodeTitleChange,
|
||||
outputs: provideNodeOutputVariablesEffect,
|
||||
inputParameters: syncConversationNameEffect,
|
||||
},
|
||||
|
||||
// 节点后端数据 -> 前端表单数据
|
||||
formatOnInit: createTransformOnInit(
|
||||
DEFAULT_CONVERSATION_VALUE,
|
||||
DEFAULT_OUTPUTS,
|
||||
),
|
||||
|
||||
// 前端表单数据 -> 节点后端数据
|
||||
formatOnSubmit: transformOnSubmit,
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { useReadonly } from '@/nodes-v2/hooks/use-readonly';
|
||||
|
||||
import { createFormRender } from '../create-form-render';
|
||||
import {
|
||||
FIELD_CONFIG,
|
||||
DEFAULT_CONVERSATION_VALUE,
|
||||
DEFAULT_OUTPUTS,
|
||||
} from './constants';
|
||||
|
||||
const Render = ({ form }) => {
|
||||
const readonly = useReadonly();
|
||||
|
||||
return createFormRender({
|
||||
defaultInputValue: DEFAULT_CONVERSATION_VALUE,
|
||||
defaultOutputValue: DEFAULT_OUTPUTS,
|
||||
fieldConfig: FIELD_CONFIG,
|
||||
readonly,
|
||||
inputTooltip: I18n.t('wf_chatflow_33'),
|
||||
outputTooltip: I18n.t('wf_chatflow_37'),
|
||||
});
|
||||
};
|
||||
|
||||
export default Render;
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** 查看消息列表(某个会话) */
|
||||
export { QUERY_MESSAGE_LIST_NODE_REGISTRY } from './node-registry';
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { StandardNodeType } from '@coze-workflow/base';
|
||||
|
||||
import { createNodeRegistry } from '../create-node-registry';
|
||||
import { test } from './node-test';
|
||||
import { QUERY_MESSAGE_LIST_FORM_META } from './form-meta';
|
||||
import { FIELD_CONFIG } from './constants';
|
||||
|
||||
export const QUERY_MESSAGE_LIST_NODE_REGISTRY = createNodeRegistry(
|
||||
StandardNodeType.QueryMessageList,
|
||||
QUERY_MESSAGE_LIST_FORM_META,
|
||||
FIELD_CONFIG,
|
||||
{ test },
|
||||
);
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { FlowNodeFormData } from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
import {
|
||||
generateParametersToProperties,
|
||||
generateEnvToRelatedContextProperties,
|
||||
} from '@/test-run-kit';
|
||||
import { type NodeTestMeta } from '@/test-run-kit';
|
||||
|
||||
export const test: NodeTestMeta = {
|
||||
generateRelatedContext(node, context) {
|
||||
const { isInProject } = context;
|
||||
if (isInProject) {
|
||||
return {};
|
||||
}
|
||||
return generateEnvToRelatedContextProperties({
|
||||
isNeedBot: true,
|
||||
});
|
||||
},
|
||||
generateFormInputProperties(node) {
|
||||
const formData = node
|
||||
.getData(FlowNodeFormData)
|
||||
.formModel.getFormItemValueByPath('/');
|
||||
return generateParametersToProperties(formData?.inputParameters, { node });
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { set, cloneDeep } from 'lodash-es';
|
||||
import {
|
||||
DataEvent,
|
||||
type EffectOptions,
|
||||
type Effect,
|
||||
FlowNodeFormData,
|
||||
type FormModelV2,
|
||||
} from '@flowgram-adapter/free-layout-editor';
|
||||
import { ValueExpression, WorkflowMode } from '@coze-workflow/base';
|
||||
|
||||
import { CONVERSATION_NAME } from './constants';
|
||||
|
||||
/** 延迟200ms,此时等边连上后,才能检测变量作用域 */
|
||||
const DELAY = 200;
|
||||
|
||||
const effect: Effect = ({ value, context }) => {
|
||||
if (!context) {
|
||||
return;
|
||||
}
|
||||
const { node, playgroundContext } = context;
|
||||
|
||||
const { variableService, nodesService, globalState } = playgroundContext;
|
||||
const startNode = nodesService.getStartNode();
|
||||
const formModel = node.getData(FlowNodeFormData).getFormModel<FormModelV2>();
|
||||
const isChatflow = globalState.flowMode === WorkflowMode.ChatFlow;
|
||||
const { isInIDE } = globalState;
|
||||
|
||||
setTimeout(() => {
|
||||
const startConversationNameVar =
|
||||
variableService.getWorkflowVariableByKeyPath(
|
||||
[startNode.id, 'CONVERSATION_NAME'],
|
||||
{
|
||||
node,
|
||||
checkScope: true,
|
||||
},
|
||||
);
|
||||
|
||||
const clonedValue = cloneDeep(value);
|
||||
const conversationNameItem = clonedValue.find(
|
||||
v => v.name === CONVERSATION_NAME,
|
||||
);
|
||||
const noValue = ValueExpression.isEmpty(
|
||||
conversationNameItem?.input as ValueExpression,
|
||||
);
|
||||
|
||||
// 如果能够找到开始节点的 CONVERSATION_NAME 参数
|
||||
if (
|
||||
startConversationNameVar &&
|
||||
conversationNameItem &&
|
||||
isChatflow &&
|
||||
noValue
|
||||
) {
|
||||
if (formModel) {
|
||||
set(conversationNameItem, 'input', {
|
||||
type: 'ref',
|
||||
content: {
|
||||
keyPath: ['100001', 'CONVERSATION_NAME'],
|
||||
},
|
||||
});
|
||||
formModel.setValueIn('inputParameters', clonedValue);
|
||||
}
|
||||
} else if (!isInIDE && !isChatflow && conversationNameItem && noValue) {
|
||||
// 非项目中的工作流,如果存在没有值的 CONVERSATION_NAME 字段,填入默认值 default
|
||||
if (formModel) {
|
||||
set(conversationNameItem, 'input', {
|
||||
type: 'literal',
|
||||
content: 'Default',
|
||||
});
|
||||
formModel.setValueIn('inputParameters', clonedValue);
|
||||
}
|
||||
}
|
||||
}, DELAY);
|
||||
};
|
||||
|
||||
export const syncConversationNameEffect: EffectOptions[] = [
|
||||
{
|
||||
event: DataEvent.onValueInit,
|
||||
effect,
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import omit from 'lodash-es/omit';
|
||||
import {
|
||||
type InputValueVO,
|
||||
type ViewVariableTreeNode,
|
||||
type NodeDataDTO,
|
||||
} from '@coze-workflow/base';
|
||||
|
||||
const isEmptyArrayOrNil = (value: unknown) =>
|
||||
// eslint-disable-next-line eqeqeq
|
||||
(Array.isArray(value) && value.length === 0) || value == null;
|
||||
/**
|
||||
* 节点后端数据 -> 前端表单数据
|
||||
*/
|
||||
export const createTransformOnInit =
|
||||
(
|
||||
defaultInputValue: InputValueVO[] = [],
|
||||
defaultOutputValue: ViewVariableTreeNode[] = [],
|
||||
) =>
|
||||
(value: NodeDataDTO) => {
|
||||
const { inputs, outputs } = value || {};
|
||||
const inputParameters = inputs?.inputParameters || [];
|
||||
|
||||
// 由于在提交时,会将没有填值的变量给过滤掉,所以需要在初始化时,将默认值补充进来
|
||||
// 参见:packages/workflow/nodes/src/workflow-json-format.ts:241
|
||||
const refillInputParamters = defaultInputValue.map(cur => {
|
||||
const { name } = cur;
|
||||
const target = inputParameters.find(item => item.name === name);
|
||||
if (target) {
|
||||
return target;
|
||||
}
|
||||
return cur;
|
||||
}, []);
|
||||
|
||||
const initValue = {
|
||||
...omit(value, ['inputs']),
|
||||
inputParameters: refillInputParamters,
|
||||
outputs: isEmptyArrayOrNil(outputs) ? defaultOutputValue : outputs,
|
||||
};
|
||||
|
||||
return initValue;
|
||||
};
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import omit from 'lodash-es/omit';
|
||||
import { type NodeDataDTO, type InputValueVO } from '@coze-workflow/base';
|
||||
|
||||
interface FormData {
|
||||
inputParameters: InputValueVO[];
|
||||
}
|
||||
|
||||
/**
|
||||
* 前端表单数据 -> 节点后端数据
|
||||
* @param value
|
||||
* @returns
|
||||
*/
|
||||
export const transformOnSubmit = (value: FormData): NodeDataDTO => {
|
||||
const formattedValue: Record<string, unknown> = {
|
||||
...value,
|
||||
inputs: {
|
||||
inputParameters: value?.inputParameters || [],
|
||||
},
|
||||
};
|
||||
|
||||
return omit(formattedValue, ['inputParameters']) as unknown as NodeDataDTO;
|
||||
};
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { nanoid } from 'nanoid';
|
||||
import { ValueExpressionType, ViewVariableType } from '@coze-workflow/variable';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { CONVERSATION_NAME } from '../constants';
|
||||
|
||||
export const FIELD_CONFIG = {
|
||||
conversationName: {
|
||||
description: I18n.t('workflow_250407_019'),
|
||||
name: CONVERSATION_NAME,
|
||||
required: true,
|
||||
type: 'string',
|
||||
},
|
||||
newConversationName: {
|
||||
description: I18n.t('workflow_250407_020'),
|
||||
name: 'newConversationName',
|
||||
required: true,
|
||||
type: 'string',
|
||||
},
|
||||
};
|
||||
|
||||
export const DEFAULT_CONVERSATION_VALUE = Object.keys(FIELD_CONFIG).map(
|
||||
fieldName => ({
|
||||
name: fieldName,
|
||||
input: {
|
||||
type: ValueExpressionType.REF,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
export const DEFAULT_OUTPUTS = [
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'isSuccess',
|
||||
type: ViewVariableType.Boolean,
|
||||
},
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'isExisted',
|
||||
type: ViewVariableType.Boolean,
|
||||
},
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'conversationId',
|
||||
type: ViewVariableType.String,
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type FormMetaV2 } from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
import { createFormMeta } from '../create-form-meta';
|
||||
import FormRender from './form-render';
|
||||
import {
|
||||
DEFAULT_CONVERSATION_VALUE,
|
||||
DEFAULT_OUTPUTS,
|
||||
FIELD_CONFIG,
|
||||
} from './constants';
|
||||
|
||||
export const FORM_META: FormMetaV2 = createFormMeta({
|
||||
fieldConfig: FIELD_CONFIG,
|
||||
needSyncConversationName: false,
|
||||
defaultInputValue: DEFAULT_CONVERSATION_VALUE,
|
||||
defaultOutputValue: DEFAULT_OUTPUTS,
|
||||
formRenderComponent: FormRender,
|
||||
});
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { useReadonly } from '@/nodes-v2/hooks/use-readonly';
|
||||
|
||||
import { createFormRender } from '../create-form-render';
|
||||
import {
|
||||
FIELD_CONFIG,
|
||||
DEFAULT_CONVERSATION_VALUE,
|
||||
DEFAULT_OUTPUTS,
|
||||
} from './constants';
|
||||
|
||||
const Render = () => {
|
||||
const readonly = useReadonly();
|
||||
|
||||
return createFormRender({
|
||||
defaultInputValue: DEFAULT_CONVERSATION_VALUE,
|
||||
defaultOutputValue: DEFAULT_OUTPUTS,
|
||||
fieldConfig: FIELD_CONFIG,
|
||||
readonly,
|
||||
inputTooltip: I18n.t('Input'),
|
||||
outputTooltip: I18n.t('Output'),
|
||||
});
|
||||
};
|
||||
|
||||
export default Render;
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** 更新会话节点 */
|
||||
|
||||
export { UPDATE_CONVERSATION_NODE_REGISTRY } from './node-registry';
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { StandardNodeType } from '@coze-workflow/base';
|
||||
|
||||
import { createNodeRegistry } from '../create-node-registry';
|
||||
import { test } from './node-test';
|
||||
import { FORM_META } from './form-meta';
|
||||
import { FIELD_CONFIG } from './constants';
|
||||
|
||||
export const UPDATE_CONVERSATION_NODE_REGISTRY = createNodeRegistry(
|
||||
StandardNodeType.UpdateConversation,
|
||||
FORM_META,
|
||||
FIELD_CONFIG,
|
||||
{ test },
|
||||
);
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { FlowNodeFormData } from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
import {
|
||||
generateParametersToProperties,
|
||||
generateEnvToRelatedContextProperties,
|
||||
} from '@/test-run-kit';
|
||||
import { type NodeTestMeta } from '@/test-run-kit';
|
||||
|
||||
export const test: NodeTestMeta = {
|
||||
generateRelatedContext(node, context) {
|
||||
const { isInProject } = context;
|
||||
if (isInProject) {
|
||||
return {};
|
||||
}
|
||||
return generateEnvToRelatedContextProperties({
|
||||
isNeedBot: true,
|
||||
hasConversationNode: true,
|
||||
disableBot: true,
|
||||
disableBotTooltip: I18n.t('wf_chatflow_141'),
|
||||
});
|
||||
},
|
||||
generateFormInputProperties(node) {
|
||||
const formData = node
|
||||
.getData(FlowNodeFormData)
|
||||
.formModel.getFormItemValueByPath('/');
|
||||
return generateParametersToProperties(formData?.inputParameters, { node });
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { nanoid } from 'nanoid';
|
||||
import { ValueExpressionType, ViewVariableType } from '@coze-workflow/variable';
|
||||
import { VariableTypeDTO } from '@coze-workflow/base';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { CONVERSATION_NAME } from '../constants';
|
||||
|
||||
export const FIELD_CONFIG = {
|
||||
conversationName: {
|
||||
description: I18n.t('workflow_250407_010'),
|
||||
name: CONVERSATION_NAME,
|
||||
required: true,
|
||||
type: VariableTypeDTO.string,
|
||||
},
|
||||
|
||||
messageId: {
|
||||
description: I18n.t('workflow_250407_011'),
|
||||
name: 'messageId',
|
||||
required: true,
|
||||
type: VariableTypeDTO.string,
|
||||
},
|
||||
|
||||
newContent: {
|
||||
description: I18n.t('workflow_250407_012'),
|
||||
name: 'newContent',
|
||||
required: true,
|
||||
type: VariableTypeDTO.string,
|
||||
},
|
||||
};
|
||||
|
||||
export const DEFAULT_CONVERSATION_VALUE = Object.keys(FIELD_CONFIG).map(
|
||||
fieldName => ({
|
||||
name: fieldName,
|
||||
input: {
|
||||
type: ValueExpressionType.REF,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
export const DEFAULT_OUTPUTS = [
|
||||
{
|
||||
key: nanoid(),
|
||||
name: 'isSuccess',
|
||||
type: ViewVariableType.Boolean,
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type FormMetaV2 } from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
import { createFormMeta } from '../create-form-meta';
|
||||
import FormRender from './form-render';
|
||||
import {
|
||||
DEFAULT_CONVERSATION_VALUE,
|
||||
DEFAULT_OUTPUTS,
|
||||
FIELD_CONFIG,
|
||||
} from './constants';
|
||||
|
||||
export const FORM_META: FormMetaV2 = createFormMeta({
|
||||
fieldConfig: FIELD_CONFIG,
|
||||
needSyncConversationName: true,
|
||||
defaultInputValue: DEFAULT_CONVERSATION_VALUE,
|
||||
defaultOutputValue: DEFAULT_OUTPUTS,
|
||||
formRenderComponent: FormRender,
|
||||
});
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { useReadonly } from '@/nodes-v2/hooks/use-readonly';
|
||||
|
||||
import { createFormRender } from '../create-form-render';
|
||||
import {
|
||||
FIELD_CONFIG,
|
||||
DEFAULT_CONVERSATION_VALUE,
|
||||
DEFAULT_OUTPUTS,
|
||||
} from './constants';
|
||||
|
||||
const Render = () => {
|
||||
const readonly = useReadonly();
|
||||
|
||||
return createFormRender({
|
||||
defaultInputValue: DEFAULT_CONVERSATION_VALUE,
|
||||
defaultOutputValue: DEFAULT_OUTPUTS,
|
||||
fieldConfig: FIELD_CONFIG,
|
||||
readonly,
|
||||
inputTooltip: I18n.t('Input'),
|
||||
outputTooltip: I18n.t('Output'),
|
||||
});
|
||||
};
|
||||
|
||||
export default Render;
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** 修改消息节点 */
|
||||
|
||||
export { UPDATE_MESSAGE_NODE_REGISTRY } from './node-registry';
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { StandardNodeType } from '@coze-workflow/base';
|
||||
|
||||
import { createNodeRegistry } from '../create-node-registry';
|
||||
import { test } from './node-test';
|
||||
import { FORM_META } from './form-meta';
|
||||
import { FIELD_CONFIG } from './constants';
|
||||
|
||||
export const UPDATE_MESSAGE_NODE_REGISTRY = createNodeRegistry(
|
||||
StandardNodeType.UpdateMessage,
|
||||
FORM_META,
|
||||
FIELD_CONFIG,
|
||||
{ test },
|
||||
);
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { FlowNodeFormData } from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
import {
|
||||
generateParametersToProperties,
|
||||
generateEnvToRelatedContextProperties,
|
||||
} from '@/test-run-kit';
|
||||
import { type NodeTestMeta } from '@/test-run-kit';
|
||||
|
||||
export const test: NodeTestMeta = {
|
||||
generateRelatedContext(node, context) {
|
||||
const { isInProject } = context;
|
||||
if (isInProject) {
|
||||
return {};
|
||||
}
|
||||
return generateEnvToRelatedContextProperties({
|
||||
isNeedBot: true,
|
||||
});
|
||||
},
|
||||
generateFormInputProperties(node) {
|
||||
const formData = node
|
||||
.getData(FlowNodeFormData)
|
||||
.formModel.getFormItemValueByPath('/');
|
||||
return generateParametersToProperties(formData?.inputParameters, { node });
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type FC } from 'react';
|
||||
|
||||
import { IconCozPlus } from '@coze-arch/coze-design/icons';
|
||||
import { IconButton, Tooltip } from '@coze-arch/coze-design';
|
||||
|
||||
interface AddIconProps {
|
||||
disabledTooltip?: string;
|
||||
onClick?: (e) => void;
|
||||
}
|
||||
|
||||
export const AddIcon: FC<AddIconProps> = ({ disabledTooltip, onClick }) =>
|
||||
disabledTooltip ? (
|
||||
<Tooltip content={disabledTooltip}>
|
||||
<IconButton
|
||||
disabled={!!disabledTooltip}
|
||||
color="highlight"
|
||||
size="small"
|
||||
icon={<IconCozPlus className="text-sm" />}
|
||||
onClick={onClick}
|
||||
/>
|
||||
</Tooltip>
|
||||
) : (
|
||||
<IconButton
|
||||
color="highlight"
|
||||
size="small"
|
||||
icon={<IconCozPlus className="text-sm" />}
|
||||
onClick={onClick}
|
||||
/>
|
||||
);
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useMemo } from 'react';
|
||||
|
||||
import {
|
||||
useForm,
|
||||
type FlowNodeEntity,
|
||||
} from '@flowgram-adapter/free-layout-editor';
|
||||
import { FlowNodeBaseType } from '@flowgram-adapter/free-layout-editor';
|
||||
import {
|
||||
useEntityFromContext,
|
||||
usePlayground,
|
||||
} from '@flowgram-adapter/free-layout-editor';
|
||||
import { SettingOnErrorProcessType } from '@coze-workflow/nodes';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { Tooltip } from '@coze-arch/coze-design';
|
||||
|
||||
import { type ComponentProps } from '@/nodes-v2/components/types';
|
||||
import { Radio } from '@/nodes-v2/components/radio';
|
||||
import { FormCard } from '@/form-extensions/components/form-card';
|
||||
|
||||
export const BatchMode = ({
|
||||
name,
|
||||
value,
|
||||
onChange,
|
||||
onBlur,
|
||||
}: ComponentProps<string>) => {
|
||||
const node = useEntityFromContext() as FlowNodeEntity;
|
||||
|
||||
const playground = usePlayground();
|
||||
const { isBatchV2 } = playground.context.schemaGray;
|
||||
const form = useForm();
|
||||
const processType = form.getValueIn('settingOnError.processType');
|
||||
|
||||
const options = useMemo(() => {
|
||||
const isExceptionSetting =
|
||||
processType === SettingOnErrorProcessType.EXCEPTION;
|
||||
const isBatchDisabled =
|
||||
node.parent?.flowNodeType === FlowNodeBaseType.SUB_CANVAS ||
|
||||
isExceptionSetting;
|
||||
const disabledTooltip = isExceptionSetting
|
||||
? I18n.t(
|
||||
'workflow_250416_05',
|
||||
undefined,
|
||||
'需要先把节点的异常处理方式改为中断流程或者返回设定内容,才能改为批处理模式',
|
||||
)
|
||||
: '';
|
||||
|
||||
return [
|
||||
{
|
||||
value: 'single',
|
||||
label: I18n.t('workflow_batch_tab_single_radio'),
|
||||
},
|
||||
{
|
||||
value: 'batch',
|
||||
label: disabledTooltip ? (
|
||||
<Tooltip content={disabledTooltip}>
|
||||
<div>{I18n.t('workflow_batch_tab_batch_radio')}</div>
|
||||
</Tooltip>
|
||||
) : (
|
||||
I18n.t('workflow_batch_tab_batch_radio')
|
||||
),
|
||||
disabled: isBatchDisabled,
|
||||
},
|
||||
];
|
||||
}, [node, processType]);
|
||||
|
||||
if (isBatchV2) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
return (
|
||||
<FormCard collapsible={false}>
|
||||
<Radio
|
||||
name={name}
|
||||
mode={'button'}
|
||||
options={options}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
onBlur={onBlur}
|
||||
/>
|
||||
</FormCard>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,43 @@
|
||||
/* stylelint-disable declaration-no-important */
|
||||
.workflow-batch-setting-panel {
|
||||
position: relative;
|
||||
|
||||
padding: 24px;
|
||||
|
||||
background: rgba(247, 247, 250, 100%);
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 0 1px 0 rgba(0, 0, 0, 30%);
|
||||
}
|
||||
|
||||
.workflow-batch-setting-panel-title {
|
||||
padding-bottom: 32px;
|
||||
font-size: 18px !important;
|
||||
line-height: 24px !important;
|
||||
}
|
||||
|
||||
.form-field {
|
||||
display: flex;
|
||||
|
||||
&:first-child {
|
||||
margin-bottom: 16px !important;
|
||||
}
|
||||
|
||||
:global {
|
||||
.semi-form-field-label {
|
||||
width: 200px;
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
.rc-slider {
|
||||
width: 180px;
|
||||
}
|
||||
|
||||
.rc-slider-disabled {
|
||||
background-color: unset;
|
||||
}
|
||||
|
||||
.rc-slider+div {
|
||||
width: 108px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useRef, useEffect } from 'react';
|
||||
|
||||
import { debounce } from 'lodash-es';
|
||||
import {
|
||||
BATCH_SIZE_MAX,
|
||||
BATCH_SIZE_MIN,
|
||||
BATCH_CONCURRENT_SIZE_MIN,
|
||||
BATCH_CONCURRENT_SIZE_MAX,
|
||||
} from '@coze-workflow/nodes';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { type FormState } from '@coze-arch/bot-semi/Form';
|
||||
import { Form as BotSemiForm, Typography } from '@coze-arch/bot-semi';
|
||||
import { InputSlider } from '@coze-agent-ide/space-bot/input-slider';
|
||||
|
||||
import { LabelWithTooltip } from '@/form-extensions/components/label-with-tooltip';
|
||||
|
||||
import s from './batch-setting-form.module.less';
|
||||
|
||||
interface BatchSetting {
|
||||
batchSize: number;
|
||||
concurrentSize: number;
|
||||
}
|
||||
|
||||
export type BatchSettingOnChangeValue = FormState<BatchSetting>;
|
||||
|
||||
export interface BatchSettingProps {
|
||||
readonly?: boolean;
|
||||
value: BatchSetting;
|
||||
onChange: (value: FormState<BatchSetting>) => void;
|
||||
}
|
||||
|
||||
const DELAY_TIME = 10;
|
||||
|
||||
export const BatchSettingForm = ({
|
||||
value,
|
||||
readonly = false,
|
||||
onChange,
|
||||
}: BatchSettingProps) => {
|
||||
const formRef = useRef<BotSemiForm>(null);
|
||||
const isSemiFormDestroyed = useRef(false);
|
||||
const debouncedChange = debounce((v: BatchSettingOnChangeValue) => {
|
||||
// semi form 在销毁时会额外触发onChange从而污染数据,这里避免这样的情况发生
|
||||
if (isSemiFormDestroyed.current) {
|
||||
return;
|
||||
}
|
||||
onChange(v);
|
||||
}, DELAY_TIME);
|
||||
|
||||
const commonSliderProps = {
|
||||
useRcSlider: true,
|
||||
fieldClassName: s['form-field'],
|
||||
disabled: readonly,
|
||||
decimalPlaces: 0,
|
||||
step: 1,
|
||||
};
|
||||
|
||||
useEffect(
|
||||
() => () => {
|
||||
isSemiFormDestroyed.current = true;
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
return (
|
||||
// 防止触发节点选中
|
||||
<div
|
||||
className={s['workflow-batch-setting-panel']}
|
||||
onClick={e => e.stopPropagation()}
|
||||
>
|
||||
<Typography.Title className={s['workflow-batch-setting-panel-title']}>
|
||||
{I18n.t('workflow_batch_settings')}
|
||||
</Typography.Title>
|
||||
|
||||
<BotSemiForm<BatchSetting>
|
||||
ref={formRef}
|
||||
initValues={value}
|
||||
onChange={debouncedChange}
|
||||
>
|
||||
<InputSlider
|
||||
{...commonSliderProps}
|
||||
field="batchSize"
|
||||
label={
|
||||
<LabelWithTooltip
|
||||
label={I18n.t('workflow_maximum_run_count')}
|
||||
tooltip={I18n.t('workflow_maximum_run_count_tips')}
|
||||
></LabelWithTooltip>
|
||||
}
|
||||
max={BATCH_SIZE_MAX}
|
||||
min={BATCH_SIZE_MIN}
|
||||
/>
|
||||
|
||||
<InputSlider
|
||||
{...commonSliderProps}
|
||||
field="concurrentSize"
|
||||
label={
|
||||
<LabelWithTooltip
|
||||
label={I18n.t('workflow_maximum_parallel_runs')}
|
||||
tooltip={I18n.t('workflow_maximum_parallel_runs_tips')}
|
||||
></LabelWithTooltip>
|
||||
}
|
||||
max={BATCH_CONCURRENT_SIZE_MAX}
|
||||
min={BATCH_CONCURRENT_SIZE_MIN}
|
||||
/>
|
||||
</BotSemiForm>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,242 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useMemo } from 'react';
|
||||
|
||||
import { get } from 'lodash-es';
|
||||
import {
|
||||
useField,
|
||||
FieldArray,
|
||||
type FieldRenderProps,
|
||||
type FieldArrayRenderProps,
|
||||
useForm,
|
||||
Field,
|
||||
usePlayground,
|
||||
} from '@flowgram-adapter/free-layout-editor';
|
||||
import {
|
||||
DEFAULT_BATCH_CONCURRENT_SIZE,
|
||||
DEFAULT_BATCH_SIZE,
|
||||
} from '@coze-workflow/nodes';
|
||||
import {
|
||||
type BatchVOInputList,
|
||||
concatTestId,
|
||||
type RefExpression,
|
||||
type ValueExpression,
|
||||
ValueExpressionType,
|
||||
ViewVariableType,
|
||||
} from '@coze-workflow/base';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { Popover } from '@coze-arch/bot-semi';
|
||||
import { IconSetting } from '@coze-arch/bot-icons';
|
||||
import { IconCozMinus, IconCozPlus } from '@coze-arch/coze-design/icons';
|
||||
import { IconButton } from '@coze-arch/coze-design';
|
||||
|
||||
import { useReadonly } from '@/nodes-v2/hooks/use-readonly';
|
||||
import { ValueExpressionInput } from '@/nodes-v2/components/value-expression-input';
|
||||
import { NodeInputName } from '@/nodes-v2/components/node-input-name';
|
||||
import { FormItemFeedback } from '@/nodes-v2/components/form-item-feedback';
|
||||
import { FormCard } from '@/form-extensions/components/form-card';
|
||||
import { ColumnsTitleWithAction } from '@/form-extensions/components/columns-title-with-action';
|
||||
|
||||
import {
|
||||
BatchSettingForm,
|
||||
type BatchSettingOnChangeValue,
|
||||
} from './batch-setting-form';
|
||||
|
||||
import s from './index.module.less';
|
||||
|
||||
interface BatchProps {
|
||||
batchModeName: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export const Batch = ({ batchModeName, name }: BatchProps) => {
|
||||
const batchMode = useField(batchModeName)?.value;
|
||||
const readonly = useReadonly();
|
||||
|
||||
const form = useForm();
|
||||
const playground = usePlayground();
|
||||
const { isBatchV2 } = playground.context.schemaGray;
|
||||
|
||||
const actionButtonContent = useMemo(
|
||||
() => (
|
||||
<div className={s.actionButtonContent}>
|
||||
<Popover
|
||||
keepDOM
|
||||
stopPropagation
|
||||
trigger="click"
|
||||
position="bottomRight"
|
||||
content={
|
||||
<BatchSettingForm
|
||||
readonly={readonly}
|
||||
value={{
|
||||
batchSize:
|
||||
form.getValueIn(`${name}.batchSize`) ?? DEFAULT_BATCH_SIZE,
|
||||
concurrentSize:
|
||||
form.getValueIn(`${name}.concurrentSize`) ??
|
||||
DEFAULT_BATCH_CONCURRENT_SIZE,
|
||||
}}
|
||||
onChange={(value: BatchSettingOnChangeValue) => {
|
||||
form.setValueIn(
|
||||
`${name}.batchSize`,
|
||||
get(value.values, 'batchSize'),
|
||||
);
|
||||
form.setValueIn(
|
||||
`${name}.concurrentSize`,
|
||||
get(value.values, 'concurrentSize'),
|
||||
);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<IconButton
|
||||
color="secondary"
|
||||
size={'small'}
|
||||
icon={<IconSetting size="small" />}
|
||||
style={{ marginRight: 26 }}
|
||||
/>
|
||||
</Popover>
|
||||
</div>
|
||||
),
|
||||
[form, name, readonly],
|
||||
);
|
||||
|
||||
if (isBatchV2) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
return batchMode === 'batch' ? (
|
||||
<div className={s['batch-container']}>
|
||||
<FieldArray
|
||||
name={`${name}.inputLists`}
|
||||
defaultValue={[
|
||||
{ name: 'item1', input: { type: ValueExpressionType.REF }, id: '0' },
|
||||
]}
|
||||
>
|
||||
{({ field }: FieldArrayRenderProps<BatchVOInputList>) => {
|
||||
const disableDelete = field.value && field.value.length < 2;
|
||||
return (
|
||||
<FormCard
|
||||
className={s['batch-content']}
|
||||
header={I18n.t('workflow_detail_node_batch')}
|
||||
tooltip={I18n.t('workflow_detail_node_batch_tooltip')}
|
||||
actionButton={actionButtonContent}
|
||||
>
|
||||
<div className={s['columns-title']}>
|
||||
<ColumnsTitleWithAction
|
||||
columns={[
|
||||
{
|
||||
title: I18n.t('workflow_detail_variable_input_name'),
|
||||
style: {
|
||||
flex: 2,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: I18n.t('workflow_detail_variable_input_value'),
|
||||
style: {
|
||||
flex: 3,
|
||||
},
|
||||
},
|
||||
]}
|
||||
readonly={readonly}
|
||||
/>
|
||||
</div>
|
||||
{field.map((child, index) => (
|
||||
<div key={child.key} className={s['input-item']}>
|
||||
<Field name={`${child.name}.name`}>
|
||||
{({
|
||||
field: childNameField,
|
||||
fieldState: childNameState,
|
||||
}: FieldRenderProps<string>) => (
|
||||
<div
|
||||
style={{
|
||||
flex: 2,
|
||||
}}
|
||||
>
|
||||
<NodeInputName
|
||||
{...childNameField}
|
||||
input={form.getValueIn<RefExpression>(
|
||||
`${child.name}.input`,
|
||||
)}
|
||||
inputParameters={field.value || []}
|
||||
isError={!!childNameState?.errors?.length}
|
||||
/>
|
||||
<FormItemFeedback errors={childNameState?.errors} />
|
||||
</div>
|
||||
)}
|
||||
</Field>
|
||||
<Field name={`${child.name}.input`}>
|
||||
{({
|
||||
field: childInputField,
|
||||
fieldState: childInputState,
|
||||
}: FieldRenderProps<ValueExpression | undefined>) => (
|
||||
<div style={{ flex: 3, overflow: 'hidden' }}>
|
||||
<ValueExpressionInput
|
||||
{...childInputField}
|
||||
key="ValueExpressionInput"
|
||||
literalDisabled={false}
|
||||
disabledTypes={ViewVariableType.getComplement(
|
||||
ViewVariableType.getAllArrayType(),
|
||||
)}
|
||||
/>
|
||||
<FormItemFeedback errors={childInputState?.errors} />
|
||||
</div>
|
||||
)}
|
||||
</Field>
|
||||
{readonly ? (
|
||||
<></>
|
||||
) : (
|
||||
<div className="leading-none">
|
||||
<IconButton
|
||||
size="small"
|
||||
color="secondary"
|
||||
disabled={disableDelete}
|
||||
data-testid={concatTestId(child.name, 'remove')}
|
||||
icon={<IconCozMinus />}
|
||||
onClick={() => {
|
||||
if (disableDelete) {
|
||||
return;
|
||||
}
|
||||
field.delete(index);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
|
||||
<div className={s['input-add-icon']}>
|
||||
<IconButton
|
||||
className="!block"
|
||||
color="highlight"
|
||||
size="small"
|
||||
icon={<IconCozPlus />}
|
||||
onClick={() => {
|
||||
field.append({
|
||||
id: `${field.value?.length ?? 0}`,
|
||||
name: '',
|
||||
input: { type: ValueExpressionType.REF },
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</FormCard>
|
||||
);
|
||||
}}
|
||||
</FieldArray>
|
||||
</div>
|
||||
) : null;
|
||||
};
|
||||
@@ -0,0 +1,85 @@
|
||||
/* stylelint-disable max-nesting-depth */
|
||||
/* stylelint-disable no-descending-specificity */
|
||||
|
||||
.batch-container {
|
||||
.input-item {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 4px;
|
||||
align-items: flex-start;
|
||||
|
||||
margin-bottom: 8px;
|
||||
|
||||
.input-item-name {
|
||||
width: 100px;
|
||||
margin-right: 16px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.input-item-input {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.input-add-icon {
|
||||
position: absolute;
|
||||
top: 14px;
|
||||
right: 0
|
||||
}
|
||||
}
|
||||
|
||||
.batch-content {
|
||||
padding: 12px 0 0;
|
||||
}
|
||||
|
||||
|
||||
.del {
|
||||
cursor: pointer;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
height: 32px;
|
||||
|
||||
.icon {
|
||||
padding: 4px;
|
||||
|
||||
&.disabled {
|
||||
cursor: not-allowed;
|
||||
color: var(--semi-color-disabled-text);
|
||||
|
||||
>svg {
|
||||
>path {
|
||||
fill: var(--semi-color-disabled-text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
>svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
color: var(--light-usage-text-color-text-3, rgb(28 29 35 / 35%));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.columns-title{
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
.action-button-content {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.batch-form-card {
|
||||
:global(.custom-action-button) {
|
||||
margin-right: 32px;
|
||||
}
|
||||
|
||||
:global(.array-render-rehaje-add-btn) {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 12px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/* stylelint-disable declaration-no-important */
|
||||
/* stylelint-disable selector-class-pattern */
|
||||
|
||||
// lineHeight: 每一行的高度
|
||||
@lineHeight: 16px;
|
||||
// reserved: 多行场景需要多留出一点高度,便于用户感知到还有其他行
|
||||
@reserved: 12px;
|
||||
|
||||
.setMinRows(@minRows) {
|
||||
&-minRows-@{minRows} {
|
||||
&>div[data-slate-editor="true"] {
|
||||
min-height: unit(@minRows * @lineHeight + @reserved, px) !important;
|
||||
}
|
||||
}
|
||||
|
||||
&-cmMinRows-@{minRows} {
|
||||
min-height: unit(@minRows * @lineHeight + @reserved, px) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.expression-editor-container {
|
||||
position: relative;
|
||||
|
||||
display: inline-block;
|
||||
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
|
||||
word-break: break-all;
|
||||
vertical-align: bottom;
|
||||
|
||||
background-color: var(--semi-color-white);
|
||||
border: 1px solid var(--Stroke-COZ-stroke-plus, rgba(84, 97, 156, 27%));
|
||||
border-radius: var(--small, 6px);
|
||||
|
||||
transition: background-color var(--semi-transition_duration-none) var(--semi-transition_function-easeIn) var(--semi-transition_delay-none), border var(--semi-transition_duration-none) var(--semi-transition_function-easeIn) var(--semi-transition_delay-none);
|
||||
|
||||
.editor-render {
|
||||
cursor: text;
|
||||
resize: none;
|
||||
|
||||
position: relative;
|
||||
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
padding: 5px 12px;
|
||||
|
||||
font-family: "SF Pro Display", -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
color: var(--semi-color-text-0);
|
||||
vertical-align: bottom;
|
||||
|
||||
background-color: transparent;
|
||||
border: 0 solid transparent;
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
|
||||
&-bottom-padding {
|
||||
padding: 5px 12px 22px;
|
||||
}
|
||||
|
||||
&-minRows-1 {
|
||||
&>div[data-slate-editor="true"] {
|
||||
min-height: unit(@lineHeight, px) !important;
|
||||
}
|
||||
}
|
||||
|
||||
&-cm-content {
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
&-cmMinRows-1 {
|
||||
min-height: unit(@lineHeight, px) !important;
|
||||
}
|
||||
|
||||
// 根据最小行数预设最小高度
|
||||
.setMinRows(2);
|
||||
.setMinRows(3);
|
||||
.setMinRows(4);
|
||||
.setMinRows(5);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.expression-editor-error {
|
||||
border: 1px var(--semi-color-danger) solid !important;
|
||||
}
|
||||
|
||||
.expression-editor-focused {
|
||||
border: 1px var(--semi-color-primary) solid;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
type FC,
|
||||
} from 'react';
|
||||
|
||||
import { debounce } from 'lodash-es';
|
||||
import classNames from 'classnames';
|
||||
import { SelectorBoxConfigEntity } from '@flowgram-adapter/free-layout-editor';
|
||||
import { useEntity } from '@flowgram-adapter/free-layout-editor';
|
||||
import {
|
||||
ExpressionEditorCounter,
|
||||
ExpressionEditorEvent,
|
||||
ExpressionEditorModel,
|
||||
type ExpressionEditorTreeNode,
|
||||
Expression,
|
||||
} from '@coze-workflow/components';
|
||||
import { type InputValueVO, useNodeTestId } from '@coze-workflow/base';
|
||||
|
||||
import { useParseText, useVariableTree } from '../hooks';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
export interface ExpressionEditorContainerProps {
|
||||
name: string;
|
||||
value: string;
|
||||
key?: string;
|
||||
placeholder?: string | (() => string);
|
||||
readonly?: boolean;
|
||||
disableSuggestion?: boolean;
|
||||
disableCounter?: boolean;
|
||||
onChange?: (value: string) => void;
|
||||
minRows?: number;
|
||||
maxLength?: number;
|
||||
onBlur?: () => void;
|
||||
onFocus?: () => void;
|
||||
isError?: boolean;
|
||||
inputParameters?: InputValueVO[];
|
||||
className?: string;
|
||||
containerClassName?: string;
|
||||
shouldUseContainerRef?: boolean;
|
||||
testId?: string;
|
||||
onChangeTrigger?: 'onChange' | 'onBlur';
|
||||
}
|
||||
|
||||
/**
|
||||
* 业务逻辑和编辑器逻辑的聚合层
|
||||
*/
|
||||
export const ExpressionEditorContainer: FC<
|
||||
ExpressionEditorContainerProps
|
||||
> = props => {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const {
|
||||
name,
|
||||
key,
|
||||
onChange,
|
||||
onBlur,
|
||||
onFocus,
|
||||
isError,
|
||||
readonly = false,
|
||||
disableSuggestion = false,
|
||||
disableCounter = true,
|
||||
minRows = 4,
|
||||
className,
|
||||
containerClassName,
|
||||
shouldUseContainerRef,
|
||||
testId,
|
||||
onChangeTrigger = 'onBlur',
|
||||
} = props;
|
||||
const maxLength = undefined; // 临时禁用
|
||||
const variableTree: ExpressionEditorTreeNode[] = useVariableTree();
|
||||
const [focus, _setFocus] = useState<boolean>(false);
|
||||
const { getNodeSetterId } = useNodeTestId();
|
||||
|
||||
const selectorBoxConfig = useEntity<SelectorBoxConfigEntity>(
|
||||
SelectorBoxConfigEntity,
|
||||
);
|
||||
|
||||
const [curEditorVal, setCurEditorVal] = useState<string>(props.value || '');
|
||||
|
||||
const placeholder = useParseText(props.placeholder);
|
||||
const dataTestID = getNodeSetterId(testId ?? name);
|
||||
const formValue: string = props.value || '';
|
||||
const [model] = useState<ExpressionEditorModel>(
|
||||
() => new ExpressionEditorModel(formValue),
|
||||
);
|
||||
model.setVariableTree(variableTree);
|
||||
model.setFocus(focus);
|
||||
|
||||
// 设置防抖防止 onFocus / onBlur 在点击时出现抖动
|
||||
const setFocus = useCallback(
|
||||
debounce((newFocusValue: boolean) => {
|
||||
_setFocus(newFocusValue);
|
||||
}, 50),
|
||||
[],
|
||||
);
|
||||
|
||||
const overflow = useMemo(() => {
|
||||
if (typeof maxLength !== 'number') {
|
||||
return false;
|
||||
}
|
||||
return model.value.length > maxLength;
|
||||
}, [model.value.length, maxLength]);
|
||||
|
||||
useEffect(() => {
|
||||
const disposer = model.on<ExpressionEditorEvent.Change>(
|
||||
ExpressionEditorEvent.Change,
|
||||
params => {
|
||||
onChange && onChange(params.value);
|
||||
},
|
||||
);
|
||||
return () => {
|
||||
disposer();
|
||||
};
|
||||
}, [onChange]);
|
||||
|
||||
function handlePopoverVisibilityChange(visible: boolean) {
|
||||
if (visible) {
|
||||
selectorBoxConfig.disabled = true;
|
||||
} else {
|
||||
selectorBoxConfig.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 存在输入中文时 value 和 editor.getValue() 始终不一致,导致重渲染的情况
|
||||
* 所以改为 onBlur 时更新表单数据
|
||||
*/
|
||||
const handleOnBlur = () => {
|
||||
if (onChangeTrigger === 'onBlur') {
|
||||
onChange?.(curEditorVal);
|
||||
}
|
||||
setFocus(false);
|
||||
onBlur?.();
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
key={key}
|
||||
className={classNames(
|
||||
containerClassName,
|
||||
styles['expression-editor-container'],
|
||||
{
|
||||
[styles['expression-editor-focused']]: focus,
|
||||
[styles['expression-editor-error']]: isError || overflow,
|
||||
},
|
||||
)}
|
||||
onFocus={() => {
|
||||
setFocus(true);
|
||||
onFocus?.();
|
||||
}}
|
||||
onBlur={handleOnBlur}
|
||||
ref={containerRef}
|
||||
>
|
||||
<Expression.EditorProvider>
|
||||
<Expression.Renderer
|
||||
value={formValue}
|
||||
variableTree={variableTree}
|
||||
className={classNames(
|
||||
className,
|
||||
styles['editor-render'],
|
||||
styles['editor-render-cm-content'],
|
||||
styles[`editor-render-cmMinRows-${minRows}`],
|
||||
{
|
||||
[styles['editor-render-bottom-padding']]:
|
||||
!disableCounter || overflow,
|
||||
},
|
||||
)}
|
||||
readonly={readonly}
|
||||
placeholder={placeholder}
|
||||
dataTestID={dataTestID}
|
||||
onChange={v => {
|
||||
onChangeTrigger === 'onBlur' ? setCurEditorVal(v) : onChange?.(v);
|
||||
}}
|
||||
/>
|
||||
{readonly || disableSuggestion ? null : (
|
||||
<Expression.Popover
|
||||
variableTree={variableTree}
|
||||
getPopupContainer={() =>
|
||||
shouldUseContainerRef
|
||||
? (containerRef.current ?? document.body)
|
||||
: document.body
|
||||
}
|
||||
onVisibilityChange={handlePopoverVisibilityChange}
|
||||
/>
|
||||
)}
|
||||
</Expression.EditorProvider>
|
||||
|
||||
<ExpressionEditorCounter
|
||||
model={model}
|
||||
maxLength={maxLength}
|
||||
disabled={disableCounter && !overflow}
|
||||
isError={overflow}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import {
|
||||
type ExpressionEditorTreeNode,
|
||||
ExpressionEditorTreeHelper,
|
||||
} from '@coze-workflow/components';
|
||||
import { useWorkflowNode } from '@coze-workflow/base';
|
||||
|
||||
import { convertInputs } from '@/form-extensions/setters/expression-editor/utils/convert-inputs';
|
||||
import { useNodeAvailableVariablesWithNode } from '@/form-extensions/hooks';
|
||||
|
||||
const useInputs = (): {
|
||||
name: string;
|
||||
keyPath?: string[];
|
||||
}[] => {
|
||||
const workflowNode = useWorkflowNode();
|
||||
const inputs = workflowNode?.inputParameters ?? [];
|
||||
return convertInputs(inputs);
|
||||
};
|
||||
|
||||
export const useVariableTree = (): ExpressionEditorTreeNode[] => {
|
||||
const variables = useNodeAvailableVariablesWithNode();
|
||||
const inputs = useInputs();
|
||||
|
||||
const availableVariables = ExpressionEditorTreeHelper.findAvailableVariables({
|
||||
variables,
|
||||
inputs,
|
||||
});
|
||||
|
||||
const variableTree =
|
||||
ExpressionEditorTreeHelper.createVariableTree(availableVariables);
|
||||
return variableTree;
|
||||
};
|
||||
|
||||
export const useParseText = (
|
||||
text?: string | (() => string),
|
||||
): string | undefined =>
|
||||
useMemo((): string | undefined => {
|
||||
if (!text) {
|
||||
return;
|
||||
}
|
||||
if (typeof text === 'string') {
|
||||
return text;
|
||||
}
|
||||
if (typeof text === 'function') {
|
||||
return text();
|
||||
}
|
||||
return;
|
||||
}, [text]);
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useReadonly } from '@/nodes-v2/hooks/use-readonly';
|
||||
import { type ComponentProps } from '@/nodes-v2/components/types';
|
||||
|
||||
import {
|
||||
ExpressionEditorContainer,
|
||||
type ExpressionEditorContainerProps,
|
||||
} from './container';
|
||||
|
||||
export type ExpressionEditorProps = ComponentProps<string> &
|
||||
ExpressionEditorContainerProps;
|
||||
|
||||
export const ExpressionEditor = (props: ExpressionEditorProps) => {
|
||||
const readonly = useReadonly();
|
||||
|
||||
return <ExpressionEditorContainer {...props} readonly={readonly} />;
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import type { Validate } from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
interface CreateExpressionEditorValidatorOptions {
|
||||
maxLength?: number;
|
||||
}
|
||||
|
||||
export const createExpressionEditorValidator =
|
||||
(options?: CreateExpressionEditorValidatorOptions): Validate<string> =>
|
||||
({ value }): string | undefined => {
|
||||
if (!value) {
|
||||
return I18n.t('workflow_detail_node_error_empty');
|
||||
}
|
||||
const { maxLength } = options || {};
|
||||
|
||||
if (maxLength && value.length > maxLength) {
|
||||
return I18n.t('workflow_derail_node_detail_title_max', {
|
||||
max: maxLength,
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
Field,
|
||||
FieldArray,
|
||||
type FieldArrayRenderProps,
|
||||
type FieldRenderProps,
|
||||
} from '@flowgram-adapter/free-layout-editor';
|
||||
import { variableUtils } from '@coze-workflow/variable';
|
||||
import {
|
||||
ViewVariableType,
|
||||
type InputValueVO,
|
||||
type ValueExpression,
|
||||
type VariableTypeDTO,
|
||||
} from '@coze-workflow/base';
|
||||
|
||||
import { ValueExpressionInput } from '@/nodes-v2/components/value-expression-input';
|
||||
import { FormItemFeedback } from '@/nodes-v2/components/form-item-feedback';
|
||||
import { FormCard } from '@/form-extensions/components/form-card';
|
||||
import { ColumnsTitle } from '@/form-extensions/components/columns-title';
|
||||
|
||||
import InputLabel from '../input-label';
|
||||
|
||||
export interface FixedInputParametersProps {
|
||||
fieldName?: string;
|
||||
defaultValue?: InputValueVO[];
|
||||
headerTitle: string;
|
||||
headerTootip: string;
|
||||
columns?: {
|
||||
title: string;
|
||||
style: React.CSSProperties;
|
||||
}[];
|
||||
fieldConfig?: Record<
|
||||
string,
|
||||
{
|
||||
description: string;
|
||||
name: string;
|
||||
required: boolean;
|
||||
type: string;
|
||||
optionsList?: {
|
||||
label: string;
|
||||
value: string;
|
||||
}[];
|
||||
}
|
||||
>;
|
||||
readonly?: boolean;
|
||||
}
|
||||
|
||||
const FixedInputParameters = (props: FixedInputParametersProps) => {
|
||||
const {
|
||||
fieldName = 'inputParameters',
|
||||
defaultValue = [],
|
||||
headerTitle,
|
||||
headerTootip,
|
||||
columns,
|
||||
fieldConfig = {},
|
||||
readonly = false,
|
||||
} = props;
|
||||
return (
|
||||
<FieldArray name={fieldName} defaultValue={defaultValue}>
|
||||
{({ field: _field }: FieldArrayRenderProps<InputValueVO>) => (
|
||||
<>
|
||||
<FormCard header={headerTitle} tooltip={headerTootip}>
|
||||
<div className="pb-[8px]">
|
||||
<ColumnsTitle columns={columns ?? []} />
|
||||
</div>
|
||||
|
||||
{Object.keys(fieldConfig).map((_fieldName, index) => (
|
||||
<div
|
||||
key={_fieldName}
|
||||
className="array-item-wrapper flex items-start pb-[8px]"
|
||||
>
|
||||
<div className={'w-[140px]'}>
|
||||
<InputLabel
|
||||
required={fieldConfig[_fieldName]?.required}
|
||||
label={fieldConfig[_fieldName]?.name}
|
||||
tooltip={fieldConfig[_fieldName]?.description}
|
||||
tootipIconClassName="coz-fg-secondary"
|
||||
tag={null}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Field name={`inputParameters.${index}.input`}>
|
||||
{({
|
||||
field: childField,
|
||||
fieldState: childState,
|
||||
}: FieldRenderProps<ValueExpression | undefined>) => (
|
||||
<div className="flex-1 min-w-0">
|
||||
<ValueExpressionInput
|
||||
{...childField}
|
||||
readonly={readonly}
|
||||
disabledTypes={ViewVariableType.getComplement([
|
||||
variableUtils.DTOTypeToViewType(
|
||||
fieldConfig[_fieldName].type as VariableTypeDTO,
|
||||
),
|
||||
])}
|
||||
literalConfig={{
|
||||
// 下拉选择数据源
|
||||
optionsList: fieldConfig[_fieldName]?.optionsList,
|
||||
}}
|
||||
isError={!!childState?.errors?.length}
|
||||
/>
|
||||
<FormItemFeedback errors={childState?.errors} />
|
||||
</div>
|
||||
)}
|
||||
</Field>
|
||||
</div>
|
||||
))}
|
||||
</FormCard>
|
||||
</>
|
||||
)}
|
||||
</FieldArray>
|
||||
);
|
||||
};
|
||||
|
||||
export default FixedInputParameters;
|
||||
@@ -0,0 +1,7 @@
|
||||
.form-item-error {
|
||||
font-family: "SF Pro Display",-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Hiragino Sans GB","Microsoft YaHei","Helvetica Neue",Helvetica,Arial,sans-serif;
|
||||
font-size: var(--coze-12);
|
||||
line-height: 16px;
|
||||
color: var(--semi-color-danger)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import classnames from 'classnames';
|
||||
import {
|
||||
type FieldState,
|
||||
type FieldError,
|
||||
type FieldWarning,
|
||||
} from '@flowgram-adapter/free-layout-editor';
|
||||
import { type WithCustomStyle } from '@coze-workflow/base/types';
|
||||
|
||||
import s from './index.module.less';
|
||||
|
||||
export interface FormItemErrorProps extends WithCustomStyle {
|
||||
errors?: FieldState['errors'];
|
||||
// coze 暂无warnings
|
||||
// warnings?: FieldState['warnings'];
|
||||
}
|
||||
|
||||
export const FormItemFeedback = ({
|
||||
errors,
|
||||
className,
|
||||
style,
|
||||
}: FormItemErrorProps) => {
|
||||
const renderFeedbacks = (fs: FieldError[] | FieldWarning[]) =>
|
||||
fs.map(f => <span key={f.field}>{f.message}</span>);
|
||||
return errors ? (
|
||||
<div className={classnames(s.formItemError, className)} style={style}>
|
||||
{renderFeedbacks(errors)}
|
||||
</div>
|
||||
) : null;
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
.global-var-option {
|
||||
:global .option-text-wrapper {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.tag {
|
||||
height: 16px;
|
||||
margin-left: 8px;
|
||||
padding: 1px 4px;
|
||||
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
line-height: 14px;
|
||||
color: rgba(6, 7, 9, 80%);
|
||||
|
||||
background: rgba(6, 7, 9, 8%);
|
||||
}
|
||||
}
|
||||
|
||||
.empty-block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
box-sizing: border-box;
|
||||
padding: 40px 0;
|
||||
|
||||
.text {
|
||||
margin-top: 10px;
|
||||
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
color: rgba(52, 60, 87, 72%);
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, {
|
||||
type CSSProperties,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useCallback,
|
||||
useRef,
|
||||
} from 'react';
|
||||
|
||||
import { get } from 'lodash-es';
|
||||
import { useService } from '@flowgram-adapter/free-layout-editor';
|
||||
import {
|
||||
type RefExpression,
|
||||
WorkflowVariableService,
|
||||
useGlobalVariableServiceState,
|
||||
isGlobalVariableKey,
|
||||
} from '@coze-workflow/variable';
|
||||
import {
|
||||
type ViewVariableType,
|
||||
ValueExpressionType,
|
||||
VARIABLE_TYPE_ALIAS_MAP,
|
||||
} from '@coze-workflow/base';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { type Select as SemiSelect } from '@coze-arch/bot-semi';
|
||||
import {
|
||||
IconCozCross,
|
||||
IconCozEmpty,
|
||||
IconCozWarningCircle,
|
||||
} from '@coze-arch/coze-design/icons';
|
||||
import { Select, Tag, Typography } from '@coze-arch/coze-design';
|
||||
|
||||
import { useReadonly } from '@/nodes-v2/hooks/use-readonly';
|
||||
import { useGlobalState } from '@/hooks';
|
||||
import { type VariableMetaWithNode } from '@/form-extensions/typings';
|
||||
import { useNodeAvailableVariablesWithNode } from '@/form-extensions/hooks';
|
||||
import { BotProjectVariableSelect } from '@/components/test-run/bot-project-variable-select';
|
||||
import { VARIABLE_TYPE_ICON_MAP } from '@/components/node-render/node-render-new/fields/constants';
|
||||
|
||||
import s from './index.module.less';
|
||||
|
||||
const { Text } = Typography;
|
||||
|
||||
interface Props {
|
||||
value?: RefExpression;
|
||||
onChange?: (value?: RefExpression) => void;
|
||||
disabled?: boolean;
|
||||
readonly?: boolean;
|
||||
style?: CSSProperties;
|
||||
onBlur?: () => void;
|
||||
name?: string;
|
||||
placeholder?: string;
|
||||
disabledTypes?: ViewVariableType[];
|
||||
isError?: boolean;
|
||||
variablesFilter?: (
|
||||
variables: VariableMetaWithNode[],
|
||||
) => VariableMetaWithNode[];
|
||||
useMatchType?: boolean;
|
||||
matchType?: ViewVariableType;
|
||||
}
|
||||
|
||||
type ValueType = string[];
|
||||
|
||||
const encodeValue = (data?: ValueType) =>
|
||||
data ? JSON.stringify(data) : undefined;
|
||||
|
||||
const decodeValue = (data: string) =>
|
||||
data ? (JSON.parse(data) as ValueType) : undefined;
|
||||
|
||||
const getIconByType = (type?: ViewVariableType) =>
|
||||
type ? (
|
||||
VARIABLE_TYPE_ICON_MAP[type] || <IconCozWarningCircle />
|
||||
) : (
|
||||
<IconCozWarningCircle />
|
||||
);
|
||||
|
||||
export const GlobalVariableSelect = (props: Props) => {
|
||||
const {
|
||||
value,
|
||||
onChange,
|
||||
onBlur,
|
||||
readonly: setterReadonly,
|
||||
placeholder = I18n.t('variable_assignment_node_select_placeholder'),
|
||||
disabledTypes,
|
||||
isError,
|
||||
variablesFilter = data => data,
|
||||
matchType,
|
||||
useMatchType,
|
||||
} = props;
|
||||
|
||||
const selectRef = useRef<SemiSelect | null>(null);
|
||||
|
||||
const globalReadonly = useReadonly();
|
||||
const readonly = globalReadonly || setterReadonly;
|
||||
|
||||
const { projectId } = useGlobalState();
|
||||
const { type } = useGlobalVariableServiceState();
|
||||
|
||||
const isProject = Boolean(projectId);
|
||||
const isSelectedBotOrProject = !isProject && Boolean(type);
|
||||
|
||||
const useNewGlobalVariableCache = !isProject;
|
||||
|
||||
const availableVariables = useNodeAvailableVariablesWithNode();
|
||||
|
||||
const variableService: WorkflowVariableService = useService(
|
||||
WorkflowVariableService,
|
||||
);
|
||||
|
||||
const keyPath = get(value, 'content.keyPath') as string[] | undefined;
|
||||
|
||||
// 监听联动变量变化,从而重新触发 effect
|
||||
useEffect(() => {
|
||||
const hasDisabledTypes =
|
||||
Array.isArray(disabledTypes) && disabledTypes.length > 0;
|
||||
|
||||
if (!keyPath || !hasDisabledTypes) {
|
||||
return;
|
||||
}
|
||||
|
||||
const listener = variableService.onListenVariableTypeChange(
|
||||
keyPath,
|
||||
v => {
|
||||
// 如果变量类型变化后,位于 disabledTypes 中,那么需要清空
|
||||
if (v && (disabledTypes || []).includes(v.type)) {
|
||||
onChange?.({
|
||||
type: ValueExpressionType.REF,
|
||||
});
|
||||
}
|
||||
},
|
||||
{},
|
||||
);
|
||||
|
||||
return () => {
|
||||
listener?.dispose();
|
||||
};
|
||||
}, [keyPath, variableService, onChange, disabledTypes]);
|
||||
|
||||
const optionList = useMemo(
|
||||
() =>
|
||||
variablesFilter(
|
||||
availableVariables.filter(
|
||||
item => item.nodeId && isGlobalVariableKey(item.nodeId),
|
||||
),
|
||||
).map(item => ({
|
||||
value: encodeValue([item.nodeId as string, item.key]),
|
||||
disabled: useMatchType && matchType && matchType !== item.type,
|
||||
...item,
|
||||
})),
|
||||
[availableVariables, variablesFilter, matchType, useMatchType],
|
||||
);
|
||||
|
||||
const handleChange = useCallback(
|
||||
(v): void => {
|
||||
const data = v ? decodeValue(v) : undefined;
|
||||
|
||||
if (data === undefined) {
|
||||
onChange?.(undefined);
|
||||
} else {
|
||||
onChange?.({
|
||||
type: ValueExpressionType.REF,
|
||||
content: { keyPath: data },
|
||||
});
|
||||
}
|
||||
},
|
||||
[onChange],
|
||||
);
|
||||
|
||||
const emptyContent = useMemo(() => {
|
||||
const getEmptyMsg = () => {
|
||||
if (isProject) {
|
||||
return I18n.t('variable_select_empty_appide_tips');
|
||||
}
|
||||
|
||||
if (isSelectedBotOrProject) {
|
||||
return I18n.t('variable_select_empty_library_tips_02');
|
||||
}
|
||||
|
||||
return I18n.t('variable_select_empty_library_tips');
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={s['empty-block']}>
|
||||
<IconCozEmpty
|
||||
style={{ fontSize: '32px', color: 'rgba(52, 60, 87, 0.72)' }}
|
||||
/>
|
||||
<span className={s.text}>{getEmptyMsg()}</span>
|
||||
</div>
|
||||
);
|
||||
}, [isProject, isSelectedBotOrProject]);
|
||||
|
||||
const handleVariableSelect = useCallback(
|
||||
(v?: string) => {
|
||||
handleChange(v);
|
||||
selectRef.current?.close();
|
||||
},
|
||||
[handleChange],
|
||||
);
|
||||
|
||||
return (
|
||||
<Select
|
||||
ref={selectRef}
|
||||
hasError={isError}
|
||||
dropdownStyle={{
|
||||
width: useNewGlobalVariableCache ? '326px' : '228px',
|
||||
}}
|
||||
showClear
|
||||
size={'small'}
|
||||
disabled={readonly}
|
||||
clearIcon={<IconCozCross style={{ fontSize: '12px' }} />}
|
||||
emptyContent={useNewGlobalVariableCache ? null : emptyContent}
|
||||
value={encodeValue(value?.content?.keyPath)}
|
||||
onChange={handleChange}
|
||||
onBlur={onBlur}
|
||||
style={{
|
||||
width: '100%',
|
||||
}}
|
||||
placeholder={placeholder}
|
||||
renderSelectedItem={item => {
|
||||
const selectedItem = optionList.find(op => op.value === item.value);
|
||||
|
||||
return (
|
||||
<div className={'flex items-center'}>
|
||||
<span
|
||||
className={'flex items-center mr-4px'}
|
||||
style={{
|
||||
fontSize: '14px',
|
||||
color: selectedItem?.name
|
||||
? 'rgba(var(--coze-fg-1),var(--coze-fg-1-alpha))'
|
||||
: 'rgba(var(--coze-yellow-5), 1)',
|
||||
}}
|
||||
>
|
||||
{getIconByType(selectedItem?.type)}
|
||||
</span>
|
||||
<span
|
||||
style={{
|
||||
color: selectedItem?.name
|
||||
? 'rgba(var(--coze-fg-3),var(--coze-fg-3-alpha))'
|
||||
: 'rgba(var(--coze-yellow-5), 1)',
|
||||
}}
|
||||
>
|
||||
{selectedItem?.name || I18n.t('workflow_variable_undefined')}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
outerBottomSlot={
|
||||
useNewGlobalVariableCache ? (
|
||||
<BotProjectVariableSelect
|
||||
onVariableSelect={handleVariableSelect}
|
||||
variableValue={encodeValue(value?.content?.keyPath)}
|
||||
variablesFormatter={arr =>
|
||||
variablesFilter(
|
||||
arr.map(item => ({
|
||||
value: encodeValue([item.nodeId as string, item.key]),
|
||||
disabled:
|
||||
useMatchType && matchType && matchType !== item.type,
|
||||
...item,
|
||||
})),
|
||||
)
|
||||
}
|
||||
/>
|
||||
) : undefined
|
||||
}
|
||||
>
|
||||
{useNewGlobalVariableCache
|
||||
? null
|
||||
: optionList.map(option => (
|
||||
<Select.Option
|
||||
// disabled 变化 Option 不会重新渲染,先通过设置 key 的方式兼容一下
|
||||
key={`${option.value}-${option.disabled}`}
|
||||
value={option.value}
|
||||
className={s['global-var-option']}
|
||||
disabled={option.disabled}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex w-full items-center justify-between pl-8px pr-8px'
|
||||
}
|
||||
>
|
||||
<Text
|
||||
disabled={option.disabled}
|
||||
ellipsis={{ showTooltip: true }}
|
||||
style={{ flex: 1 }}
|
||||
>
|
||||
{option.name}
|
||||
</Text>
|
||||
<Tag
|
||||
disabled={option.disabled}
|
||||
className={s.tag}
|
||||
size={'small'}
|
||||
>
|
||||
{VARIABLE_TYPE_ALIAS_MAP[option.type]}
|
||||
</Tag>
|
||||
</div>
|
||||
</Select.Option>
|
||||
))}
|
||||
</Select>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export const nameValidationRule =
|
||||
/^(?!.*\b(true|false|and|AND|or|OR|not|NOT|null|nil|If|Switch)\b)[a-zA-Z_][a-zA-Z_$0-9]*$/;
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type ReactNode, type CSSProperties } from 'react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
import { IconInfo } from '@coze-arch/bot-icons';
|
||||
|
||||
import AutoSizeTooltip from '@/ui-components/auto-size-tooltip';
|
||||
|
||||
export interface InputLabelProps {
|
||||
required?: boolean;
|
||||
hideRequiredTag?: boolean;
|
||||
label: ReactNode;
|
||||
tooltip?: ReactNode;
|
||||
tag?: ReactNode;
|
||||
className?: string;
|
||||
labelStyle?: CSSProperties;
|
||||
labelClassName?: string;
|
||||
tootipPopoverClassName?: string;
|
||||
tootipIconClassName?: string;
|
||||
}
|
||||
|
||||
const InputLabel = ({
|
||||
required,
|
||||
hideRequiredTag = false,
|
||||
label,
|
||||
tooltip,
|
||||
tag,
|
||||
labelStyle = {
|
||||
fontSize: 12,
|
||||
marginRight: 0,
|
||||
},
|
||||
className,
|
||||
labelClassName,
|
||||
tootipPopoverClassName,
|
||||
tootipIconClassName,
|
||||
}: InputLabelProps) => (
|
||||
<div className={classNames('flex mr-2 items-baseline', className)}>
|
||||
<div className="flex overflow-hidden">
|
||||
<AutoSizeTooltip
|
||||
content={label}
|
||||
showArrow
|
||||
position="top"
|
||||
className="flex-1 grow-1 truncate"
|
||||
>
|
||||
<span
|
||||
className={classNames('flex-1 grow-1 truncate', labelClassName)}
|
||||
style={labelStyle}
|
||||
>
|
||||
{label}
|
||||
</span>
|
||||
</AutoSizeTooltip>
|
||||
|
||||
{required && !hideRequiredTag ? (
|
||||
<span
|
||||
style={{ color: 'var(--light-usage-danger-color-danger,#f93920)' }}
|
||||
>
|
||||
*
|
||||
</span>
|
||||
) : null}
|
||||
{tooltip ? (
|
||||
<div className="ml-[4px] mt-[2px]">
|
||||
<AutoSizeTooltip
|
||||
showArrow
|
||||
position="top"
|
||||
className={tootipPopoverClassName}
|
||||
content={tooltip}
|
||||
>
|
||||
<IconInfo className={tootipIconClassName} />
|
||||
</AutoSizeTooltip>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
{tag ? <div className="flex-1 shrink-0 grow-1">{tag}</div> : null}
|
||||
</div>
|
||||
);
|
||||
|
||||
export default InputLabel;
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* 组件迁移自 packages/workflow/playground/src/form-extensions/setters/node-header
|
||||
* 仅做了对新版节点引擎接口适配
|
||||
*/
|
||||
import React from 'react';
|
||||
|
||||
import { type FieldError } from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
import { useReadonly } from '@/nodes-v2/hooks/use-readonly';
|
||||
import { type ComponentProps } from '@/nodes-v2/components/types';
|
||||
import { useGlobalState, useNodeRenderScene } from '@/hooks';
|
||||
import { NodeHeader as NodeHeaderComponent } from '@/form-extensions/components/node-header';
|
||||
|
||||
import { withValidation } from '../validation';
|
||||
|
||||
export interface NodeHeaderValue {
|
||||
title: string;
|
||||
icon: string;
|
||||
subTitle: string;
|
||||
description: string;
|
||||
}
|
||||
export type NodeHeaderProps = ComponentProps<NodeHeaderValue> & {
|
||||
errors?: FieldError[];
|
||||
readonly?: boolean;
|
||||
hideTest?: boolean;
|
||||
batchModePath?: string;
|
||||
outputsPath?: string;
|
||||
extraOperation?: React.ReactNode;
|
||||
showTrigger?: boolean;
|
||||
triggerIsOpen?: boolean;
|
||||
nodeDisabled?: boolean;
|
||||
readonlyAllowDeleteOperation?: boolean;
|
||||
};
|
||||
|
||||
export const NodeHeader = withValidation<NodeHeaderProps>(
|
||||
({
|
||||
value,
|
||||
onChange,
|
||||
onBlur,
|
||||
readonly = false,
|
||||
hideTest = false,
|
||||
extraOperation,
|
||||
showTrigger = false,
|
||||
triggerIsOpen = false,
|
||||
nodeDisabled,
|
||||
readonlyAllowDeleteOperation,
|
||||
}: NodeHeaderProps) => {
|
||||
const { title, icon, subTitle, description } = value || {};
|
||||
const workflowReadonly = useReadonly();
|
||||
const { projectId, projectCommitVersion } = useGlobalState();
|
||||
const { isNodeSideSheet } = useNodeRenderScene();
|
||||
|
||||
return (
|
||||
<NodeHeaderComponent
|
||||
title={title}
|
||||
subTitle={subTitle}
|
||||
// 如果是coze2.0新版节点渲染 隐藏掉描述
|
||||
description={description}
|
||||
logo={icon}
|
||||
onTitleChange={newTitle => {
|
||||
onChange({ ...value, title: newTitle });
|
||||
onBlur?.();
|
||||
}}
|
||||
onDescriptionChange={desc => {
|
||||
onChange({ ...value, description: desc });
|
||||
}}
|
||||
readonly={readonly || workflowReadonly}
|
||||
readonlyAllowDeleteOperation={
|
||||
workflowReadonly ? false : readonlyAllowDeleteOperation
|
||||
}
|
||||
hideTest={
|
||||
hideTest || IS_BOT_OP || !!(projectId && projectCommitVersion)
|
||||
}
|
||||
showTrigger={showTrigger}
|
||||
triggerIsOpen={triggerIsOpen}
|
||||
extraOperation={extraOperation}
|
||||
showCloseButton={isNodeSideSheet}
|
||||
nodeDisabled={nodeDisabled}
|
||||
/>
|
||||
);
|
||||
},
|
||||
);
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { NodeInputName } from './node-input-name';
|
||||
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import {
|
||||
useCurrentEntity,
|
||||
useService,
|
||||
} from '@flowgram-adapter/free-layout-editor';
|
||||
import { WorkflowVariableFacadeService } from '@coze-workflow/variable';
|
||||
import { useNodeTestId } from '@coze-workflow/base';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { IconCozInfoCircle } from '@coze-arch/coze-design/icons';
|
||||
import { Tooltip, Input, Typography } from '@coze-arch/coze-design';
|
||||
|
||||
import { useReadonly } from '@/nodes-v2/hooks/use-readonly';
|
||||
import {
|
||||
getVariableName,
|
||||
getUniqueName,
|
||||
} from '@/form-extensions/setters/node-input-name/utils';
|
||||
|
||||
import type { NodeInputNameProps } from './type';
|
||||
|
||||
// eslint-disable-next-line complexity
|
||||
export const NodeInputName = ({
|
||||
value,
|
||||
onChange,
|
||||
onBlur,
|
||||
name,
|
||||
style,
|
||||
input,
|
||||
inputParameters,
|
||||
initValidate = false,
|
||||
isPureText = false,
|
||||
prefix = '',
|
||||
suffix = '',
|
||||
format,
|
||||
tooltip,
|
||||
isError,
|
||||
inputPrefix,
|
||||
disabled,
|
||||
}: NodeInputNameProps) => {
|
||||
const [initialized, setInitialized] = useState<boolean>(false);
|
||||
const [userEdited, setUserEdited] = useState<boolean>(false);
|
||||
const [variableName, setVariableName] = useState<string | undefined>(value);
|
||||
const [text, setText] = useState<string | undefined>(value);
|
||||
const readonly = useReadonly();
|
||||
|
||||
const node = useCurrentEntity();
|
||||
const variableService = useService(WorkflowVariableFacadeService);
|
||||
const { getNodeSetterId } = useNodeTestId();
|
||||
|
||||
// text 状态受控(删除节点时联动 text 的值)
|
||||
useEffect(() => {
|
||||
if (value !== text) {
|
||||
setText(value);
|
||||
}
|
||||
}, [value]);
|
||||
|
||||
const computedVariableName = getVariableName({
|
||||
input,
|
||||
prefix,
|
||||
suffix,
|
||||
format,
|
||||
node,
|
||||
variableService,
|
||||
});
|
||||
|
||||
const onInputChange = useCallback((newInputValue: string): void => {
|
||||
setUserEdited(true);
|
||||
setText(newInputValue || '');
|
||||
setVariableName(undefined);
|
||||
}, []);
|
||||
|
||||
const handleOnBlur = () => {
|
||||
onChange(text || '');
|
||||
onBlur?.();
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (initValidate) {
|
||||
// 初始化写值触发校验
|
||||
onChange(value);
|
||||
onBlur?.();
|
||||
}
|
||||
if (value) {
|
||||
setUserEdited(true);
|
||||
}
|
||||
setInitialized(true);
|
||||
}, [initValidate, onChange, value]);
|
||||
|
||||
if (initialized && !readonly && !userEdited) {
|
||||
if (computedVariableName && computedVariableName !== variableName) {
|
||||
const computedUniqueName = getUniqueName({
|
||||
variableName: computedVariableName,
|
||||
inputParameters,
|
||||
});
|
||||
onChange(computedUniqueName);
|
||||
setVariableName(computedVariableName);
|
||||
setText(computedUniqueName);
|
||||
} else if (!computedVariableName && variableName) {
|
||||
setVariableName(undefined);
|
||||
setText(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex items-center"
|
||||
style={{
|
||||
...style,
|
||||
pointerEvents: readonly ? 'none' : 'auto',
|
||||
}}
|
||||
>
|
||||
{isPureText ? (
|
||||
<>
|
||||
<Typography.Text className="h-8 leading-8">{value}</Typography.Text>
|
||||
{tooltip ? (
|
||||
<Tooltip content={tooltip}>
|
||||
<IconCozInfoCircle
|
||||
className="ml-1"
|
||||
style={{
|
||||
fontSize: 12,
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
) : null}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Input
|
||||
size={'small'}
|
||||
data-testid={getNodeSetterId(name)}
|
||||
value={text}
|
||||
onChange={onInputChange}
|
||||
onBlur={handleOnBlur}
|
||||
validateStatus={isError ? 'error' : undefined}
|
||||
placeholder={I18n.t('workflow_detail_node_input_entername')}
|
||||
prefix={inputPrefix}
|
||||
disabled={disabled}
|
||||
/>
|
||||
{tooltip ? (
|
||||
<Tooltip content={tooltip}>
|
||||
<IconCozInfoCircle
|
||||
className="ml-1"
|
||||
style={{
|
||||
fontSize: 12,
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
) : null}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { CSSProperties } from 'react';
|
||||
|
||||
import type { InputValueVO, RefExpression } from '@coze-workflow/base';
|
||||
import { type InputProps } from '@coze-arch/coze-design';
|
||||
|
||||
import { type ComponentProps } from '@/nodes-v2/components/types';
|
||||
|
||||
export type NodeInputNameFormat = (params: {
|
||||
name: string;
|
||||
prefix: string;
|
||||
suffix: string;
|
||||
input: RefExpression;
|
||||
// context: SetterOrDecoratorContext;
|
||||
}) => string;
|
||||
|
||||
export type NodeInputNameProps = Omit<
|
||||
ComponentProps<string>,
|
||||
'inputParameters'
|
||||
> & {
|
||||
readonly?: boolean;
|
||||
initValidate?: boolean;
|
||||
isPureText?: boolean;
|
||||
style?: CSSProperties;
|
||||
/** 同一层的变量表达式 */
|
||||
input: RefExpression;
|
||||
/** 当前输入列表中所有输入项 */
|
||||
inputParameters: Array<InputValueVO>;
|
||||
/** 前缀 */
|
||||
prefix?: string;
|
||||
/** 后缀 */
|
||||
suffix?: string;
|
||||
/** 名称自定义格式化 */
|
||||
format?: NodeInputNameFormat;
|
||||
tooltip?: string;
|
||||
isError?: boolean;
|
||||
inputPrefix?: InputProps['prefix'];
|
||||
disabled?: boolean;
|
||||
};
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { type Validate } from '@flowgram-adapter/free-layout-editor';
|
||||
|
||||
import { nameValidationRule } from '../helpers';
|
||||
|
||||
export interface CreateNodeInputNameValidateOptions {
|
||||
getNames?: ({ value, formValues }) => string[];
|
||||
validatorConfig?: {
|
||||
rule?: RegExp;
|
||||
errorMessage?: string;
|
||||
};
|
||||
invalidValues?: Record<string, string>;
|
||||
skipValidate?: ({ value, formValues }) => boolean;
|
||||
}
|
||||
|
||||
const defaultGetNames = ({ formValues }) =>
|
||||
formValues.inputParameters.map(item => item.name);
|
||||
|
||||
export const createNodeInputNameValidate =
|
||||
(options?: CreateNodeInputNameValidateOptions): Validate =>
|
||||
({ value, formValues }) => {
|
||||
const {
|
||||
getNames = defaultGetNames,
|
||||
validatorConfig,
|
||||
invalidValues,
|
||||
skipValidate,
|
||||
} = options || {};
|
||||
if (skipValidate?.({ value, formValues })) {
|
||||
return;
|
||||
}
|
||||
|
||||
const validatorRule = validatorConfig?.rule ?? nameValidationRule;
|
||||
const validatorErrorMessage =
|
||||
validatorConfig?.errorMessage ??
|
||||
I18n.t('workflow_detail_node_error_format');
|
||||
|
||||
/** 命名校验 */
|
||||
if (!validatorRule.test(value)) {
|
||||
return validatorErrorMessage;
|
||||
}
|
||||
|
||||
/** 非法值校验 */
|
||||
if (invalidValues?.[value]) {
|
||||
return invalidValues[value];
|
||||
}
|
||||
|
||||
const names: string[] = getNames({ value, formValues });
|
||||
|
||||
const foundSames = names.filter((name: string) => name === value);
|
||||
|
||||
return foundSames.length > 1
|
||||
? I18n.t('workflow_detail_node_input_duplicated')
|
||||
: undefined;
|
||||
};
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
Field,
|
||||
type FieldRenderProps,
|
||||
useCurrentEntity,
|
||||
} from '@flowgram-adapter/free-layout-editor';
|
||||
import { WorkflowNode } from '@coze-workflow/base';
|
||||
|
||||
import { useDefaultNodeMeta } from '@/nodes-v2/hooks/use-default-node-meta';
|
||||
import { type NodeHeaderValue } from '@/nodes-v2/components/node-header';
|
||||
import { NodeHeader } from '@/nodes-v2/components/node-header';
|
||||
|
||||
interface NodeMetaProps {
|
||||
fieldName?: string;
|
||||
deps?: string[];
|
||||
outputsPath?: string;
|
||||
batchModePath?: string;
|
||||
}
|
||||
|
||||
const NodeMeta = ({
|
||||
fieldName = 'nodeMeta',
|
||||
deps,
|
||||
outputsPath,
|
||||
batchModePath,
|
||||
}: NodeMetaProps) => {
|
||||
const defaultNodeMeta = useDefaultNodeMeta();
|
||||
const node = useCurrentEntity();
|
||||
const wrappedNode = new WorkflowNode(node);
|
||||
|
||||
return (
|
||||
<Field
|
||||
name={fieldName}
|
||||
deps={deps}
|
||||
defaultValue={defaultNodeMeta as unknown as NodeHeaderValue}
|
||||
>
|
||||
{({ field, fieldState }: FieldRenderProps<NodeHeaderValue>) => (
|
||||
<NodeHeader
|
||||
{...field}
|
||||
outputsPath={outputsPath}
|
||||
batchModePath={batchModePath}
|
||||
hideTest={!!wrappedNode?.registry?.meta?.hideTest}
|
||||
errors={fieldState?.errors || []}
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
);
|
||||
};
|
||||
|
||||
export default NodeMeta;
|
||||
@@ -0,0 +1,19 @@
|
||||
.content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px 0;
|
||||
font-size: 12px;
|
||||
|
||||
|
||||
.tag {
|
||||
height: 16px;
|
||||
margin-left: 8px;
|
||||
padding: 1px 4px;
|
||||
|
||||
font-size: 12px;
|
||||
line-height: 14px;
|
||||
color: rgba(6, 7, 9, 80%);
|
||||
|
||||
background: rgba(6, 7, 9, 8%);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { type CSSProperties } from 'react';
|
||||
|
||||
import { Tag } from '@coze-arch/coze-design';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
interface Props {
|
||||
label?: string;
|
||||
type?: string;
|
||||
required?: boolean;
|
||||
style?: CSSProperties;
|
||||
}
|
||||
|
||||
export const OutputSingleText = ({ label, type, required, style }: Props) => (
|
||||
<p className={styles.content} style={style}>
|
||||
<span>{label}</span>
|
||||
{required ? <span style={{ color: '#f93920' }}>*</span> : null}
|
||||
{type ? <Tag className={styles.tag}>{type}</Tag> : null}
|
||||
</p>
|
||||
);
|
||||
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { useEffect, useMemo, useRef } from 'react';
|
||||
|
||||
import { useForm, useRefresh } from '@flowgram-adapter/free-layout-editor';
|
||||
import { useService } from '@flowgram-adapter/free-layout-editor';
|
||||
import { WorkflowBatchService } from '@coze-workflow/variable';
|
||||
import { sortErrorBody, useIsSettingOnErrorV2 } from '@coze-workflow/nodes';
|
||||
import { HistoryService } from '@coze-workflow/history';
|
||||
import { BatchMode, type ViewVariableTreeNode } from '@coze-workflow/base';
|
||||
import { useNodeTestId } from '@coze-workflow/base';
|
||||
|
||||
import { useReadonly } from '@/nodes-v2/hooks/use-readonly';
|
||||
import { type ValidationProps } from '@/nodes-v2/components/validation/with-validation';
|
||||
import { type ComponentProps } from '@/nodes-v2/components/types';
|
||||
import {
|
||||
OutputTree,
|
||||
type OutputTreeProps,
|
||||
} from '@/form-extensions/components/output-tree';
|
||||
|
||||
import { withValidation } from '../validation';
|
||||
|
||||
type OutputTreeValue = Array<ViewVariableTreeNode> | undefined;
|
||||
type SortValue = (
|
||||
value?: ViewVariableTreeNode[] | undefined,
|
||||
isBatch?: boolean,
|
||||
) => ViewVariableTreeNode[] | undefined;
|
||||
interface OutputTreeOptions {
|
||||
id: string;
|
||||
batchMode?: BatchMode;
|
||||
withDescription?: boolean;
|
||||
withRequired?: boolean;
|
||||
disabled?: boolean;
|
||||
disabledTooltip?: string;
|
||||
readonly?: boolean;
|
||||
topLevelReadonly?: boolean;
|
||||
allowDeleteLast?: boolean;
|
||||
emptyPlaceholder?: string;
|
||||
showResponseFormat?: boolean;
|
||||
needErrorBody?: boolean;
|
||||
hide?: boolean;
|
||||
defaultCollapse?: boolean;
|
||||
needAppendChildWhenNodeIsPreset?: boolean;
|
||||
noCard?: boolean;
|
||||
sortValue?: SortValue; // 排序函数
|
||||
}
|
||||
type OutputsProps = ComponentProps<OutputTreeValue> &
|
||||
OutputTreeOptions &
|
||||
Pick<
|
||||
OutputTreeProps,
|
||||
| 'hiddenTypes'
|
||||
| 'addItemTitle'
|
||||
| 'withDefaultValue'
|
||||
| 'defaultExpandParams'
|
||||
| 'columnsRatio'
|
||||
| 'maxLimit'
|
||||
> &
|
||||
ValidationProps;
|
||||
|
||||
export const Outputs = withValidation<OutputsProps>((props: OutputsProps) => {
|
||||
const {
|
||||
name,
|
||||
value,
|
||||
onChange,
|
||||
id,
|
||||
disabled = false,
|
||||
batchMode,
|
||||
withDescription = false,
|
||||
withRequired = false,
|
||||
readonly = false,
|
||||
topLevelReadonly = false,
|
||||
allowDeleteLast = false,
|
||||
emptyPlaceholder,
|
||||
hiddenTypes,
|
||||
showResponseFormat = false,
|
||||
needErrorBody = false,
|
||||
hide = false,
|
||||
defaultCollapse,
|
||||
needAppendChildWhenNodeIsPreset,
|
||||
noCard,
|
||||
sortValue,
|
||||
} = props || {};
|
||||
|
||||
const form = useForm();
|
||||
|
||||
const workflowReadonly = useReadonly();
|
||||
|
||||
const isBatch = batchMode === BatchMode.Batch;
|
||||
const historyService = useService<HistoryService>(HistoryService);
|
||||
const refresh = useRefresh();
|
||||
const isSettingOnErrorV2 = useIsSettingOnErrorV2();
|
||||
|
||||
// 记录当前batchMode
|
||||
const curBatchMode = useRef<BatchMode>();
|
||||
|
||||
// 变更不记录历史
|
||||
const onChangeWithoutHistory = (outputTreeValue: OutputTreeValue) => {
|
||||
historyService.stop();
|
||||
onChange(outputTreeValue);
|
||||
historyService.start();
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
/**
|
||||
* 初始化时,赋值curBatchMode,但无需对值做修改
|
||||
*/
|
||||
if (!curBatchMode.current) {
|
||||
curBatchMode.current = batchMode;
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换batch mode 需要将 single mode 的output 包成list, 或将 batch mode 的outputList 去掉list这层
|
||||
*/
|
||||
if (batchMode !== curBatchMode.current) {
|
||||
curBatchMode.current = batchMode;
|
||||
|
||||
if (batchMode === BatchMode.Batch) {
|
||||
onChangeWithoutHistory(
|
||||
WorkflowBatchService.singleOutputMetasToList(value),
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (batchMode === BatchMode.Single) {
|
||||
onChangeWithoutHistory(
|
||||
WorkflowBatchService.listOutputMetasToSingle(value),
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}, [batchMode, onChange]);
|
||||
|
||||
const { getNodeSetterId } = useNodeTestId();
|
||||
|
||||
// 要对 value 排序,保证 errorbody 这个属性在最下面
|
||||
const _value = useMemo(() => {
|
||||
const sortedValue = sortValue ? sortValue(value, isBatch) : value;
|
||||
if (needErrorBody) {
|
||||
return sortErrorBody({
|
||||
value: sortedValue as ViewVariableTreeNode[],
|
||||
isBatch,
|
||||
isSettingOnErrorV2,
|
||||
});
|
||||
}
|
||||
return sortedValue;
|
||||
}, [value, needErrorBody, isBatch, isSettingOnErrorV2]);
|
||||
|
||||
if (hide) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<OutputTree
|
||||
{...props}
|
||||
id={id}
|
||||
testId={getNodeSetterId(name)}
|
||||
responseFormat={{
|
||||
visible: showResponseFormat,
|
||||
value: form.getValueIn('model.responseFormat'),
|
||||
readonly: needErrorBody,
|
||||
onChange: v => {
|
||||
const model = form.getValueIn('model');
|
||||
if (model) {
|
||||
form.setValueIn('model', {
|
||||
...model,
|
||||
responseFormat: v,
|
||||
});
|
||||
}
|
||||
refresh();
|
||||
},
|
||||
}}
|
||||
readonly={readonly || workflowReadonly}
|
||||
disabled={disabled}
|
||||
value={_value as any}
|
||||
onChange={onChange as any}
|
||||
isBatch={isBatch}
|
||||
withDescription={withDescription}
|
||||
withRequired={withRequired}
|
||||
topLevelReadonly={topLevelReadonly}
|
||||
allowDeleteLast={allowDeleteLast}
|
||||
emptyPlaceholder={emptyPlaceholder}
|
||||
hiddenTypes={hiddenTypes}
|
||||
defaultCollapse={defaultCollapse}
|
||||
needAppendChildWhenNodeIsPreset={needAppendChildWhenNodeIsPreset}
|
||||
noCard={noCard}
|
||||
/>
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
/* stylelint-disable selector-class-pattern */
|
||||
.workflow-node-setter-radio {
|
||||
&:global(.semi-radioGroup) {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
:global(.semi-radio) {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
:global(.semi-radio-content) {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type FC, useMemo } from 'react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
import { useNodeTestId } from '@coze-workflow/base';
|
||||
import type {
|
||||
OptionItem,
|
||||
RadioChangeEvent,
|
||||
RadioType,
|
||||
} from '@coze-arch/bot-semi/Radio';
|
||||
import { Radio as RadioUI, RadioGroup } from '@coze-arch/bot-semi';
|
||||
|
||||
import { type ComponentProps } from '@/nodes-v2/components/types';
|
||||
|
||||
import { useReadonly } from '../../hooks/use-readonly';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
type RadioItem = OptionItem & {
|
||||
disabled?: boolean;
|
||||
};
|
||||
|
||||
type RadioProps = ComponentProps<string> & {
|
||||
name: string;
|
||||
mode: RadioType;
|
||||
options: RadioItem[];
|
||||
};
|
||||
|
||||
export const Radio: FC<RadioProps> = props => {
|
||||
const { value, onChange, options = [], mode, name } = props;
|
||||
|
||||
const { getNodeSetterId, concatTestId } = useNodeTestId();
|
||||
const readonly = useReadonly();
|
||||
|
||||
const uiOptions = useMemo(
|
||||
() =>
|
||||
options.map(item => (
|
||||
<RadioUI
|
||||
className={classNames({
|
||||
'border-[#1C1F23]/[8%]': mode === 'card' && item.value !== value,
|
||||
'bg-[--semi-color-bg-0]': mode === 'card' && item.value !== value,
|
||||
})}
|
||||
key={item.value}
|
||||
value={item.value}
|
||||
disabled={item.disabled}
|
||||
data-testid={concatTestId(getNodeSetterId(name), `${item.value}`)}
|
||||
>
|
||||
{item.label}
|
||||
</RadioUI>
|
||||
)),
|
||||
[options, mode, value, concatTestId, getNodeSetterId, name],
|
||||
);
|
||||
|
||||
return (
|
||||
<RadioGroup
|
||||
style={{
|
||||
pointerEvents: readonly ? 'none' : 'auto',
|
||||
}}
|
||||
className={styles.workflowNodeSetterRadio}
|
||||
type={mode}
|
||||
value={value}
|
||||
onChange={onChange as unknown as (event: RadioChangeEvent) => void}
|
||||
>
|
||||
{uiOptions}
|
||||
</RadioGroup>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
Field,
|
||||
type FieldRenderProps,
|
||||
} from '@flowgram-adapter/free-layout-editor';
|
||||
import { type SettingOnErrorValue } from '@coze-workflow/nodes';
|
||||
|
||||
import { useReadonly } from '@/nodes-v2/hooks/use-readonly';
|
||||
import { SettingOnError as SettingOnErrorComp } from '@/form-extensions/components/setting-on-error';
|
||||
|
||||
interface Props {
|
||||
fieldName?: string;
|
||||
batchModePath?: string;
|
||||
outputsPath?: string;
|
||||
}
|
||||
|
||||
export const SettingOnError = ({
|
||||
fieldName = 'settingOnError',
|
||||
batchModePath,
|
||||
outputsPath,
|
||||
}: Props) => {
|
||||
const readonly = useReadonly();
|
||||
|
||||
return (
|
||||
<Field name={fieldName}>
|
||||
{({ field }: FieldRenderProps<SettingOnErrorValue>) => (
|
||||
<SettingOnErrorComp
|
||||
{...field}
|
||||
batchModePath={batchModePath}
|
||||
outputsPath={outputsPath}
|
||||
readonly={readonly}
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
.spacing {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import s from './index.module.less';
|
||||
|
||||
export const Spacing = () => <div className={s.spacing} />;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user