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

@ -1,5 +1,6 @@
import type { FC } from 'react'
import type { WriteMode } from '../types'
import type { Item } from '../utils'
import type { VarType } from '@/app/components/workflow/types'
import {
RiArrowDownSLine,
@ -14,12 +15,7 @@ import {
PortalToFollowElemTrigger,
} from '@/app/components/base/portal-to-follow-elem'
import { cn } from '@/utils/classnames'
import { getOperationItems } from '../utils'
type Item = {
value: string | number
name: string
}
import { getOperationItems, isOperationItem } from '../utils'
type OperationSelectorProps = {
value: string | number
@ -34,8 +30,6 @@ type OperationSelectorProps = {
writeModeTypesNum?: WriteMode[]
}
const i18nPrefix = 'workflow.nodes.assigner'
const OperationSelector: FC<OperationSelectorProps> = ({
value,
onSelect,
@ -72,7 +66,7 @@ const OperationSelector: FC<OperationSelectorProps> = ({
className={`system-sm-regular overflow-hidden truncate text-ellipsis
${selectedItem ? 'text-components-input-text-filled' : 'text-components-input-text-disabled'}`}
>
{selectedItem?.name ? t(`${i18nPrefix}.operations.${selectedItem?.name}` as any) as string : t(`${i18nPrefix}.operations.title` as any) as string}
{selectedItem && isOperationItem(selectedItem) ? t(`nodes.assigner.operations.${selectedItem.name}`, { ns: 'workflow' }) : t('nodes.assigner.operations.title', { ns: 'workflow' })}
</span>
</div>
<RiArrowDownSLine className={`h-4 w-4 text-text-quaternary ${disabled && 'text-components-input-text-placeholder'} ${open && 'text-text-secondary'}`} />
@ -83,10 +77,10 @@ const OperationSelector: FC<OperationSelectorProps> = ({
<div className="flex w-[140px] flex-col items-start rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur shadow-lg">
<div className="flex flex-col items-start self-stretch p-1">
<div className="flex items-start self-stretch px-3 pb-0.5 pt-1">
<div className="system-xs-medium-uppercase flex grow text-text-tertiary">{t(`${i18nPrefix}.operations.title` as any) as string}</div>
<div className="system-xs-medium-uppercase flex grow text-text-tertiary">{t('nodes.assigner.operations.title', { ns: 'workflow' })}</div>
</div>
{items.map(item => (
item.value === 'divider'
!isOperationItem(item)
? (
<Divider key="divider" className="my-1" />
)
@ -100,7 +94,7 @@ const OperationSelector: FC<OperationSelectorProps> = ({
}}
>
<div className="flex min-h-5 grow items-center gap-1 px-1">
<span className="system-sm-medium flex grow text-text-secondary">{t(`${i18nPrefix}.operations.${item.name}` as any) as string}</span>
<span className="system-sm-medium flex grow text-text-secondary">{t(`nodes.assigner.operations.${item.name}`, { ns: 'workflow' })}</span>
</div>
{item.value === value && (
<div className="flex items-center justify-center">

View File

@ -119,7 +119,7 @@ const VarList: FC<Props> = ({
if (list.length === 0) {
return (
<ListNoDataPlaceholder>
{t('workflow.nodes.assigner.noVarTip')}
{t('nodes.assigner.noVarTip', { ns: 'workflow' })}
</ListNoDataPlaceholder>
)
}
@ -144,7 +144,7 @@ const VarList: FC<Props> = ({
onChange={handleAssignedVarChange(index)}
onOpen={handleOpen(index)}
filterVar={filterVar}
placeholder={t('workflow.nodes.assigner.selectAssignedVariable') as string}
placeholder={t('nodes.assigner.selectAssignedVariable', { ns: 'workflow' }) as string}
minWidth={352}
popupFor="assigned"
className="w-full"
@ -172,7 +172,7 @@ const VarList: FC<Props> = ({
onChange={handleToAssignedVarChange(index)}
filterVar={handleFilterToAssignedVar(index)}
valueTypePlaceHolder={toAssignedVarType}
placeholder={t('workflow.nodes.assigner.setParameter') as string}
placeholder={t('nodes.assigner.setParameter', { ns: 'workflow' }) as string}
minWidth={352}
popupFor="toAssigned"
className="w-full"

View File

@ -5,7 +5,7 @@ import { BlockEnum } from '@/app/components/workflow/types'
import { genNodeMetaData } from '@/app/components/workflow/utils'
import { WriteMode } from './types'
const i18nPrefix = 'workflow.errorMsg'
const i18nPrefix = 'errorMsg'
const metaData = genNodeMetaData({
classification: BlockClassificationEnum.Transform,
@ -27,17 +27,17 @@ const nodeDefault: NodeDefault<AssignerNodeType> = {
operationItems?.forEach((value) => {
if (!errorMessages && !value.variable_selector?.length)
errorMessages = t(`${i18nPrefix}.fieldRequired`, { field: t('workflow.nodes.assigner.assignedVariable') })
errorMessages = t(`${i18nPrefix}.fieldRequired`, { ns: 'workflow', field: t('nodes.assigner.assignedVariable', { ns: 'workflow' }) })
if (!errorMessages && value.operation !== WriteMode.clear && value.operation !== WriteMode.removeFirst && value.operation !== WriteMode.removeLast) {
if (value.operation === WriteMode.set || value.operation === WriteMode.increment
|| value.operation === WriteMode.decrement || value.operation === WriteMode.multiply
|| value.operation === WriteMode.divide) {
if (!value.value && value.value !== false && typeof value.value !== 'number')
errorMessages = t(`${i18nPrefix}.fieldRequired`, { field: t('workflow.nodes.assigner.variable') })
errorMessages = t(`${i18nPrefix}.fieldRequired`, { ns: 'workflow', field: t('nodes.assigner.variable', { ns: 'workflow' }) })
}
else if (!value.value?.length) {
errorMessages = t(`${i18nPrefix}.fieldRequired`, { field: t('workflow.nodes.assigner.variable') })
errorMessages = t(`${i18nPrefix}.fieldRequired`, { ns: 'workflow', field: t('nodes.assigner.variable', { ns: 'workflow' }) })
}
}
})

View File

@ -1,5 +1,6 @@
import type { FC } from 'react'
import type { AssignerNodeType } from './types'
import type { OperationName } from './utils'
import type { Node, NodeProps } from '@/app/components/workflow/types'
import * as React from 'react'
import { useTranslation } from 'react-i18next'
@ -11,7 +12,7 @@ import {
} from '@/app/components/workflow/nodes/_base/components/variable/variable-label'
import { BlockEnum } from '@/app/components/workflow/types'
const i18nPrefix = 'workflow.nodes.assigner'
const i18nPrefix = 'nodes.assigner'
const NodeComponent: FC<NodeProps<AssignerNodeType>> = ({
data,
@ -29,7 +30,7 @@ const NodeComponent: FC<NodeProps<AssignerNodeType>> = ({
<div className="relative flex flex-col items-start gap-0.5 self-stretch px-3 py-1">
<div className="flex flex-col items-start gap-1 self-stretch">
<div className="flex items-center gap-1 self-stretch rounded-md bg-workflow-block-parma-bg px-[5px] py-1">
<div className="system-xs-medium flex-1 text-text-tertiary">{t(`${i18nPrefix}.varNotSet`)}</div>
<div className="system-xs-medium flex-1 text-text-tertiary">{t(`${i18nPrefix}.varNotSet`, { ns: 'workflow' })}</div>
</div>
</div>
</div>
@ -50,7 +51,7 @@ const NodeComponent: FC<NodeProps<AssignerNodeType>> = ({
nodeType={node?.data.type}
nodeTitle={node?.data.title}
rightSlot={
value.operation && <Badge className="!ml-auto shrink-0" text={t(`${i18nPrefix}.operations.${value.operation}`)} />
value.operation && <Badge className="!ml-auto shrink-0" text={t(`${i18nPrefix}.operations.${value.operation}`, { ns: 'workflow' })} />
}
/>
)
@ -59,7 +60,8 @@ const NodeComponent: FC<NodeProps<AssignerNodeType>> = ({
)
}
// Legacy version
const { assigned_variable_selector: variable, write_mode: writeMode } = data as any
type LegacyAssignerNodeType = { assigned_variable_selector: string[], write_mode: OperationName }
const { assigned_variable_selector: variable, write_mode: writeMode } = data as unknown as LegacyAssignerNodeType
if (!variable || variable.length === 0)
return null
@ -73,7 +75,7 @@ const NodeComponent: FC<NodeProps<AssignerNodeType>> = ({
nodeType={node?.data.type}
nodeTitle={node?.data.title}
rightSlot={
writeMode && <Badge className="!ml-auto shrink-0" text={t(`${i18nPrefix}.operations.${writeMode}` as any) as string} />
writeMode && <Badge className="!ml-auto shrink-0" text={t(`nodes.assigner.operations.${writeMode}`, { ns: 'workflow' })} />
}
/>
</div>

View File

@ -11,7 +11,7 @@ import VarList from './components/var-list'
import { useHandleAddOperationItem } from './hooks'
import useConfig from './use-config'
const i18nPrefix = 'workflow.nodes.assigner'
const i18nPrefix = 'nodes.assigner'
const Panel: FC<NodePanelProps<AssignerNodeType>> = ({
id,
@ -40,7 +40,7 @@ const Panel: FC<NodePanelProps<AssignerNodeType>> = ({
<div className="flex flex-col items-start self-stretch py-2">
<div className="flex w-full flex-col items-start justify-center gap-1 self-stretch px-4 py-2">
<div className="flex items-start gap-2 self-stretch">
<div className="system-sm-semibold-uppercase flex grow flex-col items-start justify-center text-text-secondary">{t(`${i18nPrefix}.variables`)}</div>
<div className="system-sm-semibold-uppercase flex grow flex-col items-start justify-center text-text-secondary">{t(`${i18nPrefix}.variables`, { ns: 'workflow' })}</div>
<ActionButton onClick={handleAddOperation}>
<RiAddLine className="h-4 w-4 shrink-0 text-text-tertiary" />
</ActionButton>

View File

@ -1,4 +1,5 @@
import type { AssignerNodeType } from './types'
import type { I18nKeysByPrefix } from '@/types/i18n'
import { AssignerNodeInputType, WriteMode } from './types'
export const checkNodeValid = (_payload: AssignerNodeType) => {
@ -11,9 +12,14 @@ export const formatOperationName = (type: string) => {
return type.charAt(0).toUpperCase() + type.slice(1)
}
type Item = {
value: string | number
name: string
export type OperationName = I18nKeysByPrefix<'workflow', 'nodes.assigner.operations.'>
export type Item
= | { value: 'divider', name: 'divider' }
| { value: string | number, name: OperationName }
export function isOperationItem(item: Item): item is { value: string | number, name: OperationName } {
return item.value !== 'divider'
}
export const getOperationItems = (