mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-30 12:39:27 +08:00
fix: i18n for data source internal configuration fields (#17217)
This commit is contained in:
@@ -5,9 +5,9 @@ import { useEffect, useState } from 'react';
|
||||
import { FieldValues } from 'react-hook-form';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
DataSourceFormBaseFields,
|
||||
DataSourceFormDefaultValues,
|
||||
getCommonExtraDefaultValues,
|
||||
getDataSourceFormBaseFields,
|
||||
getDataSourceFieldsWithExtras,
|
||||
mergeDataSourceFormValues,
|
||||
} from './constant';
|
||||
@@ -26,11 +26,11 @@ const AddDataSourceModal = ({
|
||||
useEffect(() => {
|
||||
if (sourceData) {
|
||||
setFields([
|
||||
...DataSourceFormBaseFields,
|
||||
...getDataSourceFieldsWithExtras(sourceData.id as any),
|
||||
...getDataSourceFormBaseFields(t),
|
||||
...getDataSourceFieldsWithExtras(t, sourceData.id as any),
|
||||
] as FormFieldConfig[]);
|
||||
}
|
||||
}, [sourceData]);
|
||||
}, [sourceData, t]);
|
||||
|
||||
const handleOk = async (values?: FieldValues) => {
|
||||
await onOk?.(values);
|
||||
|
||||
@@ -3,42 +3,47 @@ import { TFunction } from 'i18next';
|
||||
|
||||
export const bitbucketConstant = (t: TFunction) => [
|
||||
{
|
||||
label: 'Bitbucket Account Email',
|
||||
label: t('setting.dataSourceFieldBitbucketAccountEmail'),
|
||||
name: 'config.credentials.bitbucket_account_email',
|
||||
type: FormFieldType.Email,
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: 'Bitbucket API Token',
|
||||
label: t('setting.dataSourceFieldBitbucketApiToken'),
|
||||
name: 'config.credentials.bitbucket_api_token',
|
||||
type: FormFieldType.Password,
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: 'Workspace',
|
||||
label: t('setting.dataSourceFieldWorkspace'),
|
||||
name: 'config.workspace',
|
||||
type: FormFieldType.Text,
|
||||
required: true,
|
||||
tooltip: t('setting.bitbucketTopWorkspaceTip'),
|
||||
},
|
||||
{
|
||||
label: 'Index Mode',
|
||||
label: t('setting.dataSourceFieldIndexMode'),
|
||||
name: 'config.index_mode',
|
||||
type: FormFieldType.Segmented,
|
||||
options: [
|
||||
{ label: 'Repositories', value: 'repositories' },
|
||||
{ label: 'Project(s)', value: 'projects' },
|
||||
{ label: 'Workspace', value: 'workspace' },
|
||||
{
|
||||
label: t('setting.dataSourceOptionRepositories'),
|
||||
value: 'repositories',
|
||||
},
|
||||
{ label: t('setting.dataSourceOptionProjects'), value: 'projects' },
|
||||
{ label: t('setting.dataSourceOptionWorkspace'), value: 'workspace' },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Repository Slugs',
|
||||
label: t('setting.dataSourceFieldRepositorySlugs'),
|
||||
name: 'config.repository_slugs',
|
||||
type: FormFieldType.Text,
|
||||
customValidate: (val: string, formValues: any) => {
|
||||
const index_mode = formValues?.config?.index_mode;
|
||||
if (!val && index_mode === 'repositories') {
|
||||
return 'Repository Slugs is required';
|
||||
return t('setting.dataSourceValidationFieldRequired', {
|
||||
label: t('setting.dataSourceFieldRepositorySlugs'),
|
||||
});
|
||||
}
|
||||
return true;
|
||||
},
|
||||
@@ -49,13 +54,15 @@ export const bitbucketConstant = (t: TFunction) => [
|
||||
tooltip: t('setting.bitbucketRepositorySlugsTip'),
|
||||
},
|
||||
{
|
||||
label: 'Projects',
|
||||
label: t('setting.dataSourceFieldProjects'),
|
||||
name: 'config.projects',
|
||||
type: FormFieldType.Text,
|
||||
customValidate: (val: string, formValues: any) => {
|
||||
const index_mode = formValues?.config?.index_mode;
|
||||
if (!val && index_mode === 'projects') {
|
||||
return 'Projects is required';
|
||||
return t('setting.dataSourceValidationFieldRequired', {
|
||||
label: t('setting.dataSourceFieldProjects'),
|
||||
});
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
@@ -3,50 +3,52 @@ import { TFunction } from 'i18next';
|
||||
|
||||
export const confluenceConstant = (t: TFunction) => [
|
||||
{
|
||||
label: 'Confluence Username',
|
||||
label: t('setting.dataSourceFieldConfluenceUsername'),
|
||||
name: 'config.credentials.confluence_username',
|
||||
type: FormFieldType.Text,
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: 'Confluence Access Token',
|
||||
label: t('setting.dataSourceFieldConfluenceAccessToken'),
|
||||
name: 'config.credentials.confluence_access_token',
|
||||
type: FormFieldType.Password,
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: 'Wiki Base URL',
|
||||
label: t('setting.dataSourceFieldWikiBaseUrl'),
|
||||
name: 'config.wiki_base',
|
||||
type: FormFieldType.Text,
|
||||
required: false,
|
||||
tooltip: t('setting.confluenceWikiBaseUrlTip'),
|
||||
},
|
||||
{
|
||||
label: 'Is Cloud',
|
||||
label: t('setting.dataSourceFieldIsCloud'),
|
||||
name: 'config.is_cloud',
|
||||
type: FormFieldType.Checkbox,
|
||||
required: false,
|
||||
tooltip: t('setting.confluenceIsCloudTip'),
|
||||
},
|
||||
{
|
||||
label: 'Index Mode',
|
||||
label: t('setting.dataSourceFieldIndexMode'),
|
||||
name: 'config.index_mode',
|
||||
type: FormFieldType.Segmented,
|
||||
options: [
|
||||
{ label: 'Everything', value: 'everything' },
|
||||
{ label: 'Space', value: 'space' },
|
||||
{ label: 'Page', value: 'page' },
|
||||
{ label: t('setting.dataSourceOptionEverything'), value: 'everything' },
|
||||
{ label: t('setting.dataSourceOptionSpace'), value: 'space' },
|
||||
{ label: t('setting.dataSourceOptionPage'), value: 'page' },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'config.page_id',
|
||||
label: 'Page ID',
|
||||
label: t('setting.dataSourceFieldPageId'),
|
||||
type: FormFieldType.Text,
|
||||
customValidate: (val: string, formValues: any) => {
|
||||
const index_mode = formValues?.config?.index_mode;
|
||||
console.log('index_mode', index_mode, val);
|
||||
if (!val && index_mode === 'page') {
|
||||
return 'Page ID is required';
|
||||
return t('setting.dataSourceValidationFieldRequired', {
|
||||
label: t('setting.dataSourceFieldPageId'),
|
||||
});
|
||||
}
|
||||
return true;
|
||||
},
|
||||
@@ -57,12 +59,14 @@ export const confluenceConstant = (t: TFunction) => [
|
||||
},
|
||||
{
|
||||
name: 'config.space',
|
||||
label: 'Space Key',
|
||||
label: t('setting.dataSourceFieldSpaceKey'),
|
||||
type: FormFieldType.Text,
|
||||
customValidate: (val: string, formValues: any) => {
|
||||
const index_mode = formValues?.config?.index_mode;
|
||||
if (!val && index_mode === 'space') {
|
||||
return 'Space Key is required';
|
||||
return t('setting.dataSourceValidationFieldRequired', {
|
||||
label: t('setting.dataSourceFieldSpaceKey'),
|
||||
});
|
||||
}
|
||||
return true;
|
||||
},
|
||||
@@ -73,7 +77,7 @@ export const confluenceConstant = (t: TFunction) => [
|
||||
},
|
||||
{
|
||||
name: 'config.index_recursively',
|
||||
label: 'Index Recursively',
|
||||
label: t('setting.dataSourceFieldIndexRecursively'),
|
||||
type: FormFieldType.Checkbox,
|
||||
shouldRender: (formValues: any) => {
|
||||
const index_mode = formValues?.config?.index_mode;
|
||||
@@ -90,28 +94,26 @@ export const confluenceConstant = (t: TFunction) => [
|
||||
},
|
||||
render: () => (
|
||||
<div className="text-sm text-text-secondary bg-bg-card border border-border-button rounded-md px-3 py-2">
|
||||
{
|
||||
'This choice will index all pages the provided credentials have access to.'
|
||||
}
|
||||
{t('setting.dataSourceConfluenceEverythingTip')}
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
label: 'Space Key',
|
||||
label: t('setting.dataSourceFieldSpaceKey'),
|
||||
name: 'config.space',
|
||||
type: FormFieldType.Text,
|
||||
required: false,
|
||||
hidden: true,
|
||||
},
|
||||
{
|
||||
label: 'Page ID',
|
||||
label: t('setting.dataSourceFieldPageId'),
|
||||
name: 'config.page_id',
|
||||
type: FormFieldType.Text,
|
||||
required: false,
|
||||
hidden: true,
|
||||
},
|
||||
{
|
||||
label: 'Index Recursively',
|
||||
label: t('setting.dataSourceFieldIndexRecursively'),
|
||||
name: 'config.index_recursively',
|
||||
type: FormFieldType.Checkbox,
|
||||
required: false,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@ import { TFunction } from 'i18next';
|
||||
|
||||
export const jiraConstant = (t: TFunction) => [
|
||||
{
|
||||
label: 'Jira User Email',
|
||||
label: t('setting.dataSourceFieldJiraUserEmail'),
|
||||
name: 'config.credentials.jira_user_email',
|
||||
type: FormFieldType.Text,
|
||||
required: true,
|
||||
@@ -12,13 +12,18 @@ export const jiraConstant = (t: TFunction) => [
|
||||
shouldRender: (formValues: any) => formValues?.config?.is_cloud !== false,
|
||||
customValidate: (val: string, formValues: any) => {
|
||||
if (formValues?.config?.is_cloud !== false) {
|
||||
return Boolean(val) || 'Jira User Email is required';
|
||||
return (
|
||||
Boolean(val) ||
|
||||
t('setting.dataSourceValidationFieldRequired', {
|
||||
label: t('setting.dataSourceFieldJiraUserEmail'),
|
||||
})
|
||||
);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Jira Username',
|
||||
label: t('setting.dataSourceFieldJiraUsername'),
|
||||
name: 'config.credentials.jira_username',
|
||||
type: FormFieldType.Text,
|
||||
required: true,
|
||||
@@ -26,13 +31,18 @@ export const jiraConstant = (t: TFunction) => [
|
||||
shouldRender: (formValues: any) => formValues?.config?.is_cloud === false,
|
||||
customValidate: (val: string, formValues: any) => {
|
||||
if (formValues?.config?.is_cloud === false) {
|
||||
return Boolean(val) || 'Jira Username is required';
|
||||
return (
|
||||
Boolean(val) ||
|
||||
t('setting.dataSourceValidationFieldRequired', {
|
||||
label: t('setting.dataSourceFieldJiraUsername'),
|
||||
})
|
||||
);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Jira Base URL',
|
||||
label: t('setting.dataSourceFieldJiraBaseUrl'),
|
||||
name: 'config.base_url',
|
||||
type: FormFieldType.Text,
|
||||
required: true,
|
||||
@@ -40,7 +50,7 @@ export const jiraConstant = (t: TFunction) => [
|
||||
tooltip: t('setting.jiraBaseUrlTip'),
|
||||
},
|
||||
{
|
||||
label: 'Project Key',
|
||||
label: t('setting.dataSourceFieldProjectKey'),
|
||||
name: 'config.project_key',
|
||||
type: FormFieldType.Text,
|
||||
required: false,
|
||||
@@ -48,7 +58,7 @@ export const jiraConstant = (t: TFunction) => [
|
||||
tooltip: t('setting.jiraProjectKeyTip'),
|
||||
},
|
||||
{
|
||||
label: 'Custom JQL',
|
||||
label: t('setting.dataSourceFieldCustomJql'),
|
||||
name: 'config.jql_query',
|
||||
type: FormFieldType.Textarea,
|
||||
required: false,
|
||||
@@ -56,14 +66,14 @@ export const jiraConstant = (t: TFunction) => [
|
||||
tooltip: t('setting.jiraJqlTip'),
|
||||
},
|
||||
{
|
||||
label: 'Batch Size',
|
||||
label: t('setting.dataSourceFieldBatchSize'),
|
||||
name: 'config.batch_size',
|
||||
type: FormFieldType.Number,
|
||||
required: false,
|
||||
tooltip: t('setting.jiraBatchSizeTip'),
|
||||
},
|
||||
{
|
||||
label: 'Attachment Size Limit (bytes)',
|
||||
label: t('setting.dataSourceFieldAttachmentSizeLimit'),
|
||||
name: 'config.attachment_size_limit',
|
||||
type: FormFieldType.Number,
|
||||
required: false,
|
||||
@@ -71,21 +81,21 @@ export const jiraConstant = (t: TFunction) => [
|
||||
tooltip: t('setting.jiraAttachmentSizeTip'),
|
||||
},
|
||||
{
|
||||
label: 'Labels to Skip',
|
||||
label: t('setting.dataSourceFieldLabelsToSkip'),
|
||||
name: 'config.labels_to_skip',
|
||||
type: FormFieldType.Tag,
|
||||
required: false,
|
||||
tooltip: t('setting.jiraLabelsTip'),
|
||||
},
|
||||
{
|
||||
label: 'Comment Email Blacklist',
|
||||
label: t('setting.dataSourceFieldCommentEmailBlacklist'),
|
||||
name: 'config.comment_email_blacklist',
|
||||
type: FormFieldType.Tag,
|
||||
required: false,
|
||||
tooltip: t('setting.jiraBlacklistTip'),
|
||||
},
|
||||
{
|
||||
label: 'Include Comments',
|
||||
label: t('setting.dataSourceFieldIncludeComments'),
|
||||
name: 'config.include_comments',
|
||||
type: FormFieldType.Checkbox,
|
||||
required: false,
|
||||
@@ -93,7 +103,7 @@ export const jiraConstant = (t: TFunction) => [
|
||||
tooltip: t('setting.jiraCommentsTip'),
|
||||
},
|
||||
{
|
||||
label: 'Include Attachments',
|
||||
label: t('setting.dataSourceFieldIncludeAttachments'),
|
||||
name: 'config.include_attachments',
|
||||
type: FormFieldType.Checkbox,
|
||||
required: false,
|
||||
@@ -101,17 +111,17 @@ export const jiraConstant = (t: TFunction) => [
|
||||
tooltip: t('setting.jiraAttachmentsTip'),
|
||||
},
|
||||
{
|
||||
label: 'Mode',
|
||||
label: t('setting.dataSourceFieldMode'),
|
||||
name: 'config.is_cloud',
|
||||
type: FormFieldType.Segmented,
|
||||
options: [
|
||||
{ label: 'Cloud', value: true },
|
||||
{ label: 'Server', value: false },
|
||||
{ label: t('setting.dataSourceOptionCloud'), value: true },
|
||||
{ label: t('setting.dataSourceOptionServer'), value: false },
|
||||
],
|
||||
defaultValue: true,
|
||||
},
|
||||
{
|
||||
label: 'Jira API Token',
|
||||
label: t('setting.dataSourceFieldJiraApiToken'),
|
||||
name: 'config.credentials.jira_api_token',
|
||||
type: FormFieldType.Password,
|
||||
required: false,
|
||||
@@ -119,13 +129,18 @@ export const jiraConstant = (t: TFunction) => [
|
||||
shouldRender: (formValues: any) => formValues?.config?.is_cloud !== false,
|
||||
customValidate: (val: string, formValues: any) => {
|
||||
if (formValues?.config?.is_cloud !== false) {
|
||||
return Boolean(val) || 'Jira API Token is required';
|
||||
return (
|
||||
Boolean(val) ||
|
||||
t('setting.dataSourceValidationFieldRequired', {
|
||||
label: t('setting.dataSourceFieldJiraApiToken'),
|
||||
})
|
||||
);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Jira Password',
|
||||
label: t('setting.dataSourceFieldJiraPassword'),
|
||||
name: 'config.credentials.jira_password',
|
||||
type: FormFieldType.Password,
|
||||
required: false,
|
||||
@@ -133,13 +148,18 @@ export const jiraConstant = (t: TFunction) => [
|
||||
shouldRender: (formValues: any) => formValues?.config?.is_cloud === false,
|
||||
customValidate: (val: string, formValues: any) => {
|
||||
if (formValues?.config?.is_cloud === false) {
|
||||
return Boolean(val) || 'Jira Password is required';
|
||||
return (
|
||||
Boolean(val) ||
|
||||
t('setting.dataSourceValidationFieldRequired', {
|
||||
label: t('setting.dataSourceFieldJiraPassword'),
|
||||
})
|
||||
);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Use Scoped Token',
|
||||
label: t('setting.dataSourceFieldUseScopedToken'),
|
||||
name: 'config.scoped_token',
|
||||
type: FormFieldType.Checkbox,
|
||||
required: false,
|
||||
|
||||
@@ -8,13 +8,13 @@ const awsRegionOptions = BedrockRegionList.map((r) => ({
|
||||
}));
|
||||
export const S3Constant = (t: TFunction) => [
|
||||
{
|
||||
label: 'Bucket Name',
|
||||
label: t('setting.dataSourceFieldBucketName'),
|
||||
name: 'config.bucket_name',
|
||||
type: FormFieldType.Text,
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: 'Region',
|
||||
label: t('setting.dataSourceFieldRegion'),
|
||||
name: 'config.credentials.region',
|
||||
type: FormFieldType.Select,
|
||||
required: false,
|
||||
@@ -27,13 +27,13 @@ export const S3Constant = (t: TFunction) => [
|
||||
credentials.aws_access_key_id || credentials.aws_secret_access_key,
|
||||
);
|
||||
if (bucketType === 's3' && hasAccessKey) {
|
||||
return Boolean(val) || 'Region is required when using access key';
|
||||
return Boolean(val) || t('setting.dataSourceS3RegionRequired');
|
||||
}
|
||||
return true;
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Prefix',
|
||||
label: t('setting.dataSourceFieldPrefix'),
|
||||
name: 'config.prefix',
|
||||
type: FormFieldType.Text,
|
||||
required: false,
|
||||
@@ -41,22 +41,25 @@ export const S3Constant = (t: TFunction) => [
|
||||
},
|
||||
|
||||
{
|
||||
label: 'Mode',
|
||||
label: t('setting.dataSourceFieldMode'),
|
||||
name: 'config.bucket_type',
|
||||
type: FormFieldType.Segmented,
|
||||
options: [
|
||||
{ label: 'S3', value: 's3' },
|
||||
{ label: 'S3 Compatible', value: 's3_compatible' },
|
||||
{
|
||||
label: t('setting.dataSourceOptionS3Compatible'),
|
||||
value: 's3_compatible',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Authentication',
|
||||
label: t('setting.dataSourceFieldAuthentication'),
|
||||
name: 'config.credentials.authentication_method',
|
||||
type: FormFieldType.Segmented,
|
||||
options: [
|
||||
{ label: 'Access Key', value: 'access_key' },
|
||||
{ label: 'IAM Role', value: 'iam_role' },
|
||||
{ label: 'Assume Role', value: 'assume_role' },
|
||||
{ label: t('setting.dataSourceOptionAccessKey'), value: 'access_key' },
|
||||
{ label: t('setting.dataSourceOptionIamRole'), value: 'iam_role' },
|
||||
{ label: t('setting.dataSourceOptionAssumeRole'), value: 'assume_role' },
|
||||
],
|
||||
shouldRender: (formValues: any) => {
|
||||
const bucketType = formValues?.config?.bucket_type;
|
||||
@@ -65,7 +68,7 @@ export const S3Constant = (t: TFunction) => [
|
||||
},
|
||||
{
|
||||
name: 'config.credentials.aws_access_key_id',
|
||||
label: 'AWS Access Key ID',
|
||||
label: t('setting.dataSourceFieldAwsAccessKeyId'),
|
||||
type: FormFieldType.Text,
|
||||
customValidate: (val: string, formValues: any) => {
|
||||
const authMode = formValues?.config?.credentials?.authentication_method;
|
||||
@@ -75,7 +78,9 @@ export const S3Constant = (t: TFunction) => [
|
||||
!val &&
|
||||
(authMode === 'access_key' || bucketType === 's3_compatible')
|
||||
) {
|
||||
return 'AWS Access Key ID is required';
|
||||
return t('setting.dataSourceValidationFieldRequired', {
|
||||
label: t('setting.dataSourceFieldAwsAccessKeyId'),
|
||||
});
|
||||
}
|
||||
return true;
|
||||
},
|
||||
@@ -87,13 +92,18 @@ export const S3Constant = (t: TFunction) => [
|
||||
},
|
||||
{
|
||||
name: 'config.credentials.aws_secret_access_key',
|
||||
label: 'AWS Secret Access Key',
|
||||
label: t('setting.dataSourceFieldAwsSecretAccessKey'),
|
||||
type: FormFieldType.Password,
|
||||
customValidate: (val: string, formValues: any) => {
|
||||
const authMode = formValues?.config?.credentials?.authentication_method;
|
||||
const bucketType = formValues?.config?.bucket_type;
|
||||
if (authMode === 'access_key' || bucketType === 's3_compatible') {
|
||||
return Boolean(val) || '"AWS Secret Access Key" is required';
|
||||
return (
|
||||
Boolean(val) ||
|
||||
t('setting.dataSourceValidationFieldRequired', {
|
||||
label: t('setting.dataSourceFieldAwsSecretAccessKey'),
|
||||
})
|
||||
);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
@@ -105,15 +115,20 @@ export const S3Constant = (t: TFunction) => [
|
||||
},
|
||||
{
|
||||
name: 'config.credentials.aws_role_arn',
|
||||
label: 'Role ARN',
|
||||
tooltip: 'The role will be assumed by the runtime environment.',
|
||||
label: t('setting.dataSourceFieldRoleArn'),
|
||||
tooltip: t('setting.dataSourceS3RoleArnTip'),
|
||||
type: FormFieldType.Text,
|
||||
placeholder: 'arn:aws:iam::123456789012:role/YourRole',
|
||||
customValidate: (val: string, formValues: any) => {
|
||||
const authMode = formValues?.config?.credentials?.authentication_method;
|
||||
const bucketType = formValues?.config?.bucket_type;
|
||||
if (authMode === 'iam_role' || bucketType === 's3') {
|
||||
return Boolean(val) || '"AWS Secret Access Key" is required';
|
||||
return (
|
||||
Boolean(val) ||
|
||||
t('setting.dataSourceValidationFieldRequired', {
|
||||
label: t('setting.dataSourceFieldAwsSecretAccessKey'),
|
||||
})
|
||||
);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
@@ -134,20 +149,23 @@ export const S3Constant = (t: TFunction) => [
|
||||
},
|
||||
render: () => (
|
||||
<div className="text-sm text-text-secondary bg-bg-card border border-border-button rounded-md px-3 py-2">
|
||||
{'No credentials required. Uses the default environment role.'}
|
||||
{t('setting.dataSourceS3AssumeRoleTip')}
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: 'config.credentials.addressing_style',
|
||||
label: 'Addressing Style',
|
||||
label: t('setting.dataSourceFieldAddressingStyle'),
|
||||
tooltip: t('setting.S3CompatibleAddressingStyleTip'),
|
||||
required: false,
|
||||
type: FormFieldType.Select,
|
||||
defaultValue: 'virtual',
|
||||
options: [
|
||||
{ label: 'Virtual Hosted Style', value: 'virtual' },
|
||||
{ label: 'Path Style', value: 'path' },
|
||||
{
|
||||
label: t('setting.dataSourceOptionVirtualHostedStyle'),
|
||||
value: 'virtual',
|
||||
},
|
||||
{ label: t('setting.dataSourceOptionPathStyle'), value: 'path' },
|
||||
],
|
||||
shouldRender: (formValues: any) => {
|
||||
// const authMode = formValues?.config?.authMode;
|
||||
@@ -157,7 +175,7 @@ export const S3Constant = (t: TFunction) => [
|
||||
},
|
||||
{
|
||||
name: 'config.credentials.endpoint_url',
|
||||
label: 'Endpoint URL',
|
||||
label: t('setting.dataSourceFieldEndpointUrl'),
|
||||
tooltip: t('setting.S3CompatibleEndpointUrlTip'),
|
||||
placeholder: 'https://fsn1.your-objectstorage.com',
|
||||
required: false,
|
||||
|
||||
@@ -3,7 +3,7 @@ import { TFunction } from 'i18next';
|
||||
|
||||
export const seafileConstant = (t: TFunction) => [
|
||||
{
|
||||
label: 'SeaFile Server URL',
|
||||
label: t('setting.dataSourceFieldSeafileServerUrl'),
|
||||
name: 'config.seafile_url',
|
||||
type: FormFieldType.Text,
|
||||
required: true,
|
||||
@@ -11,13 +11,16 @@ export const seafileConstant = (t: TFunction) => [
|
||||
tooltip: t('setting.seafileUrlTip'),
|
||||
},
|
||||
{
|
||||
label: 'Sync Scope',
|
||||
label: t('setting.dataSourceFieldSyncScope'),
|
||||
name: 'config.sync_scope',
|
||||
type: FormFieldType.Segmented,
|
||||
options: [
|
||||
{ label: 'Entire Account', value: 'account' },
|
||||
{ label: 'Single Library', value: 'library' },
|
||||
{ label: 'Specific Directory', value: 'directory' },
|
||||
{ label: t('setting.dataSourceOptionEntireAccount'), value: 'account' },
|
||||
{ label: t('setting.dataSourceOptionSingleLibrary'), value: 'library' },
|
||||
{
|
||||
label: t('setting.dataSourceOptionSpecificDirectory'),
|
||||
value: 'directory',
|
||||
},
|
||||
],
|
||||
tooltip: t('setting.seafileSyncScopeTip'),
|
||||
},
|
||||
@@ -37,7 +40,7 @@ export const seafileConstant = (t: TFunction) => [
|
||||
),
|
||||
},
|
||||
{
|
||||
label: 'Account API Token',
|
||||
label: t('setting.dataSourceFieldAccountApiToken'),
|
||||
name: 'config.credentials.seafile_token',
|
||||
type: FormFieldType.Password,
|
||||
required: false,
|
||||
@@ -56,7 +59,7 @@ export const seafileConstant = (t: TFunction) => [
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Include Shared Libraries',
|
||||
label: t('setting.dataSourceFieldIncludeSharedLibraries'),
|
||||
name: 'config.include_shared',
|
||||
type: FormFieldType.Checkbox,
|
||||
required: false,
|
||||
@@ -84,11 +87,15 @@ export const seafileConstant = (t: TFunction) => [
|
||||
</p>
|
||||
<ul className="list-disc list-inside space-y-0.5">
|
||||
<li>
|
||||
<span className="font-medium">Account API Token</span>
|
||||
<span className="font-medium">
|
||||
{t('setting.dataSourceFieldAccountApiToken')}
|
||||
</span>
|
||||
{' ' + t('setting.seafileTokenPanelAccountBullet')}
|
||||
</li>
|
||||
<li>
|
||||
<span className="font-medium">Library Token</span>
|
||||
<span className="font-medium">
|
||||
{t('setting.dataSourceFieldLibraryToken')}
|
||||
</span>
|
||||
{' ' + t('setting.seafileTokenPanelLibraryBullet')}
|
||||
</li>
|
||||
</ul>
|
||||
@@ -96,7 +103,7 @@ export const seafileConstant = (t: TFunction) => [
|
||||
),
|
||||
},
|
||||
{
|
||||
label: 'Account API Token',
|
||||
label: t('setting.dataSourceFieldAccountApiToken'),
|
||||
name: 'config.credentials.seafile_token',
|
||||
type: FormFieldType.Password,
|
||||
required: false,
|
||||
@@ -107,7 +114,7 @@ export const seafileConstant = (t: TFunction) => [
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Library Token',
|
||||
label: t('setting.dataSourceFieldLibraryToken'),
|
||||
name: 'config.credentials.repo_token',
|
||||
type: FormFieldType.Password,
|
||||
required: false,
|
||||
@@ -130,7 +137,7 @@ export const seafileConstant = (t: TFunction) => [
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Library ID',
|
||||
label: t('setting.dataSourceFieldLibraryId'),
|
||||
name: 'config.repo_id',
|
||||
type: FormFieldType.Text,
|
||||
required: false,
|
||||
@@ -150,7 +157,7 @@ export const seafileConstant = (t: TFunction) => [
|
||||
},
|
||||
|
||||
{
|
||||
label: 'Directory Path',
|
||||
label: t('setting.dataSourceFieldDirectoryPath'),
|
||||
name: 'config.sync_path',
|
||||
type: FormFieldType.Text,
|
||||
required: false,
|
||||
@@ -168,7 +175,7 @@ export const seafileConstant = (t: TFunction) => [
|
||||
},
|
||||
|
||||
{
|
||||
label: 'Batch Size',
|
||||
label: t('setting.dataSourceFieldBatchSize'),
|
||||
name: 'config.batch_size',
|
||||
type: FormFieldType.Number,
|
||||
required: false,
|
||||
@@ -177,35 +184,35 @@ export const seafileConstant = (t: TFunction) => [
|
||||
},
|
||||
|
||||
{
|
||||
label: 'Account API Token',
|
||||
label: t('setting.dataSourceFieldAccountApiToken'),
|
||||
name: 'config.credentials.seafile_token',
|
||||
type: FormFieldType.Password,
|
||||
required: false,
|
||||
hidden: true,
|
||||
},
|
||||
{
|
||||
label: 'Library Token',
|
||||
label: t('setting.dataSourceFieldLibraryToken'),
|
||||
name: 'config.credentials.repo_token',
|
||||
type: FormFieldType.Password,
|
||||
required: false,
|
||||
hidden: true,
|
||||
},
|
||||
{
|
||||
label: 'Library ID',
|
||||
label: t('setting.dataSourceFieldLibraryId'),
|
||||
name: 'config.repo_id',
|
||||
type: FormFieldType.Text,
|
||||
required: false,
|
||||
hidden: true,
|
||||
},
|
||||
{
|
||||
label: 'Directory Path',
|
||||
label: t('setting.dataSourceFieldDirectoryPath'),
|
||||
name: 'config.sync_path',
|
||||
type: FormFieldType.Text,
|
||||
required: false,
|
||||
hidden: true,
|
||||
},
|
||||
{
|
||||
label: 'Include Shared Libraries',
|
||||
label: t('setting.dataSourceFieldIncludeSharedLibraries'),
|
||||
name: 'config.include_shared',
|
||||
type: FormFieldType.Checkbox,
|
||||
required: false,
|
||||
|
||||
@@ -9,15 +9,15 @@ import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Separator } from '@/components/ui/separator';
|
||||
import { RunningStatus, RunningStatusOld } from '@/constants/knowledge';
|
||||
import { t } from 'i18next';
|
||||
import { isEqual } from 'lodash';
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { FieldValues } from 'react-hook-form';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
DataSourceFormBaseFields,
|
||||
DataSourceFormDefaultValues,
|
||||
DataSourceKey,
|
||||
getCommonExtraDefaultValues,
|
||||
getDataSourceFormBaseFields,
|
||||
getDataSourceFieldsWithExtras,
|
||||
mergeDataSourceFormValues,
|
||||
useDataSourceInfo,
|
||||
@@ -31,6 +31,7 @@ import {
|
||||
import { DataSourceLogsTable } from './log-table';
|
||||
|
||||
const SourceDetailPage = () => {
|
||||
const { t } = useTranslation();
|
||||
const formRef = useRef<DynamicFormRef>(null);
|
||||
|
||||
const { data: detail } = useFetchDataSourceDetail();
|
||||
@@ -54,7 +55,7 @@ const SourceDetailPage = () => {
|
||||
const customFields = useMemo(() => {
|
||||
return [
|
||||
{
|
||||
label: 'Prune Freq',
|
||||
label: t('setting.dataSourcePruneFreq'),
|
||||
name: 'prune_freq',
|
||||
type: FormFieldType.Number,
|
||||
required: false,
|
||||
@@ -74,7 +75,7 @@ const SourceDetailPage = () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Refresh Freq',
|
||||
label: t('setting.dataSourceRefreshFreq'),
|
||||
name: 'refresh_freq',
|
||||
type: FormFieldType.Number,
|
||||
required: false,
|
||||
@@ -91,7 +92,7 @@ const SourceDetailPage = () => {
|
||||
),
|
||||
},
|
||||
{
|
||||
label: 'Timeout Secs',
|
||||
label: t('setting.dataSourceTimeoutSecs'),
|
||||
name: 'timeout_secs',
|
||||
type: FormFieldType.Number,
|
||||
required: false,
|
||||
@@ -112,7 +113,7 @@ const SourceDetailPage = () => {
|
||||
),
|
||||
},
|
||||
];
|
||||
}, []);
|
||||
}, [t]);
|
||||
|
||||
const { addLoading, handleAddOk } = useAddDataSource({ isEdit: true });
|
||||
const { loading: testLoading, handleTest } = useTestDataSource();
|
||||
@@ -164,13 +165,13 @@ const SourceDetailPage = () => {
|
||||
}, [actionMode, onSubmit, updateStatus]);
|
||||
|
||||
const primaryActionLabel = useMemo(() => {
|
||||
if (actionMode === 'stop') return 'Stop';
|
||||
if (actionMode === 'resume') return 'Resume';
|
||||
return 'Save';
|
||||
}, [actionMode]);
|
||||
if (actionMode === 'stop') return t('common.stop');
|
||||
if (actionMode === 'resume') return t('common.resume');
|
||||
return t('common.save');
|
||||
}, [actionMode, t]);
|
||||
|
||||
useEffect(() => {
|
||||
const baseFields = DataSourceFormBaseFields.map((field) => {
|
||||
const baseFields = getDataSourceFormBaseFields(t).map((field) => {
|
||||
if (field.name === 'name') {
|
||||
return {
|
||||
...field,
|
||||
@@ -185,7 +186,7 @@ const SourceDetailPage = () => {
|
||||
if (detail) {
|
||||
const fields = [
|
||||
...baseFields,
|
||||
...getDataSourceFieldsWithExtras(detail.source as any),
|
||||
...getDataSourceFieldsWithExtras(t, detail.source as any),
|
||||
...customFields,
|
||||
] as FormFieldConfig[];
|
||||
|
||||
@@ -210,7 +211,7 @@ const SourceDetailPage = () => {
|
||||
setDefaultValues(defaultValueTemp);
|
||||
setIsDirty(false);
|
||||
}
|
||||
}, [detail, customFields, onSubmit]);
|
||||
}, [detail, customFields, onSubmit, t]);
|
||||
|
||||
useEffect(() => {
|
||||
const instance = formRef.current;
|
||||
|
||||
Reference in New Issue
Block a user