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:
Stephen Zhou
2025-12-29 14:52:32 +08:00
committed by GitHub
parent 09be869f58
commit 6d0e36479b
2552 changed files with 111159 additions and 142972 deletions

View File

@ -73,7 +73,7 @@ const ApiInput: FC<Props> = ({
nodesOutputVars={availableVars}
availableNodes={availableNodesWithParent}
onFocusChange={setIsFocus}
placeholder={!readonly ? t('workflow.nodes.http.apiPlaceholder')! : ''}
placeholder={!readonly ? t('nodes.http.apiPlaceholder', { ns: 'workflow' })! : ''}
placeholderClassName="!leading-[21px]"
/>
</div>

View File

@ -16,7 +16,7 @@ import { cn } from '@/utils/classnames'
import { APIType, AuthorizationType } from '../../types'
import RadioGroup from './radio-group'
const i18nPrefix = 'workflow.nodes.http.authorization'
const i18nPrefix = 'nodes.http.authorization'
type Props = {
nodeId: string
@ -116,17 +116,17 @@ const Authorization: FC<Props> = ({
}, [tempPayload, onChange, onHide])
return (
<Modal
title={t(`${i18nPrefix}.authorization`)}
title={t(`${i18nPrefix}.authorization`, { ns: 'workflow' })}
isShow={isShow}
onClose={onHide}
>
<div>
<div className="space-y-2">
<Field title={t(`${i18nPrefix}.authorizationType`)}>
<Field title={t(`${i18nPrefix}.authorizationType`, { ns: 'workflow' })}>
<RadioGroup
options={[
{ value: AuthorizationType.none, label: t(`${i18nPrefix}.no-auth`) },
{ value: AuthorizationType.apiKey, label: t(`${i18nPrefix}.api-key`) },
{ value: AuthorizationType.none, label: t(`${i18nPrefix}.no-auth`, { ns: 'workflow' }) },
{ value: AuthorizationType.apiKey, label: t(`${i18nPrefix}.api-key`, { ns: 'workflow' }) },
]}
value={tempPayload.type}
onChange={handleAuthTypeChange}
@ -135,19 +135,19 @@ const Authorization: FC<Props> = ({
{tempPayload.type === AuthorizationType.apiKey && (
<>
<Field title={t(`${i18nPrefix}.auth-type`)}>
<Field title={t(`${i18nPrefix}.auth-type`, { ns: 'workflow' })}>
<RadioGroup
options={[
{ value: APIType.basic, label: t(`${i18nPrefix}.basic`) },
{ value: APIType.bearer, label: t(`${i18nPrefix}.bearer`) },
{ value: APIType.custom, label: t(`${i18nPrefix}.custom`) },
{ value: APIType.basic, label: t(`${i18nPrefix}.basic`, { ns: 'workflow' }) },
{ value: APIType.bearer, label: t(`${i18nPrefix}.bearer`, { ns: 'workflow' }) },
{ value: APIType.custom, label: t(`${i18nPrefix}.custom`, { ns: 'workflow' }) },
]}
value={tempPayload.config?.type || APIType.basic}
onChange={handleAuthAPITypeChange}
/>
</Field>
{tempPayload.config?.type === APIType.custom && (
<Field title={t(`${i18nPrefix}.header`)} isRequired>
<Field title={t(`${i18nPrefix}.header`, { ns: 'workflow' })} isRequired>
<BaseInput
value={tempPayload.config?.header || ''}
onChange={handleAPIKeyOrHeaderChange('header')}
@ -155,7 +155,7 @@ const Authorization: FC<Props> = ({
</Field>
)}
<Field title={t(`${i18nPrefix}.api-key-title`)} isRequired>
<Field title={t(`${i18nPrefix}.api-key-title`, { ns: 'workflow' })} isRequired>
<div className="flex">
<Input
instanceId="http-api-key"
@ -174,8 +174,8 @@ const Authorization: FC<Props> = ({
)}
</div>
<div className="mt-6 flex justify-end space-x-2">
<Button onClick={onHide}>{t('common.operation.cancel')}</Button>
<Button variant="primary" onClick={handleConfirm}>{t('common.operation.save')}</Button>
<Button onClick={onHide}>{t('operation.cancel', { ns: 'common' })}</Button>
<Button variant="primary" onClick={handleConfirm}>{t('operation.save', { ns: 'common' })}</Button>
</div>
</div>
</Modal>

View File

@ -144,7 +144,7 @@ const CurlPanel: FC<Props> = ({ nodeId, isShow, onHide, handleCurlImport }) => {
return (
<Modal
title={t('workflow.nodes.http.curl.title')}
title={t('nodes.http.curl.title', { ns: 'workflow' })}
isShow={isShow}
onClose={onHide}
className="!w-[400px] !max-w-[400px] !p-4"
@ -154,14 +154,14 @@ const CurlPanel: FC<Props> = ({ nodeId, isShow, onHide, handleCurlImport }) => {
value={inputString}
className="my-3 h-40 w-full grow"
onChange={e => setInputString(e.target.value)}
placeholder={t('workflow.nodes.http.curl.placeholder')!}
placeholder={t('nodes.http.curl.placeholder', { ns: 'workflow' })!}
/>
</div>
<div className="mt-4 flex justify-end space-x-2">
<Button className="!w-[95px]" onClick={onHide}>{t('common.operation.cancel')}</Button>
<Button className="!w-[95px]" onClick={onHide}>{t('operation.cancel', { ns: 'common' })}</Button>
<Button className="!w-[95px]" variant="primary" onClick={handleSave}>
{' '}
{t('common.operation.save')}
{t('operation.save', { ns: 'common' })}
</Button>
</div>
</Modal>

View File

@ -6,7 +6,7 @@ import { useTranslation } from 'react-i18next'
import { LayoutGrid02 } from '@/app/components/base/icons/src/vender/line/layout'
import TextEditor from '@/app/components/workflow/nodes/_base/components/editor/text-editor'
const i18nPrefix = 'workflow.nodes.http'
const i18nPrefix = 'nodes.http'
type Props = {
value: string
@ -39,7 +39,7 @@ const BulkEdit: FC<Props> = ({
<div>
<TextEditor
isInNode
title={<div className="uppercase">{t(`${i18nPrefix}.bulkEdit`)}</div>}
title={<div className="uppercase">{t(`${i18nPrefix}.bulkEdit`, { ns: 'workflow' })}</div>}
value={tempValue}
onChange={handleChange}
onBlur={handleBlur}
@ -50,7 +50,7 @@ const BulkEdit: FC<Props> = ({
onClick={handleSwitchToKeyValueEdit}
>
<LayoutGrid02 className="h-3 w-3 text-gray-500" />
<div className="text-xs font-normal leading-[18px] text-gray-500">{t(`${i18nPrefix}.keyValueEdit`)}</div>
<div className="text-xs font-normal leading-[18px] text-gray-500">{t(`${i18nPrefix}.keyValueEdit`, { ns: 'workflow' })}</div>
</div>
<div className="ml-3 mr-1.5 h-3 w-px bg-gray-200"></div>
</div>

View File

@ -8,7 +8,7 @@ import { useTranslation } from 'react-i18next'
import { cn } from '@/utils/classnames'
import KeyValueItem from './item'
const i18nPrefix = 'workflow.nodes.http'
const i18nPrefix = 'nodes.http'
type Props = {
readonly: boolean
@ -59,9 +59,9 @@ const KeyValueList: FC<Props> = ({
return (
<div className="overflow-hidden rounded-lg border border-divider-regular">
<div className={cn('system-xs-medium-uppercase flex h-7 items-center leading-7 text-text-tertiary')}>
<div className={cn('h-full border-r border-divider-regular pl-3', isSupportFile ? 'w-[140px]' : 'w-1/2')}>{t(`${i18nPrefix}.key`)}</div>
{isSupportFile && <div className="h-full w-[70px] shrink-0 border-r border-divider-regular pl-3">{t(`${i18nPrefix}.type`)}</div>}
<div className={cn('h-full items-center justify-between pl-3 pr-1', isSupportFile ? 'grow' : 'w-1/2')}>{t(`${i18nPrefix}.value`)}</div>
<div className={cn('h-full border-r border-divider-regular pl-3', isSupportFile ? 'w-[140px]' : 'w-1/2')}>{t(`${i18nPrefix}.key`, { ns: 'workflow' })}</div>
{isSupportFile && <div className="h-full w-[70px] shrink-0 border-r border-divider-regular pl-3">{t(`${i18nPrefix}.type`, { ns: 'workflow' })}</div>}
<div className={cn('h-full items-center justify-between pl-3 pr-1', isSupportFile ? 'grow' : 'w-1/2')}>{t(`${i18nPrefix}.value`, { ns: 'workflow' })}</div>
</div>
{
list.map((item, index) => (

View File

@ -71,7 +71,7 @@ const InputItem: FC<Props> = ({
nodesOutputVars={availableVars}
availableNodes={availableNodesWithParent}
onFocusChange={setIsFocus}
placeholder={t('workflow.nodes.http.insertVarPlaceholder')!}
placeholder={t('nodes.http.insertVarPlaceholder', { ns: 'workflow' })!}
placeholderClassName="!leading-[21px]"
promptMinHeightClassName="h-full"
insertVarTipToLeft={insertVarTipToLeft}
@ -92,7 +92,7 @@ const InputItem: FC<Props> = ({
nodesOutputVars={availableVars}
availableNodes={availableNodesWithParent}
onFocusChange={setIsFocus}
placeholder={t('workflow.nodes.http.insertVarPlaceholder')!}
placeholder={t('nodes.http.insertVarPlaceholder', { ns: 'workflow' })!}
placeholderClassName="!leading-[21px]"
promptMinHeightClassName="h-full"
insertVarTipToLeft={insertVarTipToLeft}

View File

@ -13,7 +13,7 @@ import VarReferencePicker from '../../../../_base/components/variable/var-refere
import InputItem from './input-item'
// import Input from '@/app/components/base/input'
const i18nPrefix = 'workflow.nodes.http'
const i18nPrefix = 'nodes.http'
type Props = {
instanceId: string
@ -73,7 +73,7 @@ const KeyValueItem: FC<Props> = ({
value={payload.key}
onChange={handleChange('key')}
hasRemove={false}
placeholder={t(`${i18nPrefix}.key`)!}
placeholder={t(`${i18nPrefix}.key`, { ns: 'workflow' })!}
readOnly={readonly}
insertVarTipToLeft={insertVarTipToLeft}
/>
@ -123,7 +123,7 @@ const KeyValueItem: FC<Props> = ({
onChange={handleChange('value')}
hasRemove={!readonly && canRemove}
onRemove={onRemove}
placeholder={t(`${i18nPrefix}.value`)!}
placeholder={t(`${i18nPrefix}.value`, { ns: 'workflow' })!}
readOnly={readonly}
isSupportFile={isSupportFile}
insertVarTipToLeft={insertVarTipToLeft}

View File

@ -15,7 +15,7 @@ type Props = {
onChange: (payload: TimeoutPayloadType) => void
}
const i18nPrefix = 'workflow.nodes.http'
const i18nPrefix = 'nodes.http'
const InputField: FC<{
title: string
@ -69,13 +69,13 @@ const Timeout: FC<Props> = ({ readonly, payload, onChange }) => {
const defaultTimeout = defaultConfig?.timeout || {}
return (
<FieldCollapse title={t(`${i18nPrefix}.timeout.title`)}>
<FieldCollapse title={t(`${i18nPrefix}.timeout.title`, { ns: 'workflow' })}>
<div className="mt-2 space-y-1">
<div className="space-y-3">
<InputField
title={t('workflow.nodes.http.timeout.connectLabel')!}
description={t('workflow.nodes.http.timeout.connectPlaceholder')!}
placeholder={t('workflow.nodes.http.timeout.connectPlaceholder')!}
title={t('nodes.http.timeout.connectLabel', { ns: 'workflow' })!}
description={t('nodes.http.timeout.connectPlaceholder', { ns: 'workflow' })!}
placeholder={t('nodes.http.timeout.connectPlaceholder', { ns: 'workflow' })!}
readOnly={readonly}
value={connect}
onChange={v => onChange?.({ ...payload, connect: v })}
@ -83,9 +83,9 @@ const Timeout: FC<Props> = ({ readonly, payload, onChange }) => {
max={max_connect_timeout || defaultTimeout.max_connect_timeout || 10}
/>
<InputField
title={t('workflow.nodes.http.timeout.readLabel')!}
description={t('workflow.nodes.http.timeout.readPlaceholder')!}
placeholder={t('workflow.nodes.http.timeout.readPlaceholder')!}
title={t('nodes.http.timeout.readLabel', { ns: 'workflow' })!}
description={t('nodes.http.timeout.readPlaceholder', { ns: 'workflow' })!}
placeholder={t('nodes.http.timeout.readPlaceholder', { ns: 'workflow' })!}
readOnly={readonly}
value={read}
onChange={v => onChange?.({ ...payload, read: v })}
@ -93,9 +93,9 @@ const Timeout: FC<Props> = ({ readonly, payload, onChange }) => {
max={max_read_timeout || defaultTimeout.max_read_timeout || 600}
/>
<InputField
title={t('workflow.nodes.http.timeout.writeLabel')!}
description={t('workflow.nodes.http.timeout.writePlaceholder')!}
placeholder={t('workflow.nodes.http.timeout.writePlaceholder')!}
title={t('nodes.http.timeout.writeLabel', { ns: 'workflow' })!}
description={t('nodes.http.timeout.writePlaceholder', { ns: 'workflow' })!}
placeholder={t('nodes.http.timeout.writePlaceholder', { ns: 'workflow' })!}
readOnly={readonly}
value={write}
onChange={v => onChange?.({ ...payload, write: v })}

View File

@ -42,13 +42,13 @@ const nodeDefault: NodeDefault<HttpNodeType> = {
let errorMessages = ''
if (!errorMessages && !payload.url)
errorMessages = t('workflow.errorMsg.fieldRequired', { field: t('workflow.nodes.http.api') })
errorMessages = t('errorMsg.fieldRequired', { ns: 'workflow', field: t('nodes.http.api', { ns: 'workflow' }) })
if (!errorMessages
&& payload.body.type === BodyType.binary
&& ((!(payload.body.data as BodyPayload)[0]?.file) || (payload.body.data as BodyPayload)[0]?.file?.length === 0)
) {
errorMessages = t('workflow.errorMsg.fieldRequired', { field: t('workflow.nodes.http.binaryFileVariable') })
errorMessages = t('errorMsg.fieldRequired', { ns: 'workflow', field: t('nodes.http.binaryFileVariable', { ns: 'workflow' }) })
}
return {

View File

@ -18,7 +18,7 @@ import KeyValue from './components/key-value'
import Timeout from './components/timeout'
import useConfig from './use-config'
const i18nPrefix = 'workflow.nodes.http'
const i18nPrefix = 'nodes.http'
const Panel: FC<NodePanelProps<HttpNodeType>> = ({
id,
@ -58,7 +58,7 @@ const Panel: FC<NodePanelProps<HttpNodeType>> = ({
<div className="pt-2">
<div className="space-y-4 px-4 pb-4">
<Field
title={t(`${i18nPrefix}.api`)}
title={t(`${i18nPrefix}.api`, { ns: 'workflow' })}
required
operations={(
<div className="flex">
@ -68,8 +68,8 @@ const Panel: FC<NodePanelProps<HttpNodeType>> = ({
>
{!readOnly && <Settings01 className="h-3 w-3 text-text-tertiary" />}
<div className="text-xs font-medium text-text-tertiary">
{t(`${i18nPrefix}.authorization.authorization`)}
<span className="ml-1 text-text-secondary">{t(`${i18nPrefix}.authorization.${inputs.authorization.type}`)}</span>
{t(`${i18nPrefix}.authorization.authorization`, { ns: 'workflow' })}
<span className="ml-1 text-text-secondary">{t(`${i18nPrefix}.authorization.${inputs.authorization.type}`, { ns: 'workflow' })}</span>
</div>
</div>
<div
@ -78,7 +78,7 @@ const Panel: FC<NodePanelProps<HttpNodeType>> = ({
>
{!readOnly && <FileArrow01 className="h-3 w-3 text-text-tertiary" />}
<div className="text-xs font-medium text-text-tertiary">
{t(`${i18nPrefix}.curl.title`)}
{t(`${i18nPrefix}.curl.title`, { ns: 'workflow' })}
</div>
</div>
</div>
@ -94,7 +94,7 @@ const Panel: FC<NodePanelProps<HttpNodeType>> = ({
/>
</Field>
<Field
title={t(`${i18nPrefix}.headers`)}
title={t(`${i18nPrefix}.headers`, { ns: 'workflow' })}
>
<KeyValue
nodeId={id}
@ -105,7 +105,7 @@ const Panel: FC<NodePanelProps<HttpNodeType>> = ({
/>
</Field>
<Field
title={t(`${i18nPrefix}.params`)}
title={t(`${i18nPrefix}.params`, { ns: 'workflow' })}
>
<KeyValue
nodeId={id}
@ -116,7 +116,7 @@ const Panel: FC<NodePanelProps<HttpNodeType>> = ({
/>
</Field>
<Field
title={t(`${i18nPrefix}.body`)}
title={t(`${i18nPrefix}.body`, { ns: 'workflow' })}
required
>
<EditBody
@ -127,8 +127,8 @@ const Panel: FC<NodePanelProps<HttpNodeType>> = ({
/>
</Field>
<Field
title={t(`${i18nPrefix}.verifySSL.title`)}
tooltip={t(`${i18nPrefix}.verifySSL.warningTooltip`)}
title={t(`${i18nPrefix}.verifySSL.title`, { ns: 'workflow' })}
tooltip={t(`${i18nPrefix}.verifySSL.warningTooltip`, { ns: 'workflow' })}
operations={(
<Switch
defaultValue={!!inputs.ssl_verify}
@ -163,22 +163,22 @@ const Panel: FC<NodePanelProps<HttpNodeType>> = ({
<VarItem
name="body"
type="string"
description={t(`${i18nPrefix}.outputVars.body`)}
description={t(`${i18nPrefix}.outputVars.body`, { ns: 'workflow' })}
/>
<VarItem
name="status_code"
type="number"
description={t(`${i18nPrefix}.outputVars.statusCode`)}
description={t(`${i18nPrefix}.outputVars.statusCode`, { ns: 'workflow' })}
/>
<VarItem
name="headers"
type="object"
description={t(`${i18nPrefix}.outputVars.headers`)}
description={t(`${i18nPrefix}.outputVars.headers`, { ns: 'workflow' })}
/>
<VarItem
name="files"
type="Array[File]"
description={t(`${i18nPrefix}.outputVars.files`)}
description={t(`${i18nPrefix}.outputVars.files`, { ns: 'workflow' })}
/>
</>
</OutputVars>