fix(i18n): Add and update i18n Translation for Toolbar Tool Names (#5392)

This commit is contained in:
毛知劲 | LIS/PACS/RIS 产品负责人 authored and GitHub committed 2025-09-25 10:22:02 -04:00
1 parent add69e5e4f
commit 7783d0f558
51 files changed
+1058 -558

No files matched your search

+14 -14
View File
@@ -518,8 +518,8 @@ function commandsModule({
if (!labelConfig) {
const label = await callInputDialog({
uiDialogService,
title: 'Edit Measurement Label',
placeholder: measurement.label || 'Enter new label',
title: i18n.t('Tools:Edit Measurement Label'),
placeholder: measurement.label || i18n.t('Tools:Enter new label'),
defaultValue: measurement.label,
});
@@ -733,8 +733,8 @@ function commandsModule({
if (!labelConfig) {
const label = await callInputDialog({
uiDialogService,
title: 'Edit Arrow Text',
placeholder: data?.data?.label || 'Enter new text',
title: i18n.t('Tools:Edit Arrow Text'),
placeholder: data?.data?.label || i18n.t('Tools:Enter new text'),
defaultValue: data?.data?.label || '',
});
@@ -978,8 +978,8 @@ function commandsModule({
if (!cornerstoneViewportService.getCornerstoneViewport(activeViewportId)) {
// Cannot download a non-cornerstone viewport (image).
uiNotificationService.show({
title: 'Download Image',
message: 'Image cannot be downloaded',
title: i18n.t('Tools:Download Image'),
message: i18n.t('Tools:Image cannot be downloaded'),
type: 'error',
});
return;
@@ -990,7 +990,7 @@ function commandsModule({
if (uiModalService) {
uiModalService.show({
content: CornerstoneViewportDownloadForm,
title: 'Download High Quality Image',
title: i18n.t('Tools:Download High Quality Image'),
contentProps: {
activeViewportId,
cornerstoneViewportService,
@@ -1454,7 +1454,7 @@ function commandsModule({
const segs = segmentationService.getSegmentations();
const label = options.label || `Segmentation ${segs.length + 1}`;
const label = options.label || `${i18n.t('Tools:Segmentation')} ${segs.length + 1}`;
const segmentationId = options.segmentationId || `${csUtils.uuidv4()}`;
const displaySet = displaySetService.getDisplaySetByUID(displaySetInstanceUID);
@@ -1468,7 +1468,7 @@ function commandsModule({
segments: options.createInitialSegment
? {
1: {
label: `${i18n.t('Segment')} 1`,
label: `${i18n.t('Tools:Segment')} 1`,
active: true,
},
}
@@ -1745,8 +1745,8 @@ function commandsModule({
callInputDialog({
uiDialogService,
title: 'Edit Segment Label',
placeholder: 'Enter new label',
title: i18n.t('Tools:Edit Segment Label'),
placeholder: i18n.t('Tools:Enter new label'),
defaultValue: segment.label,
}).then(label => {
segmentationService.setSegmentLabel(segmentationId, segmentIndex, label);
@@ -1765,8 +1765,8 @@ function commandsModule({
callInputDialog({
uiDialogService,
title: 'Edit Segmentation Label',
placeholder: 'Enter new label',
title: i18n.t('Tools:Edit Segmentation Label'),
placeholder: i18n.t('Tools:Enter new label'),
defaultValue: label,
}).then(label => {
segmentationService.addOrUpdateSegmentation({ segmentationId, label });
@@ -1788,7 +1788,7 @@ function commandsModule({
uiDialogService.show({
content: colorPickerDialog,
title: 'Segment Color',
title: i18n.t('Tools:Segment Color'),
contentProps: {
value: rgbaColor,
onSave: newRgbaColor => {
@@ -1,9 +1,11 @@
import React, { ReactElement, useCallback } from 'react';
import { Switch } from '@ohif/ui-next';
import { useViewportRendering } from '../../hooks/useViewportRendering';
import { useTranslation } from 'react-i18next';
export function Colorbar({ viewportId }: { viewportId?: string } = {}): ReactElement {
const { hasColorbar, toggleColorbar } = useViewportRendering(viewportId);
const { t } = useTranslation('WindowLevelActionMenu');
const handleToggle = useCallback(() => {
toggleColorbar();
@@ -16,7 +18,7 @@ export function Colorbar({ viewportId }: { viewportId?: string } = {}): ReactEle
className="flex-grow"
onClick={handleToggle}
>
Display Color bar
{t('Display Color bar')}
</span>
<Switch
className="ml-2 flex-shrink-0"
@@ -1,9 +1,11 @@
import React, { ReactElement, useEffect, useRef, useState } from 'react';
import { AllInOneMenu, ScrollArea, Switch, Tabs, TabsList, TabsTrigger } from '@ohif/ui-next';
import { useViewportRendering } from '../../hooks/useViewportRendering';
import { useTranslation } from 'react-i18next';
export function Colormap({ viewportId }: { viewportId?: string } = {}): ReactElement {
const { viewportDisplaySets } = useViewportRendering(viewportId);
const { t } = useTranslation('WindowLevelActionMenu');
const [activeDisplaySetUID, setActiveDisplaySetUID] = useState<string | undefined>(
viewportDisplaySets?.[0]?.displaySetInstanceUID
@@ -74,7 +76,7 @@ export function Colormap({ viewportId }: { viewportId?: string } = {}): ReactEle
className="hover:bg-accent flex h-8 w-full flex-shrink-0 cursor-pointer items-center px-2 text-base hover:rounded"
onClick={() => setShowPreview(!showPreview)}
>
<span className="flex-shrink-0">Preview in viewport</span>
<span className="flex-shrink-0">{t('Preview in viewport')}</span>
<Switch
className="ml-auto flex-shrink-0"
checked={showPreview}
@@ -7,6 +7,7 @@ import { WindowLevel } from './WindowLevel';
import { VolumeRenderingPresets } from './VolumeRenderingPresets';
import { VolumeRenderingOptions } from './VolumeRenderingOptions';
import { useViewportRendering } from '../../hooks/useViewportRendering';
import i18n from 'i18next';
export type WindowLevelActionMenuProps = {
viewportId: string;
@@ -58,6 +59,7 @@ export function WindowLevelActionMenuContent({
isVisible={true}
align={align}
side={side}
backLabel={i18n.t('WindowLevelActionMenu:Back to Display Options')}
>
<AllInOneMenu.ItemPanel>
{!is3DVolume && <Colorbar viewportId={viewportId} />}
@@ -65,7 +67,7 @@ export function WindowLevelActionMenuContent({
{colorbarProperties?.colormaps && !is3DVolume && (
<AllInOneMenu.SubMenu
key="colorLUTPresets"
itemLabel="Color LUT"
itemLabel={t('Color LUT')}
itemIcon="icon-color-lut"
className="flex h-[calc(100%-32px)] flex-col"
>
@@ -86,7 +88,7 @@ export function WindowLevelActionMenuContent({
{volumeRenderingPresets && is3DVolume && <VolumeRenderingPresets viewportId={viewportId} />}
{volumeRenderingQualityRange && is3DVolume && (
<AllInOneMenu.SubMenu itemLabel="Rendering Options">
<AllInOneMenu.SubMenu itemLabel={t('Rendering Options')}>
<VolumeRenderingOptions viewportId={viewportId} />
</AllInOneMenu.SubMenu>
)}
@@ -1,6 +1,6 @@
import React, { useState, useEffect } from 'react';
import { ImageModal, FooterAction } from '@ohif/ui-next';
import { useTranslation } from 'react-i18next';
const MAX_TEXTURE_SIZE = 10000;
const DEFAULT_FILENAME = 'image';
@@ -37,6 +37,7 @@ function ViewportDownloadFormNew({
const [showWarningMessage, setShowWarningMessage] = useState(true);
const [filename, setFilename] = useState(DEFAULT_FILENAME);
const [fileType, setFileType] = useState('jpg');
const { t } = useTranslation('CaptureViewportModal');
useEffect(() => {
if (!viewportElement) {
@@ -82,7 +83,7 @@ function ViewportDownloadFormNew({
value={filename}
onChange={e => setFilename(e.target.value)}
>
File name
{t('File name')}
</ImageModal.Filename>
<ImageModal.Filetype
selected={fileType}
@@ -109,7 +110,7 @@ function ViewportDownloadFormNew({
maxWidth={MAX_TEXTURE_SIZE.toString()}
maxHeight={MAX_TEXTURE_SIZE.toString()}
>
Image size <span className="text-muted-foreground">px</span>
{t('Image size')} <span className="text-muted-foreground">px</span>
</ImageModal.ImageSize>
<ImageModal.SwitchOption
@@ -117,7 +118,7 @@ function ViewportDownloadFormNew({
checked={showAnnotations}
onCheckedChange={onAnnotationsChange}
>
Include annotations
{t('Include annotations')}
</ImageModal.SwitchOption>
{warningState.enabled && (
<ImageModal.SwitchOption
@@ -125,19 +126,21 @@ function ViewportDownloadFormNew({
checked={showWarningMessage}
onCheckedChange={setShowWarningMessage}
>
Include warning message
{t('Include warning message')}
</ImageModal.SwitchOption>
)}
<FooterAction className="mt-2">
<FooterAction.Right>
<FooterAction.Secondary onClick={onClose}>Cancel</FooterAction.Secondary>
<FooterAction.Secondary onClick={onClose}>
{t('Common:Cancel')}
</FooterAction.Secondary>
<FooterAction.Primary
onClick={() => {
onDownload(filename || DEFAULT_FILENAME, fileType);
onClose();
}}
>
Save
{t('Common:Save')}
</FooterAction.Primary>
</FooterAction.Right>
</FooterAction>
+2 -2
View File
@@ -1,9 +1,9 @@
import { HYDRATE_SEG_SYNC_GROUP, VOI_SYNC_GROUP } from './mpr';
import i18n from 'i18next';
export const fourUp = {
id: 'fourUp',
locked: true,
name: '3D four up',
name: i18n.t('Hps:3D four up'),
icon: 'layout-advanced-3d-four-up',
isPreset: true,
createdDate: '2023-03-15T10:29:44.894Z',
+3 -3
View File
@@ -1,9 +1,9 @@
import { Types } from '@ohif/core';
import i18n from 'i18next';
const frameView: Types.HangingProtocol.Protocol = {
id: '@ohif/frameView',
description: 'Frame view for the active series',
name: 'Frame View',
description: i18n.t('Hps:Frame view for the active series'),
name: i18n.t('Hps:Frame View'),
icon: 'tool-stack-scroll',
isPreset: true,
toolGroupIds: ['default'],
+2 -2
View File
@@ -1,9 +1,9 @@
import { HYDRATE_SEG_SYNC_GROUP, VOI_SYNC_GROUP } from './mpr';
import i18n from 'i18next';
export const main3D = {
id: 'main3D',
locked: true,
name: '3D main',
name: i18n.t('Hps:3D main'),
icon: 'layout-advanced-3d-main',
isPreset: true,
createdDate: '2023-03-15T10:29:44.894Z',
+2 -2
View File
@@ -1,5 +1,5 @@
import { Types } from '@ohif/core';
import i18n from 'i18next';
export const VOI_SYNC_GROUP = {
type: 'voi',
id: 'mpr',
@@ -22,7 +22,7 @@ export const HYDRATE_SEG_SYNC_GROUP = {
export const mpr: Types.HangingProtocol.Protocol = {
id: 'mpr',
name: 'MPR',
name: i18n.t('Hps:MPR'),
locked: true,
icon: 'layout-advanced-mpr',
isPreset: true,
@@ -1,9 +1,9 @@
import { HYDRATE_SEG_SYNC_GROUP, VOI_SYNC_GROUP } from './mpr';
import i18n from 'i18next';
export const mprAnd3DVolumeViewport = {
id: 'mprAnd3DVolumeViewport',
locked: true,
name: 'mpr',
name: i18n.t('Hps:mpr'),
createdDate: '2023-03-15T10:29:44.894Z',
modifiedDate: '2023-03-15T10:29:44.894Z',
availableTo: {},
+2 -1
View File
@@ -1,9 +1,10 @@
import { HYDRATE_SEG_SYNC_GROUP, VOI_SYNC_GROUP } from './mpr';
import i18n from 'i18next';
export const only3D = {
id: 'only3D',
locked: true,
name: '3D only',
name: i18n.t('Hps:3D only'),
icon: 'layout-advanced-3d-only',
isPreset: true,
createdDate: '2023-03-15T10:29:44.894Z',
+2 -2
View File
@@ -1,9 +1,9 @@
import { HYDRATE_SEG_SYNC_GROUP, VOI_SYNC_GROUP } from './mpr';
import i18n from 'i18next';
export const primary3D = {
id: 'primary3D',
locked: true,
name: '3D primary',
name: i18n.t('Hps:3D primary'),
icon: 'layout-advanced-3d-primary',
isPreset: true,
createdDate: '2023-03-15T10:29:44.894Z',
@@ -1,9 +1,9 @@
import { HYDRATE_SEG_SYNC_GROUP, VOI_SYNC_GROUP } from './mpr';
import i18n from 'i18next';
export const primaryAxial = {
id: 'primaryAxial',
locked: true,
name: 'Axial Primary',
name: i18n.t('Hps:Axial Primary'),
icon: 'layout-advanced-axial-primary',
isPreset: true,
createdDate: '2023-03-15T10:29:44.894Z',
@@ -4,6 +4,7 @@ import PropTypes from 'prop-types';
import { CommandsManager } from '@ohif/core';
import { LayoutSelector } from '@ohif/ui-next';
import { useTranslation } from 'react-i18next';
function ToolbarLayoutSelectorWithServices({
commandsManager,
@@ -13,6 +14,7 @@ function ToolbarLayoutSelectorWithServices({
...props
}) {
const { customizationService } = servicesManager.services;
const { t } = useTranslation('ToolbarLayoutSelector');
// Get the presets from the customization service
const commonPresets = customizationService?.getCustomization('layoutSelector.commonPresets') || [
@@ -135,14 +137,14 @@ function ToolbarLayoutSelectorWithServices({
onSelectionChange={handleSelectionChange}
{...props}
>
<LayoutSelector.Trigger tooltip="Change layout" />
<LayoutSelector.Trigger tooltip={t('Change layout')} />
<LayoutSelector.Content>
{/* Left side - Presets */}
{(commonPresets.length > 0 || advancedPresets.length > 0) && (
<div className="bg-popover flex flex-col gap-2.5 rounded-lg p-2">
{commonPresets.length > 0 && (
<>
<LayoutSelector.PresetSection title="Common">
<LayoutSelector.PresetSection title={t('Common')}>
{commonPresets.map((preset, index) => (
<LayoutSelector.Preset
key={`common-preset-${index}`}
@@ -157,7 +159,7 @@ function ToolbarLayoutSelectorWithServices({
)}
{advancedPresets.length > 0 && (
<LayoutSelector.PresetSection title="Advanced">
<LayoutSelector.PresetSection title={t('Advanced')}>
{advancedPresets.map((preset, index) => (
<LayoutSelector.Preset
key={`advanced-preset-${index}`}
@@ -175,14 +177,15 @@ function ToolbarLayoutSelectorWithServices({
{/* Right Side - Grid Layout */}
<div className="bg-muted flex flex-col gap-2.5 border-l-2 border-solid border-black p-2">
<div className="text-muted-foreground text-xs">Custom</div>
<div className="text-muted-foreground text-xs">{t('Custom')}</div>
<LayoutSelector.GridSelector
rows={rows}
columns={columns}
/>
<LayoutSelector.HelpText>
Hover to select <br />
rows and columns <br /> Click to apply
{t('Hover to select')} <br />
{t('rows and columns')} <br />
{t('Click to apply')}
</LayoutSelector.HelpText>
</div>
</LayoutSelector.Content>
@@ -1,4 +1,5 @@
import { utils } from '@ohif/core';
import i18n from '@ohif/i18n';
const { formatDate } = utils;
export default {
@@ -6,7 +7,7 @@ export default {
'studyBrowser.thumbnailMenuItems': [
{
id: 'tagBrowser',
label: 'Tag Browser',
label: i18n.t('StudyBrowser:Tag Browser'),
iconName: 'DicomTagBrowser',
onClick: ({ commandsManager, displaySetInstanceUID }: withAppTypes) => {
commandsManager.runCommand('openDICOMTagViewer', {
@@ -16,7 +17,7 @@ export default {
},
{
id: 'addAsLayer',
label: 'Add as Layer',
label: i18n.t('StudyBrowser:Add as Layer'),
iconName: 'ViewportViews',
onClick: ({ commandsManager, displaySetInstanceUID, servicesManager }: withAppTypes) => {
const { viewportGridService } = servicesManager.services;
@@ -37,13 +38,13 @@ export default {
],
'studyBrowser.sortFunctions': [
{
label: 'Series Number',
label: i18n.t('StudyBrowser:Series Number'),
sortFunction: (a, b) => {
return a?.SeriesNumber - b?.SeriesNumber;
},
},
{
label: 'Series Date',
label: i18n.t('StudyBrowser:Series Date'),
sortFunction: (a, b) => {
const dateA = new Date(formatDate(a?.SeriesDate));
const dateB = new Date(formatDate(b?.SeriesDate));
@@ -81,8 +82,10 @@ export default {
} catch (error) {
console.warn(error);
uiNotificationService.show({
title: 'Thumbnail Double Click',
message: 'The selected display sets could not be added to the viewport.',
title: i18n.t('StudyBrowser:Thumbnail Double Click'),
message: i18n.t(
'StudyBrowser:The selected display sets could not be added to the viewport.'
),
type: 'error',
duration: 3000,
});