mirror of
https://github.com/langgenius/dify.git
synced 2026-05-05 18:08:07 +08:00
refactor(i18n): use JSON with flattened key and namespace (#30114)
Co-authored-by: yyh <yuanyouhuilyz@gmail.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
@ -51,7 +51,7 @@ const ConfigCredential: FC<Props> = ({
|
||||
isShow
|
||||
positionCenter={positionCenter}
|
||||
onHide={onHide}
|
||||
title={t('tools.createTool.authMethod.title')!}
|
||||
title={t('createTool.authMethod.title', { ns: 'tools' })!}
|
||||
dialogClassName="z-[60]"
|
||||
dialogBackdropClassName="z-[70]"
|
||||
panelClassName="mt-2 !w-[520px] h-fit z-[80]"
|
||||
@ -62,10 +62,10 @@ const ConfigCredential: FC<Props> = ({
|
||||
<div className="px-6 pt-2">
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('tools.createTool.authMethod.type')}</div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('createTool.authMethod.type', { ns: 'tools' })}</div>
|
||||
<div className="flex space-x-3">
|
||||
<SelectItem
|
||||
text={t('tools.createTool.authMethod.types.none')}
|
||||
text={t('createTool.authMethod.types.none', { ns: 'tools' })}
|
||||
value={AuthType.none}
|
||||
isChecked={tempCredential.auth_type === AuthType.none}
|
||||
onClick={value => setTempCredential({
|
||||
@ -73,7 +73,7 @@ const ConfigCredential: FC<Props> = ({
|
||||
})}
|
||||
/>
|
||||
<SelectItem
|
||||
text={t('tools.createTool.authMethod.types.api_key_header')}
|
||||
text={t('createTool.authMethod.types.api_key_header', { ns: 'tools' })}
|
||||
value={AuthType.apiKeyHeader}
|
||||
isChecked={tempCredential.auth_type === AuthType.apiKeyHeader}
|
||||
onClick={value => setTempCredential({
|
||||
@ -84,7 +84,7 @@ const ConfigCredential: FC<Props> = ({
|
||||
})}
|
||||
/>
|
||||
<SelectItem
|
||||
text={t('tools.createTool.authMethod.types.api_key_query')}
|
||||
text={t('createTool.authMethod.types.api_key_query', { ns: 'tools' })}
|
||||
value={AuthType.apiKeyQuery}
|
||||
isChecked={tempCredential.auth_type === AuthType.apiKeyQuery}
|
||||
onClick={value => setTempCredential({
|
||||
@ -98,22 +98,22 @@ const ConfigCredential: FC<Props> = ({
|
||||
{tempCredential.auth_type === AuthType.apiKeyHeader && (
|
||||
<>
|
||||
<div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('tools.createTool.authHeaderPrefix.title')}</div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('createTool.authHeaderPrefix.title', { ns: 'tools' })}</div>
|
||||
<div className="flex space-x-3">
|
||||
<SelectItem
|
||||
text={t('tools.createTool.authHeaderPrefix.types.basic')}
|
||||
text={t('createTool.authHeaderPrefix.types.basic', { ns: 'tools' })}
|
||||
value={AuthHeaderPrefix.basic}
|
||||
isChecked={tempCredential.api_key_header_prefix === AuthHeaderPrefix.basic}
|
||||
onClick={value => setTempCredential({ ...tempCredential, api_key_header_prefix: value as AuthHeaderPrefix })}
|
||||
/>
|
||||
<SelectItem
|
||||
text={t('tools.createTool.authHeaderPrefix.types.bearer')}
|
||||
text={t('createTool.authHeaderPrefix.types.bearer', { ns: 'tools' })}
|
||||
value={AuthHeaderPrefix.bearer}
|
||||
isChecked={tempCredential.api_key_header_prefix === AuthHeaderPrefix.bearer}
|
||||
onClick={value => setTempCredential({ ...tempCredential, api_key_header_prefix: value as AuthHeaderPrefix })}
|
||||
/>
|
||||
<SelectItem
|
||||
text={t('tools.createTool.authHeaderPrefix.types.custom')}
|
||||
text={t('createTool.authHeaderPrefix.types.custom', { ns: 'tools' })}
|
||||
value={AuthHeaderPrefix.custom}
|
||||
isChecked={tempCredential.api_key_header_prefix === AuthHeaderPrefix.custom}
|
||||
onClick={value => setTempCredential({ ...tempCredential, api_key_header_prefix: value as AuthHeaderPrefix })}
|
||||
@ -122,11 +122,11 @@ const ConfigCredential: FC<Props> = ({
|
||||
</div>
|
||||
<div>
|
||||
<div className="system-sm-medium flex items-center py-2 text-text-primary">
|
||||
{t('tools.createTool.authMethod.key')}
|
||||
{t('createTool.authMethod.key', { ns: 'tools' })}
|
||||
<Tooltip
|
||||
popupContent={(
|
||||
<div className="w-[261px] text-text-tertiary">
|
||||
{t('tools.createTool.authMethod.keyTooltip')}
|
||||
{t('createTool.authMethod.keyTooltip', { ns: 'tools' })}
|
||||
</div>
|
||||
)}
|
||||
triggerClassName="ml-0.5 w-4 h-4"
|
||||
@ -135,15 +135,15 @@ const ConfigCredential: FC<Props> = ({
|
||||
<Input
|
||||
value={tempCredential.api_key_header}
|
||||
onChange={e => setTempCredential({ ...tempCredential, api_key_header: e.target.value })}
|
||||
placeholder={t('tools.createTool.authMethod.types.apiKeyPlaceholder')!}
|
||||
placeholder={t('createTool.authMethod.types.apiKeyPlaceholder', { ns: 'tools' })!}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('tools.createTool.authMethod.value')}</div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('createTool.authMethod.value', { ns: 'tools' })}</div>
|
||||
<Input
|
||||
value={tempCredential.api_key_value}
|
||||
onChange={e => setTempCredential({ ...tempCredential, api_key_value: e.target.value })}
|
||||
placeholder={t('tools.createTool.authMethod.types.apiValuePlaceholder')!}
|
||||
placeholder={t('createTool.authMethod.types.apiValuePlaceholder', { ns: 'tools' })!}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
@ -152,11 +152,11 @@ const ConfigCredential: FC<Props> = ({
|
||||
<>
|
||||
<div>
|
||||
<div className="system-sm-medium flex items-center py-2 text-text-primary">
|
||||
{t('tools.createTool.authMethod.queryParam')}
|
||||
{t('createTool.authMethod.queryParam', { ns: 'tools' })}
|
||||
<Tooltip
|
||||
popupContent={(
|
||||
<div className="w-[261px] text-text-tertiary">
|
||||
{t('tools.createTool.authMethod.queryParamTooltip')}
|
||||
{t('createTool.authMethod.queryParamTooltip', { ns: 'tools' })}
|
||||
</div>
|
||||
)}
|
||||
triggerClassName="ml-0.5 w-4 h-4"
|
||||
@ -165,15 +165,15 @@ const ConfigCredential: FC<Props> = ({
|
||||
<Input
|
||||
value={tempCredential.api_key_query_param}
|
||||
onChange={e => setTempCredential({ ...tempCredential, api_key_query_param: e.target.value })}
|
||||
placeholder={t('tools.createTool.authMethod.types.queryParamPlaceholder')!}
|
||||
placeholder={t('createTool.authMethod.types.queryParamPlaceholder', { ns: 'tools' })!}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('tools.createTool.authMethod.value')}</div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('createTool.authMethod.value', { ns: 'tools' })}</div>
|
||||
<Input
|
||||
value={tempCredential.api_key_value}
|
||||
onChange={e => setTempCredential({ ...tempCredential, api_key_value: e.target.value })}
|
||||
placeholder={t('tools.createTool.authMethod.types.apiValuePlaceholder')!}
|
||||
placeholder={t('createTool.authMethod.types.apiValuePlaceholder', { ns: 'tools' })!}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
@ -182,7 +182,7 @@ const ConfigCredential: FC<Props> = ({
|
||||
</div>
|
||||
|
||||
<div className="mt-4 flex shrink-0 justify-end space-x-2 py-4">
|
||||
<Button onClick={onHide}>{t('common.operation.cancel')}</Button>
|
||||
<Button onClick={onHide}>{t('operation.cancel', { ns: 'common' })}</Button>
|
||||
<Button
|
||||
variant="primary"
|
||||
onClick={() => {
|
||||
@ -190,7 +190,7 @@ const ConfigCredential: FC<Props> = ({
|
||||
onHide()
|
||||
}}
|
||||
>
|
||||
{t('common.operation.save')}
|
||||
{t('operation.save', { ns: 'common' })}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -176,6 +176,6 @@ const examples = [
|
||||
}
|
||||
}`,
|
||||
},
|
||||
]
|
||||
] as const
|
||||
|
||||
export default examples
|
||||
|
||||
@ -29,7 +29,7 @@ const GetSchema: FC<Props> = ({
|
||||
if (!importUrl.startsWith('http://') && !importUrl.startsWith('https://')) {
|
||||
Toast.notify({
|
||||
type: 'error',
|
||||
message: t('tools.createTool.urlError'),
|
||||
message: t('createTool.urlError', { ns: 'tools' }),
|
||||
})
|
||||
return
|
||||
}
|
||||
@ -65,7 +65,7 @@ const GetSchema: FC<Props> = ({
|
||||
onClick={() => { setShowImportFromUrl(!showImportFromUrl) }}
|
||||
>
|
||||
<RiAddLine className="h-3 w-3" />
|
||||
<div className="system-xs-medium text-text-secondary">{t('tools.createTool.importFromUrl')}</div>
|
||||
<div className="system-xs-medium text-text-secondary">{t('createTool.importFromUrl', { ns: 'tools' })}</div>
|
||||
</Button>
|
||||
{showImportFromUrl && (
|
||||
<div className=" absolute left-[-35px] top-[26px] rounded-lg border border-components-panel-border bg-components-panel-bg p-2 shadow-lg">
|
||||
@ -73,7 +73,7 @@ const GetSchema: FC<Props> = ({
|
||||
<Input
|
||||
type="text"
|
||||
className="w-[244px]"
|
||||
placeholder={t('tools.createTool.importFromUrlPlaceHolder')!}
|
||||
placeholder={t('createTool.importFromUrlPlaceHolder', { ns: 'tools' })!}
|
||||
value={importUrl}
|
||||
onChange={e => setImportUrl(e.target.value)}
|
||||
/>
|
||||
@ -85,7 +85,7 @@ const GetSchema: FC<Props> = ({
|
||||
onClick={handleImportFromUrl}
|
||||
loading={isParsing}
|
||||
>
|
||||
{isParsing ? '' : t('common.operation.ok')}
|
||||
{isParsing ? '' : t('operation.ok', { ns: 'common' })}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
@ -97,7 +97,7 @@ const GetSchema: FC<Props> = ({
|
||||
className="space-x-1"
|
||||
onClick={() => { setShowExamples(!showExamples) }}
|
||||
>
|
||||
<div className="system-xs-medium text-text-secondary">{t('tools.createTool.examples')}</div>
|
||||
<div className="system-xs-medium text-text-secondary">{t('createTool.examples', { ns: 'tools' })}</div>
|
||||
<RiArrowDownSLine className="h-3 w-3" />
|
||||
</Button>
|
||||
{showExamples && (
|
||||
@ -111,7 +111,7 @@ const GetSchema: FC<Props> = ({
|
||||
}}
|
||||
className="system-sm-regular cursor-pointer whitespace-nowrap rounded-lg px-3 py-1.5 leading-5 text-text-secondary hover:bg-components-panel-on-panel-item-bg-hover"
|
||||
>
|
||||
{t(`tools.createTool.exampleOptions.${item.key}` as any) as string}
|
||||
{t(`createTool.exampleOptions.${item.key}`, { ns: 'tools' })}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@ -154,10 +154,10 @@ const EditCustomCollectionModal: FC<Props> = ({
|
||||
|
||||
let errorMessage = ''
|
||||
if (!postData.provider)
|
||||
errorMessage = t('common.errorMsg.fieldRequired', { field: t('tools.createTool.name') })
|
||||
errorMessage = t('errorMsg.fieldRequired', { ns: 'common', field: t('createTool.name', { ns: 'tools' }) })
|
||||
|
||||
if (!postData.schema)
|
||||
errorMessage = t('common.errorMsg.fieldRequired', { field: t('tools.createTool.schema') })
|
||||
errorMessage = t('errorMsg.fieldRequired', { ns: 'common', field: t('createTool.schema', { ns: 'tools' }) })
|
||||
|
||||
if (errorMessage) {
|
||||
Toast.notify({
|
||||
@ -197,7 +197,7 @@ const EditCustomCollectionModal: FC<Props> = ({
|
||||
isShow
|
||||
positionCenter={isAdd && !positionLeft}
|
||||
onHide={onHide}
|
||||
title={t(`tools.createTool.${isAdd ? 'title' : 'editTitle'}`)!}
|
||||
title={t(`createTool.${isAdd ? 'title' : 'editTitle'}`, { ns: 'tools' })!}
|
||||
dialogClassName={dialogClassName}
|
||||
panelClassName="mt-2 !w-[640px]"
|
||||
maxWidthClassName="!max-w-[640px]"
|
||||
@ -208,7 +208,7 @@ const EditCustomCollectionModal: FC<Props> = ({
|
||||
<div className="h-0 grow space-y-4 overflow-y-auto px-6 py-3">
|
||||
<div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">
|
||||
{t('tools.createTool.name')}
|
||||
{t('createTool.name', { ns: 'tools' })}
|
||||
{' '}
|
||||
<span className="ml-1 text-red-500">*</span>
|
||||
</div>
|
||||
@ -216,7 +216,7 @@ const EditCustomCollectionModal: FC<Props> = ({
|
||||
<AppIcon size="large" onClick={() => { setShowEmojiPicker(true) }} className="cursor-pointer" icon={emoji.content} background={emoji.background} />
|
||||
<Input
|
||||
className="h-10 grow"
|
||||
placeholder={t('tools.createTool.toolNamePlaceHolder')!}
|
||||
placeholder={t('createTool.toolNamePlaceHolder', { ns: 'tools' })!}
|
||||
value={customCollection.provider}
|
||||
onChange={(e) => {
|
||||
const newCollection = produce(customCollection, (draft) => {
|
||||
@ -233,7 +233,7 @@ const EditCustomCollectionModal: FC<Props> = ({
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center">
|
||||
<div className="system-sm-medium py-2 text-text-primary">
|
||||
{t('tools.createTool.schema')}
|
||||
{t('createTool.schema', { ns: 'tools' })}
|
||||
<span className="ml-1 text-red-500">*</span>
|
||||
</div>
|
||||
<div className="mx-2 h-3 w-px bg-divider-regular"></div>
|
||||
@ -243,7 +243,7 @@ const EditCustomCollectionModal: FC<Props> = ({
|
||||
rel="noopener noreferrer"
|
||||
className="flex h-[18px] items-center space-x-1 text-text-accent"
|
||||
>
|
||||
<div className="text-xs font-normal">{t('tools.createTool.viewSchemaSpec')}</div>
|
||||
<div className="text-xs font-normal">{t('createTool.viewSchemaSpec', { ns: 'tools' })}</div>
|
||||
<LinkExternal02 className="h-3 w-3" />
|
||||
</a>
|
||||
</div>
|
||||
@ -254,22 +254,22 @@ const EditCustomCollectionModal: FC<Props> = ({
|
||||
className="h-[240px] resize-none"
|
||||
value={schema}
|
||||
onChange={e => setSchema(e.target.value)}
|
||||
placeholder={t('tools.createTool.schemaPlaceHolder')!}
|
||||
placeholder={t('createTool.schemaPlaceHolder', { ns: 'tools' })!}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Available Tools */}
|
||||
<div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('tools.createTool.availableTools.title')}</div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('createTool.availableTools.title', { ns: 'tools' })}</div>
|
||||
<div className="w-full overflow-x-auto rounded-lg border border-divider-regular">
|
||||
<table className="system-xs-regular w-full text-text-secondary">
|
||||
<thead className="uppercase text-text-tertiary">
|
||||
<tr className={cn(paramsSchemas.length > 0 && 'border-b', 'border-divider-regular')}>
|
||||
<th className="p-2 pl-3 font-medium">{t('tools.createTool.availableTools.name')}</th>
|
||||
<th className="w-[236px] p-2 pl-3 font-medium">{t('tools.createTool.availableTools.description')}</th>
|
||||
<th className="p-2 pl-3 font-medium">{t('tools.createTool.availableTools.method')}</th>
|
||||
<th className="p-2 pl-3 font-medium">{t('tools.createTool.availableTools.path')}</th>
|
||||
<th className="w-[54px] p-2 pl-3 font-medium">{t('tools.createTool.availableTools.action')}</th>
|
||||
<th className="p-2 pl-3 font-medium">{t('createTool.availableTools.name', { ns: 'tools' })}</th>
|
||||
<th className="w-[236px] p-2 pl-3 font-medium">{t('createTool.availableTools.description', { ns: 'tools' })}</th>
|
||||
<th className="p-2 pl-3 font-medium">{t('createTool.availableTools.method', { ns: 'tools' })}</th>
|
||||
<th className="p-2 pl-3 font-medium">{t('createTool.availableTools.path', { ns: 'tools' })}</th>
|
||||
<th className="w-[54px] p-2 pl-3 font-medium">{t('createTool.availableTools.action', { ns: 'tools' })}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -287,7 +287,7 @@ const EditCustomCollectionModal: FC<Props> = ({
|
||||
setIsShowTestApi(true)
|
||||
}}
|
||||
>
|
||||
{t('tools.createTool.availableTools.test')}
|
||||
{t('createTool.availableTools.test', { ns: 'tools' })}
|
||||
</Button>
|
||||
</td>
|
||||
</tr>
|
||||
@ -299,22 +299,22 @@ const EditCustomCollectionModal: FC<Props> = ({
|
||||
|
||||
{/* Authorization method */}
|
||||
<div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('tools.createTool.authMethod.title')}</div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('createTool.authMethod.title', { ns: 'tools' })}</div>
|
||||
<div className="flex h-9 cursor-pointer items-center justify-between rounded-lg bg-components-input-bg-normal px-2.5" onClick={() => setCredentialsModalShow(true)}>
|
||||
<div className="system-xs-regular text-text-primary">{t(`tools.createTool.authMethod.types.${credential.auth_type}` as any) as string}</div>
|
||||
<div className="system-xs-regular text-text-primary">{t(`createTool.authMethod.types.${credential.auth_type}`, { ns: 'tools' })}</div>
|
||||
<RiSettings2Line className="h-4 w-4 text-text-secondary" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Labels */}
|
||||
<div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('tools.createTool.toolInput.label')}</div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('createTool.toolInput.label', { ns: 'tools' })}</div>
|
||||
<LabelSelector value={labels} onChange={handleLabelSelect} />
|
||||
</div>
|
||||
|
||||
{/* Privacy Policy */}
|
||||
<div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('tools.createTool.privacyPolicy')}</div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('createTool.privacyPolicy', { ns: 'tools' })}</div>
|
||||
<Input
|
||||
value={customCollection.privacy_policy}
|
||||
onChange={(e) => {
|
||||
@ -324,12 +324,12 @@ const EditCustomCollectionModal: FC<Props> = ({
|
||||
setCustomCollection(newCollection)
|
||||
}}
|
||||
className="h-10 grow"
|
||||
placeholder={t('tools.createTool.privacyPolicyPlaceholder') || ''}
|
||||
placeholder={t('createTool.privacyPolicyPlaceholder', { ns: 'tools' }) || ''}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('tools.createTool.customDisclaimer')}</div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('createTool.customDisclaimer', { ns: 'tools' })}</div>
|
||||
<Input
|
||||
value={customCollection.custom_disclaimer}
|
||||
onChange={(e) => {
|
||||
@ -339,7 +339,7 @@ const EditCustomCollectionModal: FC<Props> = ({
|
||||
setCustomCollection(newCollection)
|
||||
}}
|
||||
className="h-10 grow"
|
||||
placeholder={t('tools.createTool.customDisclaimerPlaceholder') || ''}
|
||||
placeholder={t('createTool.customDisclaimerPlaceholder', { ns: 'tools' }) || ''}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -347,12 +347,12 @@ const EditCustomCollectionModal: FC<Props> = ({
|
||||
<div className={cn(isEdit ? 'justify-between' : 'justify-end', 'mt-2 flex shrink-0 rounded-b-[10px] border-t border-divider-regular bg-background-section-burn px-6 py-4')}>
|
||||
{
|
||||
isEdit && (
|
||||
<Button variant="warning" onClick={onRemove}>{t('common.operation.delete')}</Button>
|
||||
<Button variant="warning" onClick={onRemove}>{t('operation.delete', { ns: 'common' })}</Button>
|
||||
)
|
||||
}
|
||||
<div className="flex space-x-2 ">
|
||||
<Button onClick={onHide}>{t('common.operation.cancel')}</Button>
|
||||
<Button variant="primary" onClick={handleSave}>{t('common.operation.save')}</Button>
|
||||
<Button onClick={onHide}>{t('operation.cancel', { ns: 'common' })}</Button>
|
||||
<Button variant="primary" onClick={handleSave}>{t('operation.save', { ns: 'common' })}</Button>
|
||||
</div>
|
||||
</div>
|
||||
{showEmojiPicker && (
|
||||
|
||||
@ -67,7 +67,7 @@ const TestApi: FC<Props> = ({
|
||||
isShow
|
||||
positionCenter={positionCenter}
|
||||
onHide={onHide}
|
||||
title={`${t('tools.test.title')} ${toolName}`}
|
||||
title={`${t('test.title', { ns: 'tools' })} ${toolName}`}
|
||||
panelClassName="mt-2 !w-[600px]"
|
||||
maxWidthClassName="!max-w-[600px]"
|
||||
height="calc(100vh - 16px)"
|
||||
@ -76,21 +76,21 @@ const TestApi: FC<Props> = ({
|
||||
<div className="overflow-y-auto px-6 pt-2">
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('tools.createTool.authMethod.title')}</div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('createTool.authMethod.title', { ns: 'tools' })}</div>
|
||||
<div className="flex h-9 cursor-pointer items-center justify-between rounded-lg bg-components-input-bg-normal px-2.5" onClick={() => setCredentialsModalShow(true)}>
|
||||
<div className="system-xs-regular text-text-primary">{t(`tools.createTool.authMethod.types.${tempCredential.auth_type}` as any) as string}</div>
|
||||
<div className="system-xs-regular text-text-primary">{t(`createTool.authMethod.types.${tempCredential.auth_type}`, { ns: 'tools' })}</div>
|
||||
<RiSettings2Line className="h-4 w-4 text-text-secondary" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('tools.test.parametersValue')}</div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('test.parametersValue', { ns: 'tools' })}</div>
|
||||
<div className="rounded-lg border border-divider-regular">
|
||||
<table className="system-xs-regular w-full font-normal text-text-secondary">
|
||||
<thead className="uppercase text-text-tertiary">
|
||||
<tr className="border-b border-divider-regular">
|
||||
<th className="p-2 pl-3 font-medium">{t('tools.test.parameters')}</th>
|
||||
<th className="p-2 pl-3 font-medium">{t('tools.test.value')}</th>
|
||||
<th className="p-2 pl-3 font-medium">{t('test.parameters', { ns: 'tools' })}</th>
|
||||
<th className="p-2 pl-3 font-medium">{t('test.value', { ns: 'tools' })}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -115,14 +115,14 @@ const TestApi: FC<Props> = ({
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<Button variant="primary" className=" mt-4 h-10 w-full" loading={testing} disabled={testing} onClick={handleTest}>{t('tools.test.title')}</Button>
|
||||
<Button variant="primary" className=" mt-4 h-10 w-full" loading={testing} disabled={testing} onClick={handleTest}>{t('test.title', { ns: 'tools' })}</Button>
|
||||
<div className="mt-6">
|
||||
<div className="flex items-center space-x-3">
|
||||
<div className="system-xs-semibold text-text-tertiary">{t('tools.test.testResult')}</div>
|
||||
<div className="system-xs-semibold text-text-tertiary">{t('test.testResult', { ns: 'tools' })}</div>
|
||||
<div className="bg-[rgb(243, 244, 246)] h-px w-0 grow"></div>
|
||||
</div>
|
||||
<div className="system-xs-regular mt-2 h-[200px] overflow-y-auto overflow-x-hidden rounded-lg bg-components-input-bg-normal px-3 py-2 text-text-secondary">
|
||||
{result || <span className="text-text-quaternary">{t('tools.test.testResultPlaceholder')}</span>}
|
||||
{result || <span className="text-text-quaternary">{t('test.testResultPlaceholder', { ns: 'tools' })}</span>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -76,7 +76,7 @@ const LabelFilter: FC<LabelFilterProps> = ({
|
||||
<Tag01 className="h-3.5 w-3.5 text-text-tertiary" />
|
||||
</div>
|
||||
<div className="text-[13px] leading-[18px] text-text-tertiary">
|
||||
{!value.length && t('common.tag.placeholder')}
|
||||
{!value.length && t('tag.placeholder', { ns: 'common' })}
|
||||
{!!value.length && currentLabel?.label}
|
||||
</div>
|
||||
{value.length > 1 && (
|
||||
@ -125,7 +125,7 @@ const LabelFilter: FC<LabelFilterProps> = ({
|
||||
{!filteredLabelList.length && (
|
||||
<div className="flex flex-col items-center gap-1 p-3">
|
||||
<Tag03 className="h-6 w-6 text-text-quaternary" />
|
||||
<div className="text-xs leading-[14px] text-text-tertiary">{t('common.tag.noTag')}</div>
|
||||
<div className="text-xs leading-[14px] text-text-tertiary">{t('tag.noTag', { ns: 'common' })}</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@ -72,7 +72,7 @@ const LabelSelector: FC<LabelSelectorProps> = ({
|
||||
)}
|
||||
>
|
||||
<div title={value.length > 0 ? selectedLabels : ''} className={cn('grow truncate text-[13px] leading-[18px] text-text-secondary', !value.length && '!text-text-quaternary')}>
|
||||
{!value.length && t('tools.createTool.toolInput.labelPlaceholder')}
|
||||
{!value.length && t('createTool.toolInput.labelPlaceholder', { ns: 'tools' })}
|
||||
{!!value.length && selectedLabels}
|
||||
</div>
|
||||
<div className="ml-1 shrink-0 text-text-secondary opacity-60">
|
||||
@ -109,7 +109,7 @@ const LabelSelector: FC<LabelSelectorProps> = ({
|
||||
{!filteredLabelList.length && (
|
||||
<div className="flex flex-col items-center gap-1 p-3">
|
||||
<Tag03 className="h-6 w-6 text-text-quaternary" />
|
||||
<div className="text-xs leading-[14px] text-text-tertiary">{t('common.tag.noTag')}</div>
|
||||
<div className="text-xs leading-[14px] text-text-tertiary">{t('tag.noTag', { ns: 'common' })}</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@ -46,44 +46,44 @@ const Marketplace = ({
|
||||
)}
|
||||
<div className="pb-3 pt-4">
|
||||
<div className="title-2xl-semi-bold bg-gradient-to-r from-[rgba(11,165,236,0.95)] to-[rgba(21,90,239,0.95)] bg-clip-text text-transparent">
|
||||
{t('plugin.marketplace.moreFrom')}
|
||||
{t('marketplace.moreFrom', { ns: 'plugin' })}
|
||||
</div>
|
||||
<div className="body-md-regular flex items-center text-center text-text-tertiary">
|
||||
{t('plugin.marketplace.discover')}
|
||||
{t('marketplace.discover', { ns: 'plugin' })}
|
||||
<span className="body-md-medium relative ml-1 text-text-secondary after:absolute after:bottom-[1.5px] after:left-0 after:h-2 after:w-full after:bg-text-text-selected after:content-['']">
|
||||
{t('plugin.category.models')}
|
||||
{t('category.models', { ns: 'plugin' })}
|
||||
</span>
|
||||
,
|
||||
<span className="body-md-medium relative ml-1 text-text-secondary after:absolute after:bottom-[1.5px] after:left-0 after:h-2 after:w-full after:bg-text-text-selected after:content-['']">
|
||||
{t('plugin.category.tools')}
|
||||
{t('category.tools', { ns: 'plugin' })}
|
||||
</span>
|
||||
,
|
||||
<span className="body-md-medium relative ml-1 text-text-secondary after:absolute after:bottom-[1.5px] after:left-0 after:h-2 after:w-full after:bg-text-text-selected after:content-['']">
|
||||
{t('plugin.category.datasources')}
|
||||
{t('category.datasources', { ns: 'plugin' })}
|
||||
</span>
|
||||
,
|
||||
<span className="body-md-medium relative ml-1 text-text-secondary after:absolute after:bottom-[1.5px] after:left-0 after:h-2 after:w-full after:bg-text-text-selected after:content-['']">
|
||||
{t('plugin.category.triggers')}
|
||||
{t('category.triggers', { ns: 'plugin' })}
|
||||
</span>
|
||||
,
|
||||
<span className="body-md-medium relative ml-1 text-text-secondary after:absolute after:bottom-[1.5px] after:left-0 after:h-2 after:w-full after:bg-text-text-selected after:content-['']">
|
||||
{t('plugin.category.agents')}
|
||||
{t('category.agents', { ns: 'plugin' })}
|
||||
</span>
|
||||
,
|
||||
<span className="body-md-medium relative ml-1 mr-1 text-text-secondary after:absolute after:bottom-[1.5px] after:left-0 after:h-2 after:w-full after:bg-text-text-selected after:content-['']">
|
||||
{t('plugin.category.extensions')}
|
||||
{t('category.extensions', { ns: 'plugin' })}
|
||||
</span>
|
||||
{t('plugin.marketplace.and')}
|
||||
{t('marketplace.and', { ns: 'plugin' })}
|
||||
<span className="body-md-medium relative ml-1 mr-1 text-text-secondary after:absolute after:bottom-[1.5px] after:left-0 after:h-2 after:w-full after:bg-text-text-selected after:content-['']">
|
||||
{t('plugin.category.bundles')}
|
||||
{t('category.bundles', { ns: 'plugin' })}
|
||||
</span>
|
||||
{t('common.operation.in')}
|
||||
{t('operation.in', { ns: 'common' })}
|
||||
<a
|
||||
href={getMarketplaceUrl('', { language: locale, q: searchPluginText, tags: filterPluginTags.join(','), theme })}
|
||||
className="system-sm-medium ml-1 flex items-center text-text-accent"
|
||||
target="_blank"
|
||||
>
|
||||
{t('plugin.marketplace.difyMarketplace')}
|
||||
{t('marketplace.difyMarketplace', { ns: 'plugin' })}
|
||||
<RiArrowRightUpLine className="h-4 w-4" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@ -50,13 +50,13 @@ const NewMCPCard = ({ handleCreate }: Props) => {
|
||||
<div className="flex h-10 w-10 items-center justify-center rounded-lg border border-dashed border-divider-deep group-hover:border-solid group-hover:border-state-accent-hover-alt group-hover:bg-state-accent-hover">
|
||||
<RiAddCircleFill className="h-4 w-4 text-text-quaternary group-hover:text-text-accent" />
|
||||
</div>
|
||||
<div className="system-md-semibold ml-3 text-text-secondary group-hover:text-text-accent">{t('tools.mcp.create.cardTitle')}</div>
|
||||
<div className="system-md-semibold ml-3 text-text-secondary group-hover:text-text-accent">{t('mcp.create.cardTitle', { ns: 'tools' })}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="rounded-b-xl border-t-[0.5px] border-divider-subtle px-4 py-3 text-text-tertiary hover:text-text-accent">
|
||||
<a href={linkUrl} target="_blank" rel="noopener noreferrer" className="flex items-center space-x-1">
|
||||
<RiBookOpenLine className="h-3 w-3 shrink-0" />
|
||||
<div className="system-xs-regular grow truncate" title={t('tools.mcp.create.cardLink') || ''}>{t('tools.mcp.create.cardLink')}</div>
|
||||
<div className="system-xs-regular grow truncate" title={t('mcp.create.cardLink', { ns: 'tools' }) || ''}>{t('mcp.create.cardLink', { ns: 'tools' })}</div>
|
||||
<RiArrowRightUpLine className="h-3 w-3 shrink-0" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@ -159,11 +159,11 @@ const MCPDetailContent: FC<Props> = ({
|
||||
<div className="system-md-semibold truncate text-text-primary" title={detail.name}>{detail.name}</div>
|
||||
</div>
|
||||
<div className="mt-0.5 flex items-center gap-1">
|
||||
<Tooltip popupContent={t('tools.mcp.identifier')}>
|
||||
<Tooltip popupContent={t('mcp.identifier', { ns: 'tools' })}>
|
||||
<div className="system-xs-regular shrink-0 cursor-pointer text-text-secondary" onClick={() => copy(detail.server_identifier || '')}>{detail.server_identifier}</div>
|
||||
</Tooltip>
|
||||
<div className="system-xs-regular shrink-0 text-text-quaternary">·</div>
|
||||
<Tooltip popupContent={t('tools.mcp.modal.serverUrl')}>
|
||||
<Tooltip popupContent={t('mcp.modal.serverUrl', { ns: 'tools' })}>
|
||||
<div className="system-xs-regular truncate text-text-secondary">{detail.server_url}</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
@ -187,7 +187,7 @@ const MCPDetailContent: FC<Props> = ({
|
||||
disabled={!isCurrentWorkspaceManager}
|
||||
>
|
||||
<Indicator className="mr-2" color="green" />
|
||||
{t('tools.auth.authorized')}
|
||||
{t('auth.authorized', { ns: 'tools' })}
|
||||
</Button>
|
||||
)}
|
||||
{!detail.is_team_authorization && !isAuthorizing && (
|
||||
@ -197,7 +197,7 @@ const MCPDetailContent: FC<Props> = ({
|
||||
onClick={handleAuthorize}
|
||||
disabled={!isCurrentWorkspaceManager}
|
||||
>
|
||||
{t('tools.mcp.authorize')}
|
||||
{t('mcp.authorize', { ns: 'tools' })}
|
||||
</Button>
|
||||
)}
|
||||
{isAuthorizing && (
|
||||
@ -207,7 +207,7 @@ const MCPDetailContent: FC<Props> = ({
|
||||
disabled
|
||||
>
|
||||
<RiLoader2Line className={cn('mr-1 h-4 w-4 animate-spin')} />
|
||||
{t('tools.mcp.authorizing')}
|
||||
{t('mcp.authorizing', { ns: 'tools' })}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
@ -217,8 +217,8 @@ const MCPDetailContent: FC<Props> = ({
|
||||
<>
|
||||
<div className="flex shrink-0 justify-between gap-2 px-4 pb-1 pt-2">
|
||||
<div className="flex h-6 items-center">
|
||||
{!isUpdating && <div className="system-sm-semibold-uppercase text-text-secondary">{t('tools.mcp.gettingTools')}</div>}
|
||||
{isUpdating && <div className="system-sm-semibold-uppercase text-text-secondary">{t('tools.mcp.updateTools')}</div>}
|
||||
{!isUpdating && <div className="system-sm-semibold-uppercase text-text-secondary">{t('mcp.gettingTools', { ns: 'tools' })}</div>}
|
||||
{isUpdating && <div className="system-sm-semibold-uppercase text-text-secondary">{t('mcp.updateTools', { ns: 'tools' })}</div>}
|
||||
</div>
|
||||
<div></div>
|
||||
</div>
|
||||
@ -229,12 +229,12 @@ const MCPDetailContent: FC<Props> = ({
|
||||
)}
|
||||
{!isUpdating && detail.is_team_authorization && !isGettingTools && !toolList.length && (
|
||||
<div className="flex h-full w-full flex-col items-center justify-center">
|
||||
<div className="system-sm-regular mb-3 text-text-tertiary">{t('tools.mcp.toolsEmpty')}</div>
|
||||
<div className="system-sm-regular mb-3 text-text-tertiary">{t('mcp.toolsEmpty', { ns: 'tools' })}</div>
|
||||
<Button
|
||||
variant="primary"
|
||||
onClick={handleUpdateTools}
|
||||
>
|
||||
{t('tools.mcp.getTools')}
|
||||
{t('mcp.getTools', { ns: 'tools' })}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
@ -242,13 +242,13 @@ const MCPDetailContent: FC<Props> = ({
|
||||
<>
|
||||
<div className="flex shrink-0 justify-between gap-2 px-4 pb-1 pt-2">
|
||||
<div className="flex h-6 items-center">
|
||||
{toolList.length > 1 && <div className="system-sm-semibold-uppercase text-text-secondary">{t('tools.mcp.toolsNum', { count: toolList.length })}</div>}
|
||||
{toolList.length === 1 && <div className="system-sm-semibold-uppercase text-text-secondary">{t('tools.mcp.onlyTool')}</div>}
|
||||
{toolList.length > 1 && <div className="system-sm-semibold-uppercase text-text-secondary">{t('mcp.toolsNum', { ns: 'tools', count: toolList.length })}</div>}
|
||||
{toolList.length === 1 && <div className="system-sm-semibold-uppercase text-text-secondary">{t('mcp.onlyTool', { ns: 'tools' })}</div>}
|
||||
</div>
|
||||
<div>
|
||||
<Button size="small" onClick={showUpdateConfirm}>
|
||||
<RiLoopLeftLine className="mr-1 h-3.5 w-3.5" />
|
||||
{t('tools.mcp.update')}
|
||||
{t('mcp.update', { ns: 'tools' })}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
@ -265,9 +265,9 @@ const MCPDetailContent: FC<Props> = ({
|
||||
|
||||
{!isUpdating && !detail.is_team_authorization && (
|
||||
<div className="flex h-full w-full flex-col items-center justify-center">
|
||||
{!isAuthorizing && <div className="system-md-medium mb-1 text-text-secondary">{t('tools.mcp.authorizingRequired')}</div>}
|
||||
{isAuthorizing && <div className="system-md-medium mb-1 text-text-secondary">{t('tools.mcp.authorizing')}</div>}
|
||||
<div className="system-sm-regular text-text-tertiary">{t('tools.mcp.authorizeTip')}</div>
|
||||
{!isAuthorizing && <div className="system-md-medium mb-1 text-text-secondary">{t('mcp.authorizingRequired', { ns: 'tools' })}</div>}
|
||||
{isAuthorizing && <div className="system-md-medium mb-1 text-text-secondary">{t('mcp.authorizing', { ns: 'tools' })}</div>}
|
||||
<div className="system-sm-regular text-text-tertiary">{t('mcp.authorizeTip', { ns: 'tools' })}</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@ -282,10 +282,10 @@ const MCPDetailContent: FC<Props> = ({
|
||||
{isShowDeleteConfirm && (
|
||||
<Confirm
|
||||
isShow
|
||||
title={t('tools.mcp.delete')}
|
||||
title={t('mcp.delete', { ns: 'tools' })}
|
||||
content={(
|
||||
<div>
|
||||
{t('tools.mcp.deleteConfirmTitle', { mcp: detail.name })}
|
||||
{t('mcp.deleteConfirmTitle', { ns: 'tools', mcp: detail.name })}
|
||||
</div>
|
||||
)}
|
||||
onCancel={hideDeleteConfirm}
|
||||
@ -297,8 +297,8 @@ const MCPDetailContent: FC<Props> = ({
|
||||
{isShowUpdateConfirm && (
|
||||
<Confirm
|
||||
isShow
|
||||
title={t('tools.mcp.toolUpdateConfirmTitle')}
|
||||
content={t('tools.mcp.toolUpdateConfirmContent')}
|
||||
title={t('mcp.toolUpdateConfirmTitle', { ns: 'tools' })}
|
||||
content={t('mcp.toolUpdateConfirmContent', { ns: 'tools' })}
|
||||
onCancel={hideUpdateConfirm}
|
||||
onConfirm={handleUpdateTools}
|
||||
/>
|
||||
|
||||
@ -69,7 +69,7 @@ const OperationDropdown: FC<Props> = ({
|
||||
}}
|
||||
>
|
||||
<RiEditLine className="h-4 w-4 text-text-tertiary" />
|
||||
<div className="system-md-regular ml-2 text-text-secondary">{t('tools.mcp.operation.edit')}</div>
|
||||
<div className="system-md-regular ml-2 text-text-secondary">{t('mcp.operation.edit', { ns: 'tools' })}</div>
|
||||
</div>
|
||||
<div
|
||||
className="group flex cursor-pointer items-center rounded-lg px-3 py-1.5 hover:bg-state-destructive-hover"
|
||||
@ -79,7 +79,7 @@ const OperationDropdown: FC<Props> = ({
|
||||
}}
|
||||
>
|
||||
<RiDeleteBinLine className="h-4 w-4 text-text-tertiary group-hover:text-text-destructive-secondary" />
|
||||
<div className="system-md-regular ml-2 text-text-secondary group-hover:text-text-destructive">{t('tools.mcp.operation.remove')}</div>
|
||||
<div className="system-md-regular ml-2 text-text-secondary group-hover:text-text-destructive">{t('mcp.operation.remove', { ns: 'tools' })}</div>
|
||||
</div>
|
||||
</div>
|
||||
</PortalToFollowElemContent>
|
||||
|
||||
@ -28,12 +28,12 @@ const MCPToolItem = ({
|
||||
return (
|
||||
<div className="mt-2">
|
||||
<div className="title-xs-semi-bold mb-1 text-text-primary">
|
||||
{t('tools.mcp.toolItem.parameters')}
|
||||
{t('mcp.toolItem.parameters', { ns: 'tools' })}
|
||||
:
|
||||
</div>
|
||||
<ul className="space-y-1">
|
||||
{parameters.map((parameter) => {
|
||||
const descriptionContent = parameter.human_description[language] || t('tools.mcp.toolItem.noDescription')
|
||||
const descriptionContent = parameter.human_description[language] || t('mcp.toolItem.noDescription', { ns: 'tools' })
|
||||
return (
|
||||
<li key={parameter.name} className="pl-2">
|
||||
<span className="system-xs-regular font-bold text-text-secondary">{parameter.name}</span>
|
||||
|
||||
@ -52,7 +52,7 @@ const HeadersInput = ({
|
||||
return (
|
||||
<div className="space-y-2">
|
||||
<div className="body-xs-regular text-text-tertiary">
|
||||
{t('tools.mcp.modal.noHeaders')}
|
||||
{t('mcp.modal.noHeaders', { ns: 'tools' })}
|
||||
</div>
|
||||
{!readonly && (
|
||||
<Button
|
||||
@ -62,7 +62,7 @@ const HeadersInput = ({
|
||||
className="w-full"
|
||||
>
|
||||
<RiAddLine className="mr-1 h-4 w-4" />
|
||||
{t('tools.mcp.modal.addHeader')}
|
||||
{t('mcp.modal.addHeader', { ns: 'tools' })}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
@ -73,13 +73,13 @@ const HeadersInput = ({
|
||||
<div className="space-y-2">
|
||||
{isMasked && (
|
||||
<div className="body-xs-regular text-text-tertiary">
|
||||
{t('tools.mcp.modal.maskedHeadersTip')}
|
||||
{t('mcp.modal.maskedHeadersTip', { ns: 'tools' })}
|
||||
</div>
|
||||
)}
|
||||
<div className="overflow-hidden rounded-lg border border-divider-regular">
|
||||
<div className="system-xs-medium-uppercase bg-background-secondary flex h-7 items-center leading-7 text-text-tertiary">
|
||||
<div className="h-full w-1/2 border-r border-divider-regular pl-3">{t('tools.mcp.modal.headerKey')}</div>
|
||||
<div className="h-full w-1/2 pl-3 pr-1">{t('tools.mcp.modal.headerValue')}</div>
|
||||
<div className="h-full w-1/2 border-r border-divider-regular pl-3">{t('mcp.modal.headerKey', { ns: 'tools' })}</div>
|
||||
<div className="h-full w-1/2 pl-3 pr-1">{t('mcp.modal.headerValue', { ns: 'tools' })}</div>
|
||||
</div>
|
||||
{headersItems.map((item, index) => (
|
||||
<div
|
||||
@ -93,7 +93,7 @@ const HeadersInput = ({
|
||||
<Input
|
||||
value={item.key}
|
||||
onChange={e => handleItemChange(index, 'key', e.target.value)}
|
||||
placeholder={t('tools.mcp.modal.headerKeyPlaceholder')}
|
||||
placeholder={t('mcp.modal.headerKeyPlaceholder', { ns: 'tools' })}
|
||||
className="rounded-none border-0"
|
||||
readOnly={readonly}
|
||||
/>
|
||||
@ -102,7 +102,7 @@ const HeadersInput = ({
|
||||
<Input
|
||||
value={item.value}
|
||||
onChange={e => handleItemChange(index, 'value', e.target.value)}
|
||||
placeholder={t('tools.mcp.modal.headerValuePlaceholder')}
|
||||
placeholder={t('mcp.modal.headerValuePlaceholder', { ns: 'tools' })}
|
||||
className="flex-1 rounded-none border-0"
|
||||
readOnly={readonly}
|
||||
/>
|
||||
@ -126,7 +126,7 @@ const HeadersInput = ({
|
||||
className="w-full"
|
||||
>
|
||||
<RiAddLine className="mr-1 h-4 w-4" />
|
||||
{t('tools.mcp.modal.addHeader')}
|
||||
{t('mcp.modal.addHeader', { ns: 'tools' })}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@ -97,18 +97,18 @@ const MCPServerModal = ({
|
||||
<RiCloseLine className="h-5 w-5 text-text-tertiary" />
|
||||
</div>
|
||||
<div className="title-2xl-semi-bold relative p-6 pb-3 text-xl text-text-primary">
|
||||
{!data ? t('tools.mcp.server.modal.addTitle') : t('tools.mcp.server.modal.editTitle')}
|
||||
{!data ? t('mcp.server.modal.addTitle', { ns: 'tools' }) : t('mcp.server.modal.editTitle', { ns: 'tools' })}
|
||||
</div>
|
||||
<div className="space-y-5 px-6 py-3">
|
||||
<div className="space-y-0.5">
|
||||
<div className="flex h-6 items-center gap-1">
|
||||
<div className="system-sm-medium text-text-secondary">{t('tools.mcp.server.modal.description')}</div>
|
||||
<div className="system-sm-medium text-text-secondary">{t('mcp.server.modal.description', { ns: 'tools' })}</div>
|
||||
<div className="system-xs-regular text-text-destructive-secondary">*</div>
|
||||
</div>
|
||||
<Textarea
|
||||
className="h-[96px] resize-none"
|
||||
value={description}
|
||||
placeholder={t('tools.mcp.server.modal.descriptionPlaceholder')}
|
||||
placeholder={t('mcp.server.modal.descriptionPlaceholder', { ns: 'tools' })}
|
||||
onChange={e => setDescription(e.target.value)}
|
||||
>
|
||||
</Textarea>
|
||||
@ -116,10 +116,10 @@ const MCPServerModal = ({
|
||||
{latestParams.length > 0 && (
|
||||
<div>
|
||||
<div className="mb-1 flex items-center gap-2">
|
||||
<div className="system-xs-medium-uppercase shrink-0 text-text-primary">{t('tools.mcp.server.modal.parameters')}</div>
|
||||
<div className="system-xs-medium-uppercase shrink-0 text-text-primary">{t('mcp.server.modal.parameters', { ns: 'tools' })}</div>
|
||||
<Divider type="horizontal" className="!m-0 !h-px grow bg-divider-subtle" />
|
||||
</div>
|
||||
<div className="body-xs-regular mb-2 text-text-tertiary">{t('tools.mcp.server.modal.parametersTip')}</div>
|
||||
<div className="body-xs-regular mb-2 text-text-tertiary">{t('mcp.server.modal.parametersTip', { ns: 'tools' })}</div>
|
||||
<div className="space-y-3">
|
||||
{latestParams.map(paramItem => (
|
||||
<MCPServerParamItem
|
||||
@ -134,8 +134,8 @@ const MCPServerModal = ({
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-row-reverse p-6 pt-5">
|
||||
<Button disabled={!description || creating || updating} className="ml-2" variant="primary" onClick={submit}>{data ? t('tools.mcp.modal.save') : t('tools.mcp.server.modal.confirm')}</Button>
|
||||
<Button onClick={onHide}>{t('tools.mcp.modal.cancel')}</Button>
|
||||
<Button disabled={!description || creating || updating} className="ml-2" variant="primary" onClick={submit}>{data ? t('mcp.modal.save', { ns: 'tools' }) : t('mcp.server.modal.confirm', { ns: 'tools' })}</Button>
|
||||
<Button onClick={onHide}>{t('mcp.modal.cancel', { ns: 'tools' })}</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
)
|
||||
|
||||
@ -27,7 +27,7 @@ const MCPServerParamItem = ({
|
||||
<Textarea
|
||||
className="h-8 resize-none"
|
||||
value={value}
|
||||
placeholder={t('tools.mcp.server.modal.parametersPlaceholder')}
|
||||
placeholder={t('mcp.server.modal.parametersPlaceholder', { ns: 'tools' })}
|
||||
onChange={e => onChange(e.target.value)}
|
||||
>
|
||||
</Textarea>
|
||||
|
||||
@ -172,7 +172,7 @@ function MCPServiceCard({
|
||||
</div>
|
||||
<div className="group w-full">
|
||||
<div className="system-md-semibold min-w-0 overflow-hidden text-ellipsis break-normal text-text-secondary group-hover:text-text-primary">
|
||||
{t('tools.mcp.server.title')}
|
||||
{t('mcp.server.title', { ns: 'tools' })}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -180,8 +180,8 @@ function MCPServiceCard({
|
||||
<Indicator color={serverActivated ? 'green' : 'yellow'} />
|
||||
<div className={`${serverActivated ? 'text-text-success' : 'text-text-warning'} system-xs-semibold-uppercase`}>
|
||||
{serverActivated
|
||||
? t('appOverview.overview.status.running')
|
||||
: t('appOverview.overview.status.disable')}
|
||||
? t('overview.status.running', { ns: 'appOverview' })
|
||||
: t('overview.status.disable', { ns: 'appOverview' })}
|
||||
</div>
|
||||
</div>
|
||||
<Tooltip
|
||||
@ -190,19 +190,19 @@ function MCPServiceCard({
|
||||
? (
|
||||
appUnpublished
|
||||
? (
|
||||
t('tools.mcp.server.publishTip')
|
||||
t('mcp.server.publishTip', { ns: 'tools' })
|
||||
)
|
||||
: missingStartNode
|
||||
? (
|
||||
<>
|
||||
<div className="mb-1 text-xs font-normal text-text-secondary">
|
||||
{t('appOverview.overview.appInfo.enableTooltip.description')}
|
||||
{t('overview.appInfo.enableTooltip.description', { ns: 'appOverview' })}
|
||||
</div>
|
||||
<div
|
||||
className="cursor-pointer text-xs font-normal text-text-accent hover:underline"
|
||||
onClick={() => window.open(docLink('/guides/workflow/node/user-input'), '_blank')}
|
||||
>
|
||||
{t('appOverview.overview.appInfo.enableTooltip.learnMore')}
|
||||
{t('overview.appInfo.enableTooltip.learnMore', { ns: 'appOverview' })}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
@ -222,7 +222,7 @@ function MCPServiceCard({
|
||||
{!isMinimalState && (
|
||||
<div className="flex flex-col items-start justify-center self-stretch">
|
||||
<div className="system-xs-medium pb-1 text-text-tertiary">
|
||||
{t('tools.mcp.server.url')}
|
||||
{t('mcp.server.url', { ns: 'tools' })}
|
||||
</div>
|
||||
<div className="inline-flex h-9 w-full items-center gap-0.5 rounded-lg bg-components-input-bg-normal p-1 pl-2">
|
||||
<div className="flex h-4 min-w-0 flex-1 items-start justify-start gap-2 px-1">
|
||||
@ -239,7 +239,7 @@ function MCPServiceCard({
|
||||
<Divider type="vertical" className="!mx-0.5 !h-3.5 shrink-0" />
|
||||
{isCurrentWorkspaceManager && (
|
||||
<Tooltip
|
||||
popupContent={t('appOverview.overview.appInfo.regenerate') || ''}
|
||||
popupContent={t('overview.appInfo.regenerate', { ns: 'appOverview' }) || ''}
|
||||
>
|
||||
<div
|
||||
className="cursor-pointer rounded-md p-1 hover:bg-state-base-hover"
|
||||
@ -266,7 +266,7 @@ function MCPServiceCard({
|
||||
|
||||
<div className="flex items-center justify-center gap-[1px]">
|
||||
<RiEditLine className="h-3.5 w-3.5" />
|
||||
<div className="system-xs-medium px-[3px] text-text-tertiary">{serverPublished ? t('tools.mcp.server.edit') : t('tools.mcp.server.addDescription')}</div>
|
||||
<div className="system-xs-medium px-[3px] text-text-tertiary">{serverPublished ? t('mcp.server.edit', { ns: 'tools' }) : t('mcp.server.addDescription', { ns: 'tools' })}</div>
|
||||
</div>
|
||||
</Button>
|
||||
</div>
|
||||
@ -287,8 +287,8 @@ function MCPServiceCard({
|
||||
{showConfirmDelete && (
|
||||
<Confirm
|
||||
type="warning"
|
||||
title={t('appOverview.overview.appInfo.regenerate')}
|
||||
content={t('tools.mcp.server.reGen')}
|
||||
title={t('overview.appInfo.regenerate', { ns: 'appOverview' })}
|
||||
content={t('mcp.server.reGen', { ns: 'tools' })}
|
||||
isShow={showConfirmDelete}
|
||||
onConfirm={() => {
|
||||
onGenCode()
|
||||
|
||||
@ -81,15 +81,15 @@ const MCPModal = ({
|
||||
|
||||
const authMethods = [
|
||||
{
|
||||
text: t('tools.mcp.modal.authentication'),
|
||||
text: t('mcp.modal.authentication', { ns: 'tools' }),
|
||||
value: MCPAuthMethod.authentication,
|
||||
},
|
||||
{
|
||||
text: t('tools.mcp.modal.headers'),
|
||||
text: t('mcp.modal.headers', { ns: 'tools' }),
|
||||
value: MCPAuthMethod.headers,
|
||||
},
|
||||
{
|
||||
text: t('tools.mcp.modal.configurations'),
|
||||
text: t('mcp.modal.configurations', { ns: 'tools' }),
|
||||
value: MCPAuthMethod.configurations,
|
||||
},
|
||||
]
|
||||
@ -231,33 +231,33 @@ const MCPModal = ({
|
||||
<div className="absolute right-5 top-5 z-10 cursor-pointer p-1.5" onClick={onHide}>
|
||||
<RiCloseLine className="h-5 w-5 text-text-tertiary" />
|
||||
</div>
|
||||
<div className="title-2xl-semi-bold relative pb-3 text-xl text-text-primary">{!isCreate ? t('tools.mcp.modal.editTitle') : t('tools.mcp.modal.title')}</div>
|
||||
<div className="title-2xl-semi-bold relative pb-3 text-xl text-text-primary">{!isCreate ? t('mcp.modal.editTitle', { ns: 'tools' }) : t('mcp.modal.title', { ns: 'tools' })}</div>
|
||||
<div className="space-y-5 py-3">
|
||||
<div>
|
||||
<div className="mb-1 flex h-6 items-center">
|
||||
<span className="system-sm-medium text-text-secondary">{t('tools.mcp.modal.serverUrl')}</span>
|
||||
<span className="system-sm-medium text-text-secondary">{t('mcp.modal.serverUrl', { ns: 'tools' })}</span>
|
||||
</div>
|
||||
<Input
|
||||
value={url}
|
||||
onChange={e => setUrl(e.target.value)}
|
||||
onBlur={e => handleBlur(e.target.value.trim())}
|
||||
placeholder={t('tools.mcp.modal.serverUrlPlaceholder')}
|
||||
placeholder={t('mcp.modal.serverUrlPlaceholder', { ns: 'tools' })}
|
||||
/>
|
||||
{originalServerUrl && originalServerUrl !== url && (
|
||||
<div className="mt-1 flex h-5 items-center">
|
||||
<span className="body-xs-regular text-text-warning">{t('tools.mcp.modal.serverUrlWarning')}</span>
|
||||
<span className="body-xs-regular text-text-warning">{t('mcp.modal.serverUrlWarning', { ns: 'tools' })}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex space-x-3">
|
||||
<div className="grow pb-1">
|
||||
<div className="mb-1 flex h-6 items-center">
|
||||
<span className="system-sm-medium text-text-secondary">{t('tools.mcp.modal.name')}</span>
|
||||
<span className="system-sm-medium text-text-secondary">{t('mcp.modal.name', { ns: 'tools' })}</span>
|
||||
</div>
|
||||
<Input
|
||||
value={name}
|
||||
onChange={e => setName(e.target.value)}
|
||||
placeholder={t('tools.mcp.modal.namePlaceholder')}
|
||||
placeholder={t('mcp.modal.namePlaceholder', { ns: 'tools' })}
|
||||
/>
|
||||
</div>
|
||||
<div className="pt-2" ref={appIconRef}>
|
||||
@ -284,17 +284,17 @@ const MCPModal = ({
|
||||
</div>
|
||||
<div>
|
||||
<div className="flex h-6 items-center">
|
||||
<span className="system-sm-medium text-text-secondary">{t('tools.mcp.modal.serverIdentifier')}</span>
|
||||
<span className="system-sm-medium text-text-secondary">{t('mcp.modal.serverIdentifier', { ns: 'tools' })}</span>
|
||||
</div>
|
||||
<div className="body-xs-regular mb-1 text-text-tertiary">{t('tools.mcp.modal.serverIdentifierTip')}</div>
|
||||
<div className="body-xs-regular mb-1 text-text-tertiary">{t('mcp.modal.serverIdentifierTip', { ns: 'tools' })}</div>
|
||||
<Input
|
||||
value={serverIdentifier}
|
||||
onChange={e => setServerIdentifier(e.target.value)}
|
||||
placeholder={t('tools.mcp.modal.serverIdentifierPlaceholder')}
|
||||
placeholder={t('mcp.modal.serverIdentifierPlaceholder', { ns: 'tools' })}
|
||||
/>
|
||||
{originalServerID && originalServerID !== serverIdentifier && (
|
||||
<div className="mt-1 flex h-5 items-center">
|
||||
<span className="body-xs-regular text-text-warning">{t('tools.mcp.modal.serverIdentifierWarning')}</span>
|
||||
<span className="body-xs-regular text-text-warning">{t('mcp.modal.serverIdentifierWarning', { ns: 'tools' })}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@ -317,13 +317,13 @@ const MCPModal = ({
|
||||
defaultValue={isDynamicRegistration}
|
||||
onChange={setIsDynamicRegistration}
|
||||
/>
|
||||
<span className="system-sm-medium text-text-secondary">{t('tools.mcp.modal.useDynamicClientRegistration')}</span>
|
||||
<span className="system-sm-medium text-text-secondary">{t('mcp.modal.useDynamicClientRegistration', { ns: 'tools' })}</span>
|
||||
</div>
|
||||
{!isDynamicRegistration && (
|
||||
<div className="mt-2 flex gap-2 rounded-lg bg-state-warning-hover p-3">
|
||||
<AlertTriangle className="mt-0.5 h-4 w-4 shrink-0 text-text-warning" />
|
||||
<div className="system-xs-regular text-text-secondary">
|
||||
<div className="mb-1">{t('tools.mcp.modal.redirectUrlWarning')}</div>
|
||||
<div className="mb-1">{t('mcp.modal.redirectUrlWarning', { ns: 'tools' })}</div>
|
||||
<code className="system-xs-medium block break-all rounded bg-state-warning-active px-2 py-1 text-text-secondary">
|
||||
{`${API_PREFIX}/mcp/oauth/callback`}
|
||||
</code>
|
||||
@ -333,25 +333,25 @@ const MCPModal = ({
|
||||
</div>
|
||||
<div>
|
||||
<div className={cn('mb-1 flex h-6 items-center', isDynamicRegistration && 'opacity-50')}>
|
||||
<span className="system-sm-medium text-text-secondary">{t('tools.mcp.modal.clientID')}</span>
|
||||
<span className="system-sm-medium text-text-secondary">{t('mcp.modal.clientID', { ns: 'tools' })}</span>
|
||||
</div>
|
||||
<Input
|
||||
value={clientID}
|
||||
onChange={e => setClientID(e.target.value)}
|
||||
onBlur={e => handleBlur(e.target.value.trim())}
|
||||
placeholder={t('tools.mcp.modal.clientID')}
|
||||
placeholder={t('mcp.modal.clientID', { ns: 'tools' })}
|
||||
disabled={isDynamicRegistration}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div className={cn('mb-1 flex h-6 items-center', isDynamicRegistration && 'opacity-50')}>
|
||||
<span className="system-sm-medium text-text-secondary">{t('tools.mcp.modal.clientSecret')}</span>
|
||||
<span className="system-sm-medium text-text-secondary">{t('mcp.modal.clientSecret', { ns: 'tools' })}</span>
|
||||
</div>
|
||||
<Input
|
||||
value={credentials}
|
||||
onChange={e => setCredentials(e.target.value)}
|
||||
onBlur={e => handleBlur(e.target.value.trim())}
|
||||
placeholder={t('tools.mcp.modal.clientSecretPlaceholder')}
|
||||
placeholder={t('mcp.modal.clientSecretPlaceholder', { ns: 'tools' })}
|
||||
disabled={isDynamicRegistration}
|
||||
/>
|
||||
</div>
|
||||
@ -362,9 +362,9 @@ const MCPModal = ({
|
||||
authMethod === MCPAuthMethod.headers && (
|
||||
<div>
|
||||
<div className="mb-1 flex h-6 items-center">
|
||||
<span className="system-sm-medium text-text-secondary">{t('tools.mcp.modal.headers')}</span>
|
||||
<span className="system-sm-medium text-text-secondary">{t('mcp.modal.headers', { ns: 'tools' })}</span>
|
||||
</div>
|
||||
<div className="body-xs-regular mb-2 text-text-tertiary">{t('tools.mcp.modal.headersTip')}</div>
|
||||
<div className="body-xs-regular mb-2 text-text-tertiary">{t('mcp.modal.headersTip', { ns: 'tools' })}</div>
|
||||
<HeadersInput
|
||||
headersItems={headers}
|
||||
onChange={setHeaders}
|
||||
@ -379,26 +379,26 @@ const MCPModal = ({
|
||||
<>
|
||||
<div>
|
||||
<div className="mb-1 flex h-6 items-center">
|
||||
<span className="system-sm-medium text-text-secondary">{t('tools.mcp.modal.timeout')}</span>
|
||||
<span className="system-sm-medium text-text-secondary">{t('mcp.modal.timeout', { ns: 'tools' })}</span>
|
||||
</div>
|
||||
<Input
|
||||
type="number"
|
||||
value={timeout}
|
||||
onChange={e => setMcpTimeout(Number(e.target.value))}
|
||||
onBlur={e => handleBlur(e.target.value.trim())}
|
||||
placeholder={t('tools.mcp.modal.timeoutPlaceholder')}
|
||||
placeholder={t('mcp.modal.timeoutPlaceholder', { ns: 'tools' })}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div className="mb-1 flex h-6 items-center">
|
||||
<span className="system-sm-medium text-text-secondary">{t('tools.mcp.modal.sseReadTimeout')}</span>
|
||||
<span className="system-sm-medium text-text-secondary">{t('mcp.modal.sseReadTimeout', { ns: 'tools' })}</span>
|
||||
</div>
|
||||
<Input
|
||||
type="number"
|
||||
value={sseReadTimeout}
|
||||
onChange={e => setSseReadTimeout(Number(e.target.value))}
|
||||
onBlur={e => handleBlur(e.target.value.trim())}
|
||||
placeholder={t('tools.mcp.modal.timeoutPlaceholder')}
|
||||
placeholder={t('mcp.modal.timeoutPlaceholder', { ns: 'tools' })}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
@ -406,8 +406,8 @@ const MCPModal = ({
|
||||
}
|
||||
</div>
|
||||
<div className="flex flex-row-reverse pt-5">
|
||||
<Button disabled={!name || !url || !serverIdentifier || isFetchingIcon} className="ml-2" variant="primary" onClick={submit}>{data ? t('tools.mcp.modal.save') : t('tools.mcp.modal.confirm')}</Button>
|
||||
<Button onClick={onHide}>{t('tools.mcp.modal.cancel')}</Button>
|
||||
<Button disabled={!name || !url || !serverIdentifier || isFetchingIcon} className="ml-2" variant="primary" onClick={submit}>{data ? t('mcp.modal.save', { ns: 'tools' }) : t('mcp.modal.confirm', { ns: 'tools' })}</Button>
|
||||
<Button onClick={onHide}>{t('mcp.modal.cancel', { ns: 'tools' })}</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
{showAppIconPicker && (
|
||||
|
||||
@ -96,19 +96,19 @@ const MCPCard = ({
|
||||
<div className="flex items-center gap-1">
|
||||
<RiHammerFill className="h-3 w-3 shrink-0 text-text-quaternary" />
|
||||
{data.tools.length > 0 && (
|
||||
<div className="system-xs-regular shrink-0 text-text-tertiary">{t('tools.mcp.toolsCount', { count: data.tools.length })}</div>
|
||||
<div className="system-xs-regular shrink-0 text-text-tertiary">{t('mcp.toolsCount', { ns: 'tools', count: data.tools.length })}</div>
|
||||
)}
|
||||
{!data.tools.length && (
|
||||
<div className="system-xs-regular shrink-0 text-text-tertiary">{t('tools.mcp.noTools')}</div>
|
||||
<div className="system-xs-regular shrink-0 text-text-tertiary">{t('mcp.noTools', { ns: 'tools' })}</div>
|
||||
)}
|
||||
</div>
|
||||
<div className={cn('system-xs-regular text-divider-deep', (!data.is_team_authorization || !data.tools.length) && 'sm:hidden')}>/</div>
|
||||
<div className={cn('system-xs-regular truncate text-text-tertiary', (!data.is_team_authorization || !data.tools.length) && ' sm:hidden')} title={`${t('tools.mcp.updateTime')} ${formatTimeFromNow(data.updated_at! * 1000)}`}>{`${t('tools.mcp.updateTime')} ${formatTimeFromNow(data.updated_at! * 1000)}`}</div>
|
||||
<div className={cn('system-xs-regular truncate text-text-tertiary', (!data.is_team_authorization || !data.tools.length) && ' sm:hidden')} title={`${t('mcp.updateTime', { ns: 'tools' })} ${formatTimeFromNow(data.updated_at! * 1000)}`}>{`${t('mcp.updateTime', { ns: 'tools' })} ${formatTimeFromNow(data.updated_at! * 1000)}`}</div>
|
||||
</div>
|
||||
{data.is_team_authorization && data.tools.length > 0 && <Indicator color="green" className="shrink-0" />}
|
||||
{(!data.is_team_authorization || !data.tools.length) && (
|
||||
<div className="system-xs-medium flex shrink-0 items-center gap-1 rounded-md border border-util-colors-red-red-500 bg-components-badge-bg-red-soft px-1.5 py-0.5 text-util-colors-red-red-500">
|
||||
{t('tools.mcp.noConfigured')}
|
||||
{t('mcp.noConfigured', { ns: 'tools' })}
|
||||
<Indicator color="red" />
|
||||
</div>
|
||||
)}
|
||||
@ -134,10 +134,10 @@ const MCPCard = ({
|
||||
{isShowDeleteConfirm && (
|
||||
<Confirm
|
||||
isShow
|
||||
title={t('tools.mcp.delete')}
|
||||
title={t('mcp.delete', { ns: 'tools' })}
|
||||
content={(
|
||||
<div>
|
||||
{t('tools.mcp.deleteConfirmTitle', { mcp: data.name })}
|
||||
{t('mcp.deleteConfirmTitle', { ns: 'tools', mcp: data.name })}
|
||||
</div>
|
||||
)}
|
||||
onCancel={hideDeleteConfirm}
|
||||
|
||||
@ -49,9 +49,9 @@ const ProviderList = () => {
|
||||
defaultValue: 'builtin',
|
||||
})
|
||||
const options = [
|
||||
{ value: 'builtin', text: t('tools.type.builtIn') },
|
||||
{ value: 'api', text: t('tools.type.custom') },
|
||||
{ value: 'workflow', text: t('tools.type.workflow') },
|
||||
{ value: 'builtin', text: t('type.builtIn', { ns: 'tools' }) },
|
||||
{ value: 'api', text: t('type.custom', { ns: 'tools' }) },
|
||||
{ value: 'workflow', text: t('type.workflow', { ns: 'tools' }) },
|
||||
{ value: 'mcp', text: 'MCP' },
|
||||
]
|
||||
const [tagFilterValue, setTagFilterValue] = useState<string[]>([])
|
||||
@ -194,7 +194,7 @@ const ProviderList = () => {
|
||||
</div>
|
||||
)}
|
||||
{!filteredCollectionList.length && activeTab === 'builtin' && (
|
||||
<Empty lightCard text={t('tools.noTools')} className="h-[224px] shrink-0 px-12" />
|
||||
<Empty lightCard text={t('noTools', { ns: 'tools' })} className="h-[224px] shrink-0 px-12" />
|
||||
)}
|
||||
<div ref={toolListTailRef} />
|
||||
{enable_marketplace && activeTab === 'builtin' && (
|
||||
|
||||
@ -37,7 +37,7 @@ const Contribute = ({ onRefreshData }: Props) => {
|
||||
await createCustomCollection(data)
|
||||
Toast.notify({
|
||||
type: 'success',
|
||||
message: t('common.api.actionSuccess'),
|
||||
message: t('api.actionSuccess', { ns: 'common' }),
|
||||
})
|
||||
setIsShowEditCustomCollectionModal(false)
|
||||
onRefreshData()
|
||||
@ -52,13 +52,13 @@ const Contribute = ({ onRefreshData }: Props) => {
|
||||
<div className="flex h-10 w-10 items-center justify-center rounded-lg border border-dashed border-divider-deep group-hover:border-solid group-hover:border-state-accent-hover-alt group-hover:bg-state-accent-hover">
|
||||
<RiAddCircleFill className="h-4 w-4 text-text-quaternary group-hover:text-text-accent" />
|
||||
</div>
|
||||
<div className="system-md-semibold ml-3 text-text-secondary group-hover:text-text-accent">{t('tools.createCustomTool')}</div>
|
||||
<div className="system-md-semibold ml-3 text-text-secondary group-hover:text-text-accent">{t('createCustomTool', { ns: 'tools' })}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="rounded-b-xl border-t-[0.5px] border-divider-subtle px-4 py-3 text-text-tertiary hover:text-text-accent">
|
||||
<a href={linkUrl} target="_blank" rel="noopener noreferrer" className="flex items-center space-x-1">
|
||||
<RiBookOpenLine className="h-3 w-3 shrink-0" />
|
||||
<div className="system-xs-regular grow truncate" title={t('tools.customToolTip') || ''}>{t('tools.customToolTip')}</div>
|
||||
<div className="system-xs-regular grow truncate" title={t('customToolTip', { ns: 'tools' }) || ''}>{t('customToolTip', { ns: 'tools' })}</div>
|
||||
<RiArrowRightUpLine className="h-3 w-3 shrink-0" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@ -124,7 +124,7 @@ const ProviderDetail = ({
|
||||
setCustomCollection(prev => prev ? { ...prev, labels: data.labels } : null)
|
||||
Toast.notify({
|
||||
type: 'success',
|
||||
message: t('common.api.actionSuccess'),
|
||||
message: t('api.actionSuccess', { ns: 'common' }),
|
||||
})
|
||||
setIsShowEditCustomCollectionModal(false)
|
||||
}
|
||||
@ -133,7 +133,7 @@ const ProviderDetail = ({
|
||||
onRefreshData()
|
||||
Toast.notify({
|
||||
type: 'success',
|
||||
message: t('common.api.actionSuccess'),
|
||||
message: t('api.actionSuccess', { ns: 'common' }),
|
||||
})
|
||||
setIsShowEditCustomCollectionModal(false)
|
||||
}
|
||||
@ -163,7 +163,7 @@ const ProviderDetail = ({
|
||||
onRefreshData()
|
||||
Toast.notify({
|
||||
type: 'success',
|
||||
message: t('common.api.actionSuccess'),
|
||||
message: t('api.actionSuccess', { ns: 'common' }),
|
||||
})
|
||||
setIsShowEditWorkflowToolModal(false)
|
||||
}
|
||||
@ -177,7 +177,7 @@ const ProviderDetail = ({
|
||||
getWorkflowToolProvider()
|
||||
Toast.notify({
|
||||
type: 'success',
|
||||
message: t('common.api.actionSuccess'),
|
||||
message: t('api.actionSuccess', { ns: 'common' }),
|
||||
})
|
||||
setIsShowEditWorkflowToolModal(false)
|
||||
}
|
||||
@ -275,7 +275,7 @@ const ProviderDetail = ({
|
||||
onClick={() => setIsShowEditCustomCollectionModal(true)}
|
||||
>
|
||||
<Settings01 className="mr-1 h-4 w-4 text-text-tertiary" />
|
||||
<div className="system-sm-medium text-text-secondary">{t('tools.createTool.editAction')}</div>
|
||||
<div className="system-sm-medium text-text-secondary">{t('createTool.editAction', { ns: 'tools' })}</div>
|
||||
</Button>
|
||||
)}
|
||||
{collection.type === CollectionType.workflow && !isDetailLoading && customCollection && (
|
||||
@ -285,7 +285,7 @@ const ProviderDetail = ({
|
||||
className={cn('my-3 w-[183px] shrink-0')}
|
||||
>
|
||||
<a className="flex items-center" href={`${basePath}/app/${(customCollection as WorkflowToolProviderResponse).workflow_app_id}/workflow`} rel="noreferrer" target="_blank">
|
||||
<div className="system-sm-medium">{t('tools.openInStudio')}</div>
|
||||
<div className="system-sm-medium">{t('openInStudio', { ns: 'tools' })}</div>
|
||||
<LinkExternal02 className="ml-1 h-4 w-4" />
|
||||
</a>
|
||||
</Button>
|
||||
@ -294,7 +294,7 @@ const ProviderDetail = ({
|
||||
onClick={() => setIsShowEditWorkflowToolModal(true)}
|
||||
disabled={!isCurrentWorkspaceManager}
|
||||
>
|
||||
<div className="system-sm-medium text-text-secondary">{t('tools.createTool.editAction')}</div>
|
||||
<div className="system-sm-medium text-text-secondary">{t('createTool.editAction', { ns: 'tools' })}</div>
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
@ -306,7 +306,7 @@ const ProviderDetail = ({
|
||||
<div className="shrink-0">
|
||||
{(collection.type === CollectionType.builtIn || collection.type === CollectionType.model) && isAuthed && (
|
||||
<div className="system-sm-semibold-uppercase mb-1 flex h-6 items-center justify-between text-text-secondary">
|
||||
{t('plugin.detailPanel.actionNum', { num: toolList.length, action: toolList.length > 1 ? 'actions' : 'action' })}
|
||||
{t('detailPanel.actionNum', { ns: 'plugin', num: toolList.length, action: toolList.length > 1 ? 'actions' : 'action' })}
|
||||
{needAuth && (
|
||||
<Button
|
||||
variant="secondary"
|
||||
@ -318,7 +318,7 @@ const ProviderDetail = ({
|
||||
disabled={!isCurrentWorkspaceManager}
|
||||
>
|
||||
<Indicator className="mr-2" color="green" />
|
||||
{t('tools.auth.authorized')}
|
||||
{t('auth.authorized', { ns: 'tools' })}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
@ -326,9 +326,9 @@ const ProviderDetail = ({
|
||||
{(collection.type === CollectionType.builtIn || collection.type === CollectionType.model) && needAuth && !isAuthed && (
|
||||
<>
|
||||
<div className="system-sm-semibold-uppercase text-text-secondary">
|
||||
<span className="">{t('tools.includeToolNum', { num: toolList.length, action: toolList.length > 1 ? 'actions' : 'action' }).toLocaleUpperCase()}</span>
|
||||
<span className="">{t('includeToolNum', { ns: 'tools', num: toolList.length, action: toolList.length > 1 ? 'actions' : 'action' }).toLocaleUpperCase()}</span>
|
||||
<span className="px-1">·</span>
|
||||
<span className="text-util-colors-orange-orange-600">{t('tools.auth.setup').toLocaleUpperCase()}</span>
|
||||
<span className="text-util-colors-orange-orange-600">{t('auth.setup', { ns: 'tools' }).toLocaleUpperCase()}</span>
|
||||
</div>
|
||||
<Button
|
||||
variant="primary"
|
||||
@ -339,18 +339,18 @@ const ProviderDetail = ({
|
||||
}}
|
||||
disabled={!isCurrentWorkspaceManager}
|
||||
>
|
||||
{t('tools.auth.unauthorized')}
|
||||
{t('auth.unauthorized', { ns: 'tools' })}
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
{(collection.type === CollectionType.custom) && (
|
||||
<div className="system-sm-semibold-uppercase text-text-secondary">
|
||||
<span className="">{t('tools.includeToolNum', { num: toolList.length, action: toolList.length > 1 ? 'actions' : 'action' }).toLocaleUpperCase()}</span>
|
||||
<span className="">{t('includeToolNum', { ns: 'tools', num: toolList.length, action: toolList.length > 1 ? 'actions' : 'action' }).toLocaleUpperCase()}</span>
|
||||
</div>
|
||||
)}
|
||||
{(collection.type === CollectionType.workflow) && (
|
||||
<div className="system-sm-semibold-uppercase text-text-secondary">
|
||||
<span className="">{t('tools.createTool.toolInput.title').toLocaleUpperCase()}</span>
|
||||
<span className="">{t('createTool.toolInput.title', { ns: 'tools' }).toLocaleUpperCase()}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@ -370,7 +370,7 @@ const ProviderDetail = ({
|
||||
<div className="mb-1 flex items-center gap-2">
|
||||
<span className="code-sm-semibold text-text-secondary">{item.name}</span>
|
||||
<span className="system-xs-regular text-text-tertiary">{item.type}</span>
|
||||
<span className="system-xs-medium text-text-warning-secondary">{item.required ? t('tools.createTool.toolInput.required') : ''}</span>
|
||||
<span className="system-xs-medium text-text-warning-secondary">{item.required ? t('createTool.toolInput.required', { ns: 'tools' }) : ''}</span>
|
||||
</div>
|
||||
<div className="system-xs-regular text-text-tertiary">{item.llm_description}</div>
|
||||
</div>
|
||||
@ -387,7 +387,7 @@ const ProviderDetail = ({
|
||||
await updateBuiltInToolCredential(collection.name, value)
|
||||
Toast.notify({
|
||||
type: 'success',
|
||||
message: t('common.api.actionSuccess'),
|
||||
message: t('api.actionSuccess', { ns: 'common' }),
|
||||
})
|
||||
await onRefreshData()
|
||||
setShowSettingAuth(false)
|
||||
@ -396,7 +396,7 @@ const ProviderDetail = ({
|
||||
await removeBuiltInToolCredential(collection.name)
|
||||
Toast.notify({
|
||||
type: 'success',
|
||||
message: t('common.api.actionSuccess'),
|
||||
message: t('api.actionSuccess', { ns: 'common' }),
|
||||
})
|
||||
await onRefreshData()
|
||||
setShowSettingAuth(false)
|
||||
@ -421,8 +421,8 @@ const ProviderDetail = ({
|
||||
)}
|
||||
{showConfirmDelete && (
|
||||
<Confirm
|
||||
title={t('tools.createTool.deleteToolConfirmTitle')}
|
||||
content={t('tools.createTool.deleteToolConfirmContent')}
|
||||
title={t('createTool.deleteToolConfirmTitle', { ns: 'tools' })}
|
||||
content={t('createTool.deleteToolConfirmContent', { ns: 'tools' })}
|
||||
isShow={showConfirmDelete}
|
||||
onConfirm={handleConfirmDelete}
|
||||
onCancel={() => setShowConfirmDelete(false)}
|
||||
|
||||
@ -32,18 +32,18 @@ const Empty = ({
|
||||
const hasLink = type && [ToolTypeEnum.Custom, ToolTypeEnum.MCP].includes(type)
|
||||
const Comp = (hasLink ? Link : 'div') as any
|
||||
const linkProps = hasLink ? { href: getLink(type), target: '_blank' } : {}
|
||||
const renderType = isAgent ? 'agent' : type
|
||||
const hasTitle = t(`tools.addToolModal.${renderType}.title` as any) as string !== `tools.addToolModal.${renderType}.title`
|
||||
const renderType = isAgent ? 'agent' as const : type
|
||||
const hasTitle = renderType && t(`addToolModal.${renderType}.title`, { ns: 'tools' }) !== `addToolModal.${renderType}.title`
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center">
|
||||
<NoToolPlaceholder className={theme === 'dark' ? 'invert' : ''} />
|
||||
<div className="mb-1 mt-2 text-[13px] font-medium leading-[18px] text-text-primary">
|
||||
{hasTitle ? t(`tools.addToolModal.${renderType}.title` as any) as string : 'No tools available'}
|
||||
{(hasTitle && renderType) ? t(`addToolModal.${renderType}.title`, { ns: 'tools' }) : 'No tools available'}
|
||||
</div>
|
||||
{(!isAgent && hasTitle) && (
|
||||
{(!isAgent && hasTitle && renderType) && (
|
||||
<Comp className={cn('flex items-center text-[13px] leading-[18px] text-text-tertiary', hasLink && 'cursor-pointer hover:text-text-accent')} {...linkProps}>
|
||||
{t(`tools.addToolModal.${renderType}.tip` as any) as string}
|
||||
{t(`addToolModal.${renderType}.tip`, { ns: 'tools' })}
|
||||
{' '}
|
||||
{hasLink && <RiArrowRightUpLine className="ml-0.5 h-3 w-3" />}
|
||||
</Comp>
|
||||
|
||||
@ -53,7 +53,7 @@ const ConfigCredential: FC<Props> = ({
|
||||
const handleSave = async () => {
|
||||
for (const field of credentialSchema) {
|
||||
if (field.required && !tempCredential[field.name]) {
|
||||
Toast.notify({ type: 'error', message: t('common.errorMsg.fieldRequired', { field: field.label[language] || field.label.en_US }) })
|
||||
Toast.notify({ type: 'error', message: t('errorMsg.fieldRequired', { ns: 'common', field: field.label[language] || field.label.en_US }) })
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -71,8 +71,8 @@ const ConfigCredential: FC<Props> = ({
|
||||
<Drawer
|
||||
isShow
|
||||
onHide={onCancel}
|
||||
title={t('tools.auth.setupModalTitle') as string}
|
||||
titleDescription={t('tools.auth.setupModalTitleDescription') as string}
|
||||
title={t('auth.setupModalTitle', { ns: 'tools' }) as string}
|
||||
titleDescription={t('auth.setupModalTitleDescription', { ns: 'tools' }) as string}
|
||||
panelClassName="mt-[64px] mb-2 !w-[420px] border-components-panel-border"
|
||||
maxWidthClassName="!max-w-[420px]"
|
||||
height="calc(100vh - 64px)"
|
||||
@ -102,7 +102,7 @@ const ConfigCredential: FC<Props> = ({
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex items-center text-xs text-text-accent"
|
||||
>
|
||||
{t('tools.howToGet')}
|
||||
{t('howToGet', { ns: 'tools' })}
|
||||
<LinkExternal02 className="ml-1 h-3 w-3" />
|
||||
</a>
|
||||
)
|
||||
@ -111,12 +111,12 @@ const ConfigCredential: FC<Props> = ({
|
||||
<div className={cn((collection.is_team_authorization && !isHideRemoveBtn) ? 'justify-between' : 'justify-end', 'mt-2 flex ')}>
|
||||
{
|
||||
(collection.is_team_authorization && !isHideRemoveBtn) && (
|
||||
<Button onClick={onRemove}>{t('common.operation.remove')}</Button>
|
||||
<Button onClick={onRemove}>{t('operation.remove', { ns: 'common' })}</Button>
|
||||
)
|
||||
}
|
||||
<div className="flex space-x-2">
|
||||
<Button onClick={onCancel}>{t('common.operation.cancel')}</Button>
|
||||
<Button loading={isLoading || isSaving} disabled={isLoading || isSaving} variant="primary" onClick={handleSave}>{t('common.operation.save')}</Button>
|
||||
<Button onClick={onCancel}>{t('operation.cancel', { ns: 'common' })}</Button>
|
||||
<Button loading={isLoading || isSaving} disabled={isLoading || isSaving} variant="primary" onClick={handleSave}>{t('operation.save', { ns: 'common' })}</Button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
||||
@ -166,7 +166,7 @@ const WorkflowToolConfigureButton = ({
|
||||
getDetail(workflowAppId)
|
||||
Toast.notify({
|
||||
type: 'success',
|
||||
message: t('common.api.actionSuccess'),
|
||||
message: t('api.actionSuccess', { ns: 'common' }),
|
||||
})
|
||||
setShowModal(false)
|
||||
}
|
||||
@ -187,7 +187,7 @@ const WorkflowToolConfigureButton = ({
|
||||
getDetail(workflowAppId)
|
||||
Toast.notify({
|
||||
type: 'success',
|
||||
message: t('common.api.actionSuccess'),
|
||||
message: t('api.actionSuccess', { ns: 'common' }),
|
||||
})
|
||||
setShowModal(false)
|
||||
}
|
||||
@ -214,14 +214,14 @@ const WorkflowToolConfigureButton = ({
|
||||
>
|
||||
<RiHammerLine className={cn('relative h-4 w-4 text-text-secondary', !disabled && !published && 'group-hover:text-text-accent')} />
|
||||
<div
|
||||
title={t('workflow.common.workflowAsTool') || ''}
|
||||
title={t('common.workflowAsTool', { ns: 'workflow' }) || ''}
|
||||
className={cn('system-sm-medium shrink grow basis-0 truncate text-text-secondary', !disabled && !published && 'group-hover:text-text-accent')}
|
||||
>
|
||||
{t('workflow.common.workflowAsTool')}
|
||||
{t('common.workflowAsTool', { ns: 'workflow' })}
|
||||
</div>
|
||||
{!published && (
|
||||
<span className="system-2xs-medium-uppercase shrink-0 rounded-[5px] border border-divider-deep bg-components-badge-bg-dimm px-1 py-0.5 text-text-tertiary">
|
||||
{t('workflow.common.configureRequired')}
|
||||
{t('common.configureRequired', { ns: 'workflow' })}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
@ -232,10 +232,10 @@ const WorkflowToolConfigureButton = ({
|
||||
>
|
||||
<RiHammerLine className="h-4 w-4 text-text-tertiary" />
|
||||
<div
|
||||
title={t('workflow.common.workflowAsTool') || ''}
|
||||
title={t('common.workflowAsTool', { ns: 'workflow' }) || ''}
|
||||
className="system-sm-medium shrink grow basis-0 truncate text-text-tertiary"
|
||||
>
|
||||
{t('workflow.common.workflowAsTool')}
|
||||
{t('common.workflowAsTool', { ns: 'workflow' })}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@ -253,7 +253,7 @@ const WorkflowToolConfigureButton = ({
|
||||
onClick={() => setShowModal(true)}
|
||||
disabled={!isCurrentWorkspaceManager || disabled}
|
||||
>
|
||||
{t('workflow.common.configure')}
|
||||
{t('common.configure', { ns: 'workflow' })}
|
||||
{outdated && <Indicator className="ml-1" color="yellow" />}
|
||||
</Button>
|
||||
<Button
|
||||
@ -262,13 +262,13 @@ const WorkflowToolConfigureButton = ({
|
||||
onClick={() => router.push('/tools?category=workflow')}
|
||||
disabled={disabled}
|
||||
>
|
||||
{t('workflow.common.manageInTools')}
|
||||
{t('common.manageInTools', { ns: 'workflow' })}
|
||||
<RiArrowRightUpLine className="ml-1 h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
{outdated && (
|
||||
<div className="mt-1 text-xs leading-[18px] text-text-warning">
|
||||
{t('workflow.common.workflowAsToolTip')}
|
||||
{t('common.workflowAsToolTip', { ns: 'workflow' })}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@ -29,14 +29,14 @@ const ConfirmModal = ({ show, onConfirm, onClose }: ConfirmModalProps) => {
|
||||
<div className="h-12 w-12 rounded-xl border-[0.5px] border-divider-regular bg-background-section p-3 shadow-xl">
|
||||
<AlertTriangle className="h-6 w-6 text-[rgb(247,144,9)]" />
|
||||
</div>
|
||||
<div className="relative mt-3 text-xl font-semibold leading-[30px] text-text-primary">{t('tools.createTool.confirmTitle')}</div>
|
||||
<div className="relative mt-3 text-xl font-semibold leading-[30px] text-text-primary">{t('createTool.confirmTitle', { ns: 'tools' })}</div>
|
||||
<div className="my-1 text-sm leading-5 text-text-tertiary">
|
||||
{t('tools.createTool.confirmTip')}
|
||||
{t('createTool.confirmTip', { ns: 'tools' })}
|
||||
</div>
|
||||
<div className="flex items-center justify-end pt-6">
|
||||
<div className="flex items-center">
|
||||
<Button className="mr-2" onClick={onClose}>{t('common.operation.cancel')}</Button>
|
||||
<Button variant="warning" onClick={onConfirm}>{t('common.operation.confirm')}</Button>
|
||||
<Button className="mr-2" onClick={onClose}>{t('operation.cancel', { ns: 'common' })}</Button>
|
||||
<Button variant="warning" onClick={onConfirm}>{t('operation.confirm', { ns: 'common' })}</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
@ -55,19 +55,19 @@ const WorkflowToolAsModal: FC<Props> = ({
|
||||
const reservedOutputParameters: WorkflowToolProviderOutputParameter[] = [
|
||||
{
|
||||
name: 'text',
|
||||
description: t('workflow.nodes.tool.outputVars.text'),
|
||||
description: t('nodes.tool.outputVars.text', { ns: 'workflow' }),
|
||||
type: VarType.string,
|
||||
reserved: true,
|
||||
},
|
||||
{
|
||||
name: 'files',
|
||||
description: t('workflow.nodes.tool.outputVars.files.title'),
|
||||
description: t('nodes.tool.outputVars.files.title', { ns: 'workflow' }),
|
||||
type: VarType.arrayFile,
|
||||
reserved: true,
|
||||
},
|
||||
{
|
||||
name: 'json',
|
||||
description: t('workflow.nodes.tool.outputVars.json'),
|
||||
description: t('nodes.tool.outputVars.json', { ns: 'workflow' }),
|
||||
type: VarType.arrayObject,
|
||||
reserved: true,
|
||||
},
|
||||
@ -104,13 +104,13 @@ const WorkflowToolAsModal: FC<Props> = ({
|
||||
const onConfirm = () => {
|
||||
let errorMessage = ''
|
||||
if (!label)
|
||||
errorMessage = t('common.errorMsg.fieldRequired', { field: t('tools.createTool.name') })
|
||||
errorMessage = t('errorMsg.fieldRequired', { ns: 'common', field: t('createTool.name', { ns: 'tools' }) })
|
||||
|
||||
if (!name)
|
||||
errorMessage = t('common.errorMsg.fieldRequired', { field: t('tools.createTool.nameForToolCall') })
|
||||
errorMessage = t('errorMsg.fieldRequired', { ns: 'common', field: t('createTool.nameForToolCall', { ns: 'tools' }) })
|
||||
|
||||
if (!isNameValid(name))
|
||||
errorMessage = t('tools.createTool.nameForToolCall') + t('tools.createTool.nameForToolCallTip')
|
||||
errorMessage = t('createTool.nameForToolCall', { ns: 'tools' }) + t('createTool.nameForToolCallTip', { ns: 'tools' })
|
||||
|
||||
if (errorMessage) {
|
||||
Toast.notify({
|
||||
@ -152,7 +152,7 @@ const WorkflowToolAsModal: FC<Props> = ({
|
||||
<Drawer
|
||||
isShow
|
||||
onHide={onHide}
|
||||
title={t('workflow.common.workflowAsTool')!}
|
||||
title={t('common.workflowAsTool', { ns: 'workflow' })!}
|
||||
panelClassName="mt-2 !w-[640px]"
|
||||
maxWidthClassName="!max-w-[640px]"
|
||||
height="calc(100vh - 16px)"
|
||||
@ -163,7 +163,7 @@ const WorkflowToolAsModal: FC<Props> = ({
|
||||
{/* name & icon */}
|
||||
<div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">
|
||||
{t('tools.createTool.name')}
|
||||
{t('createTool.name', { ns: 'tools' })}
|
||||
{' '}
|
||||
<span className="ml-1 text-red-500">*</span>
|
||||
</div>
|
||||
@ -171,7 +171,7 @@ const WorkflowToolAsModal: FC<Props> = ({
|
||||
<AppIcon size="large" onClick={() => { setShowEmojiPicker(true) }} className="cursor-pointer" iconType="emoji" icon={emoji.content} background={emoji.background} />
|
||||
<Input
|
||||
className="h-10 grow"
|
||||
placeholder={t('tools.createTool.toolNamePlaceHolder')!}
|
||||
placeholder={t('createTool.toolNamePlaceHolder', { ns: 'tools' })!}
|
||||
value={label}
|
||||
onChange={e => setLabel(e.target.value)}
|
||||
/>
|
||||
@ -180,46 +180,46 @@ const WorkflowToolAsModal: FC<Props> = ({
|
||||
{/* name for tool call */}
|
||||
<div>
|
||||
<div className="system-sm-medium flex items-center py-2 text-text-primary">
|
||||
{t('tools.createTool.nameForToolCall')}
|
||||
{t('createTool.nameForToolCall', { ns: 'tools' })}
|
||||
{' '}
|
||||
<span className="ml-1 text-red-500">*</span>
|
||||
<Tooltip
|
||||
popupContent={(
|
||||
<div className="w-[180px]">
|
||||
{t('tools.createTool.nameForToolCallPlaceHolder')}
|
||||
{t('createTool.nameForToolCallPlaceHolder', { ns: 'tools' })}
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<Input
|
||||
className="h-10"
|
||||
placeholder={t('tools.createTool.nameForToolCallPlaceHolder')!}
|
||||
placeholder={t('createTool.nameForToolCallPlaceHolder', { ns: 'tools' })!}
|
||||
value={name}
|
||||
onChange={e => setName(e.target.value)}
|
||||
/>
|
||||
{!isNameValid(name) && (
|
||||
<div className="text-xs leading-[18px] text-red-500">{t('tools.createTool.nameForToolCallTip')}</div>
|
||||
<div className="text-xs leading-[18px] text-red-500">{t('createTool.nameForToolCallTip', { ns: 'tools' })}</div>
|
||||
)}
|
||||
</div>
|
||||
{/* description */}
|
||||
<div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('tools.createTool.description')}</div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('createTool.description', { ns: 'tools' })}</div>
|
||||
<Textarea
|
||||
placeholder={t('tools.createTool.descriptionPlaceholder') || ''}
|
||||
placeholder={t('createTool.descriptionPlaceholder', { ns: 'tools' }) || ''}
|
||||
value={description}
|
||||
onChange={e => setDescription(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
{/* Tool Input */}
|
||||
<div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('tools.createTool.toolInput.title')}</div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('createTool.toolInput.title', { ns: 'tools' })}</div>
|
||||
<div className="w-full overflow-x-auto rounded-lg border border-divider-regular">
|
||||
<table className="w-full text-xs font-normal leading-[18px] text-text-secondary">
|
||||
<thead className="uppercase text-text-tertiary">
|
||||
<tr className="border-b border-divider-regular">
|
||||
<th className="w-[156px] p-2 pl-3 font-medium">{t('tools.createTool.toolInput.name')}</th>
|
||||
<th className="w-[102px] p-2 pl-3 font-medium">{t('tools.createTool.toolInput.method')}</th>
|
||||
<th className="p-2 pl-3 font-medium">{t('tools.createTool.toolInput.description')}</th>
|
||||
<th className="w-[156px] p-2 pl-3 font-medium">{t('createTool.toolInput.name', { ns: 'tools' })}</th>
|
||||
<th className="w-[102px] p-2 pl-3 font-medium">{t('createTool.toolInput.method', { ns: 'tools' })}</th>
|
||||
<th className="p-2 pl-3 font-medium">{t('createTool.toolInput.description', { ns: 'tools' })}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -229,7 +229,7 @@ const WorkflowToolAsModal: FC<Props> = ({
|
||||
<div className="text-[13px] leading-[18px]">
|
||||
<div title={item.name} className="flex">
|
||||
<span className="truncate font-medium text-text-primary">{item.name}</span>
|
||||
<span className="shrink-0 pl-1 text-xs leading-[18px] text-[#ec4a0a]">{item.required ? t('tools.createTool.toolInput.required') : ''}</span>
|
||||
<span className="shrink-0 pl-1 text-xs leading-[18px] text-[#ec4a0a]">{item.required ? t('createTool.toolInput.required', { ns: 'tools' }) : ''}</span>
|
||||
</div>
|
||||
<div className="text-text-tertiary">{item.type}</div>
|
||||
</div>
|
||||
@ -241,7 +241,7 @@ const WorkflowToolAsModal: FC<Props> = ({
|
||||
)}
|
||||
>
|
||||
<div className={cn('grow truncate text-[13px] leading-[18px] text-text-secondary')}>
|
||||
{t('tools.createTool.toolInput.methodParameter')}
|
||||
{t('createTool.toolInput.methodParameter', { ns: 'tools' })}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@ -253,7 +253,7 @@ const WorkflowToolAsModal: FC<Props> = ({
|
||||
<input
|
||||
type="text"
|
||||
className="w-full appearance-none bg-transparent text-[13px] font-normal leading-[18px] text-text-secondary caret-primary-600 outline-none placeholder:text-text-quaternary"
|
||||
placeholder={t('tools.createTool.toolInput.descriptionPlaceholder')!}
|
||||
placeholder={t('createTool.toolInput.descriptionPlaceholder', { ns: 'tools' })!}
|
||||
value={item.description}
|
||||
onChange={e => handleParameterChange('description', e.target.value, index)}
|
||||
/>
|
||||
@ -266,13 +266,13 @@ const WorkflowToolAsModal: FC<Props> = ({
|
||||
</div>
|
||||
{/* Tool Output */}
|
||||
<div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('tools.createTool.toolOutput.title')}</div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('createTool.toolOutput.title', { ns: 'tools' })}</div>
|
||||
<div className="w-full overflow-x-auto rounded-lg border border-divider-regular">
|
||||
<table className="w-full text-xs font-normal leading-[18px] text-text-secondary">
|
||||
<thead className="uppercase text-text-tertiary">
|
||||
<tr className="border-b border-divider-regular">
|
||||
<th className="w-[156px] p-2 pl-3 font-medium">{t('tools.createTool.name')}</th>
|
||||
<th className="p-2 pl-3 font-medium">{t('tools.createTool.toolOutput.description')}</th>
|
||||
<th className="w-[156px] p-2 pl-3 font-medium">{t('createTool.name', { ns: 'tools' })}</th>
|
||||
<th className="p-2 pl-3 font-medium">{t('createTool.toolOutput.description', { ns: 'tools' })}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -282,14 +282,14 @@ const WorkflowToolAsModal: FC<Props> = ({
|
||||
<div className="text-[13px] leading-[18px]">
|
||||
<div title={item.name} className="flex items-center">
|
||||
<span className="truncate font-medium text-text-primary">{item.name}</span>
|
||||
<span className="shrink-0 pl-1 text-xs leading-[18px] text-[#ec4a0a]">{item.reserved ? t('tools.createTool.toolOutput.reserved') : ''}</span>
|
||||
<span className="shrink-0 pl-1 text-xs leading-[18px] text-[#ec4a0a]">{item.reserved ? t('createTool.toolOutput.reserved', { ns: 'tools' }) : ''}</span>
|
||||
{
|
||||
!item.reserved && isOutputParameterReserved(item.name)
|
||||
? (
|
||||
<Tooltip
|
||||
popupContent={(
|
||||
<div className="w-[180px]">
|
||||
{t('tools.createTool.toolOutput.reservedParameterDuplicateTip')}
|
||||
{t('createTool.toolOutput.reservedParameterDuplicateTip', { ns: 'tools' })}
|
||||
</div>
|
||||
)}
|
||||
>
|
||||
@ -313,26 +313,26 @@ const WorkflowToolAsModal: FC<Props> = ({
|
||||
</div>
|
||||
{/* Tags */}
|
||||
<div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('tools.createTool.toolInput.label')}</div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('createTool.toolInput.label', { ns: 'tools' })}</div>
|
||||
<LabelSelector value={labels} onChange={handleLabelSelect} />
|
||||
</div>
|
||||
{/* Privacy Policy */}
|
||||
<div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('tools.createTool.privacyPolicy')}</div>
|
||||
<div className="system-sm-medium py-2 text-text-primary">{t('createTool.privacyPolicy', { ns: 'tools' })}</div>
|
||||
<Input
|
||||
className="h-10"
|
||||
value={privacyPolicy}
|
||||
onChange={e => setPrivacyPolicy(e.target.value)}
|
||||
placeholder={t('tools.createTool.privacyPolicyPlaceholder') || ''}
|
||||
placeholder={t('createTool.privacyPolicyPlaceholder', { ns: 'tools' }) || ''}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className={cn((!isAdd && onRemove) ? 'justify-between' : 'justify-end', 'mt-2 flex shrink-0 rounded-b-[10px] border-t border-divider-regular bg-background-section-burn px-6 py-4')}>
|
||||
{!isAdd && onRemove && (
|
||||
<Button variant="warning" onClick={onRemove}>{t('common.operation.delete')}</Button>
|
||||
<Button variant="warning" onClick={onRemove}>{t('operation.delete', { ns: 'common' })}</Button>
|
||||
)}
|
||||
<div className="flex space-x-2 ">
|
||||
<Button onClick={onHide}>{t('common.operation.cancel')}</Button>
|
||||
<Button onClick={onHide}>{t('operation.cancel', { ns: 'common' })}</Button>
|
||||
<Button
|
||||
variant="primary"
|
||||
onClick={() => {
|
||||
@ -342,7 +342,7 @@ const WorkflowToolAsModal: FC<Props> = ({
|
||||
setShowModal(true)
|
||||
}}
|
||||
>
|
||||
{t('common.operation.save')}
|
||||
{t('operation.save', { ns: 'common' })}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -39,7 +39,7 @@ const MethodSelector: FC<MethodSelectorProps> = ({
|
||||
)}
|
||||
>
|
||||
<div className={cn('grow truncate text-[13px] leading-[18px] text-text-secondary')}>
|
||||
{value === 'llm' ? t('tools.createTool.toolInput.methodParameter') : t('tools.createTool.toolInput.methodSetting')}
|
||||
{value === 'llm' ? t('createTool.toolInput.methodParameter', { ns: 'tools' }) : t('createTool.toolInput.methodSetting', { ns: 'tools' })}
|
||||
</div>
|
||||
<div className="ml-1 shrink-0 text-text-secondary opacity-60">
|
||||
<RiArrowDownSLine className="h-4 w-4" />
|
||||
@ -54,18 +54,18 @@ const MethodSelector: FC<MethodSelectorProps> = ({
|
||||
<div className="h-4 w-4 shrink-0">
|
||||
{value === 'llm' && <Check className="h-4 w-4 shrink-0 text-text-accent" />}
|
||||
</div>
|
||||
<div className="text-[13px] font-medium leading-[18px] text-text-secondary">{t('tools.createTool.toolInput.methodParameter')}</div>
|
||||
<div className="text-[13px] font-medium leading-[18px] text-text-secondary">{t('createTool.toolInput.methodParameter', { ns: 'tools' })}</div>
|
||||
</div>
|
||||
<div className="pl-5 text-[13px] leading-[18px] text-text-tertiary">{t('tools.createTool.toolInput.methodParameterTip')}</div>
|
||||
<div className="pl-5 text-[13px] leading-[18px] text-text-tertiary">{t('createTool.toolInput.methodParameterTip', { ns: 'tools' })}</div>
|
||||
</div>
|
||||
<div className="cursor-pointer rounded-lg py-2.5 pl-3 pr-2 hover:bg-components-panel-on-panel-item-bg-hover" onClick={() => onChange('form')}>
|
||||
<div className="item-center flex gap-1">
|
||||
<div className="h-4 w-4 shrink-0">
|
||||
{value === 'form' && <Check className="h-4 w-4 shrink-0 text-text-accent" />}
|
||||
</div>
|
||||
<div className="text-[13px] font-medium leading-[18px] text-text-secondary">{t('tools.createTool.toolInput.methodSetting')}</div>
|
||||
<div className="text-[13px] font-medium leading-[18px] text-text-secondary">{t('createTool.toolInput.methodSetting', { ns: 'tools' })}</div>
|
||||
</div>
|
||||
<div className="pl-5 text-[13px] leading-[18px] text-text-tertiary">{t('tools.createTool.toolInput.methodSettingTip')}</div>
|
||||
<div className="pl-5 text-[13px] leading-[18px] text-text-tertiary">{t('createTool.toolInput.methodSettingTip', { ns: 'tools' })}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user