chore: update French i18n (#5561)
This commit is contained in:
1 parent
ba140a05f7
commit
181c0f32c5
185 files changed
+2779
-374
No files matched your search
@@ -4,9 +4,9 @@ import PropTypes from 'prop-types';
|
||||
import { metaData, Enums, utilities, eventTarget } from '@cornerstonejs/core';
|
||||
import { Enums as csToolsEnums, UltrasoundPleuraBLineTool } from '@cornerstonejs/tools';
|
||||
import type { ImageSliceData } from '@cornerstonejs/core/types';
|
||||
import { ViewportOverlay } from '@ohif/ui-next';
|
||||
import { ViewportOverlay, formatDICOMDate } from '@ohif/ui-next';
|
||||
import type { InstanceMetadata } from '@ohif/core/src/types';
|
||||
import { formatDICOMDate, formatDICOMTime, formatNumberPrecision } from './utils';
|
||||
import { formatDICOMTime, formatNumberPrecision } from './utils';
|
||||
import { utils } from '@ohif/core';
|
||||
import { StackViewportData, VolumeViewportData } from '../../types/CornerstoneCacheService';
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import moment from 'moment';
|
||||
import i18n from 'i18next';
|
||||
import { metaData } from '@cornerstonejs/core';
|
||||
import { formatDICOMDate } from '@ohif/ui-next';
|
||||
|
||||
/**
|
||||
* Checks if value is valid.
|
||||
@@ -24,17 +26,6 @@ export function formatNumberPrecision(number, precision = 0) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats DICOM date.
|
||||
*
|
||||
* @param {string} date
|
||||
* @param {string} strFormat
|
||||
* @returns {string} formatted date.
|
||||
*/
|
||||
export function formatDICOMDate(date, strFormat = 'MMM D, YYYY') {
|
||||
return moment(date, 'YYYYMMDD').format(strFormat);
|
||||
}
|
||||
|
||||
/**
|
||||
* DICOM Time is stored as HHmmss.SSS, where:
|
||||
* HH 24 hour time:
|
||||
@@ -71,3 +62,5 @@ export function getCompression(imageId) {
|
||||
|
||||
return 'Lossless / Uncompressed';
|
||||
}
|
||||
|
||||
export { formatDICOMDate };
|
||||
@@ -31,7 +31,7 @@ export const ExportSegmentationSubMenuItem: React.FC<ExportSegmentationSubMenuIt
|
||||
allowExport,
|
||||
actions,
|
||||
}) => {
|
||||
const { t } = useTranslation('SegmentationTable');
|
||||
const { t } = useTranslation('SegmentationPanel');
|
||||
|
||||
return (
|
||||
<DropdownMenuSub>
|
||||
|
||||
@@ -8,9 +8,11 @@ import {
|
||||
DropdownMenuItem,
|
||||
Icons,
|
||||
} from '@ohif/ui-next';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export function MeasumentsMenu(props) {
|
||||
const { group, classNames } = props;
|
||||
const { t } = useTranslation('MeasurementTable');
|
||||
if (!group.items?.length) {
|
||||
console.log('No items to iterate', group.items);
|
||||
return null;
|
||||
@@ -44,7 +46,7 @@ export function MeasumentsMenu(props) {
|
||||
className={`h-6 w-6 transition-opacity ${
|
||||
isSelected || !isVisible ? 'opacity-100' : 'opacity-50 group-hover:opacity-100'
|
||||
}`}
|
||||
aria-label={isVisible ? 'Hide' : 'Show'}
|
||||
aria-label={isVisible ? t('Hide') : t('Show')}
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
onAction(e, ['jumpToMeasurement', 'toggleVisibilityMeasurement']);
|
||||
@@ -70,7 +72,7 @@ export function MeasumentsMenu(props) {
|
||||
<DropdownMenuContent align="end">
|
||||
<DropdownMenuItem onClick={e => onAction(e, 'removeMeasurement')}>
|
||||
<Icons.Delete className="text-foreground" />
|
||||
<span className="pl-2">Delete</span>
|
||||
<span className="pl-2">{t('Delete')}</span>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Switch } from '@ohif/ui-next';
|
||||
import { useSystem } from '@ohif/core';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export default function SegmentationToolConfig() {
|
||||
const { commandsManager } = useSystem();
|
||||
const { t } = useTranslation('SegmentationPanel');
|
||||
|
||||
// Get initial states based on current configuration
|
||||
const [previewEdits, setPreviewEdits] = useState(false);
|
||||
@@ -38,7 +40,7 @@ export default function SegmentationToolConfig() {
|
||||
checked={previewEdits}
|
||||
onCheckedChange={handlePreviewEditsChange}
|
||||
/>
|
||||
<span className="text-foreground text-base">Preview edits before creating</span>
|
||||
<span className="text-foreground text-base">{t('Preview edits before creating')}</span>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
@@ -46,7 +48,7 @@ export default function SegmentationToolConfig() {
|
||||
checked={useCenterAsSegmentIndex}
|
||||
onCheckedChange={handleUseCenterAsSegmentIndexChange}
|
||||
/>
|
||||
<span className="text-foreground text-base">Use center as segment index</span>
|
||||
<span className="text-foreground text-base">{t('Use center as segment index')}</span>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
@@ -54,7 +56,7 @@ export default function SegmentationToolConfig() {
|
||||
checked={toggleSegmentEnabled}
|
||||
onCheckedChange={handleToggleSegmentEnabledChange}
|
||||
/>
|
||||
<span className="text-foreground text-base">Hover on segment border to activate</span>
|
||||
<span className="text-foreground text-base">{t('Hover on segment border to activate')}</span>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
@@ -62,7 +64,7 @@ export default function SegmentationToolConfig() {
|
||||
checked={segmentLabelEnabled}
|
||||
onCheckedChange={handleSegmentLabelEnabledChange}
|
||||
/>
|
||||
<span className="text-foreground text-base">Show segment name on hover</span>
|
||||
<span className="text-foreground text-base">{t('Show segment name on hover')}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import React from 'react';
|
||||
import { Button, Icons } from '@ohif/ui-next';
|
||||
import { useSystem } from '@ohif/core';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export function StudyMeasurementsActions({ items, StudyInstanceUID, measurementFilter, actions }) {
|
||||
const { commandsManager } = useSystem();
|
||||
const { t } = useTranslation('MeasurementTable');
|
||||
const disabled = !items?.length;
|
||||
|
||||
if (disabled) {
|
||||
@@ -45,7 +47,7 @@ export function StudyMeasurementsActions({ items, StudyInstanceUID, measurementF
|
||||
}}
|
||||
>
|
||||
<Icons.Add />
|
||||
Create SR
|
||||
{t('Create SR')}
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
@@ -63,7 +65,7 @@ export function StudyMeasurementsActions({ items, StudyInstanceUID, measurementF
|
||||
}}
|
||||
>
|
||||
<Icons.Delete />
|
||||
Delete
|
||||
{t('Delete')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+6
-4
@@ -14,6 +14,7 @@ import {
|
||||
Switch,
|
||||
} from '@ohif/ui-next';
|
||||
import { useSystem } from '@ohif/core';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { useViewportDisplaySets } from '../../hooks/useViewportDisplaySets';
|
||||
import SelectItemWithModality from '../SelectItemWithModality';
|
||||
@@ -21,6 +22,7 @@ import { useViewportRendering } from '../../hooks';
|
||||
|
||||
function ViewportDataOverlayMenu({ viewportId }: withAppTypes<{ viewportId: string }>) {
|
||||
const { commandsManager, servicesManager } = useSystem();
|
||||
const { t } = useTranslation();
|
||||
const [pendingForegrounds, setPendingForegrounds] = useState<string[]>([]);
|
||||
const [pendingSegmentations, setPendingSegmentations] = useState<string[]>([]);
|
||||
const { toggleColorbar } = useViewportRendering(viewportId);
|
||||
@@ -230,7 +232,7 @@ function ViewportDataOverlayMenu({ viewportId }: withAppTypes<{ viewportId: stri
|
||||
disabled={potentialForegroundDisplaySets.length === 0}
|
||||
>
|
||||
<Icons.Plus className="h-4 w-4" />
|
||||
Foreground
|
||||
{t('Common:Foreground')}
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
@@ -242,7 +244,7 @@ function ViewportDataOverlayMenu({ viewportId }: withAppTypes<{ viewportId: stri
|
||||
dataCY={`AddSegmentationDataOverlay-${viewportId}`}
|
||||
>
|
||||
<Icons.Plus className="h-4 w-4" />
|
||||
Segmentation
|
||||
{t('Tools:Segmentation')}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -320,7 +322,7 @@ function ViewportDataOverlayMenu({ viewportId }: withAppTypes<{ viewportId: stri
|
||||
onValueChange={value => handlePendingSegmentationSelection(pendingId, value)}
|
||||
>
|
||||
<SelectTrigger className="flex-1">
|
||||
<SelectValue placeholder="SELECT A SEGMENTATION" />
|
||||
<SelectValue placeholder={t('Common:SELECT A SEGMENTATION')} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{potentialOverlayDisplaySets.map(item => (
|
||||
@@ -428,7 +430,7 @@ function ViewportDataOverlayMenu({ viewportId }: withAppTypes<{ viewportId: stri
|
||||
onValueChange={value => handlePendingForegroundSelection(pendingId, value)}
|
||||
>
|
||||
<SelectTrigger className="flex-1">
|
||||
<SelectValue placeholder="SELECT A FOREGROUND" />
|
||||
<SelectValue placeholder={t('Common:SELECT A FOREGROUND')} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{potentialForegroundDisplaySets.map(item => (
|
||||
|
||||
@@ -98,7 +98,7 @@ export function Colormap({ viewportId }: { viewportId?: string } = {}): ReactEle
|
||||
{colormaps.map((colormap, index) => (
|
||||
<AllInOneMenu.Item
|
||||
key={index}
|
||||
label={colormap.description}
|
||||
label={t(`Colormaps:${colormap.Name}`, { defaultValue: colormap.Name })}
|
||||
useIconSpace={false}
|
||||
onClick={() => {
|
||||
setCurrentColormap(colormap);
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { ReactElement, useState, useEffect, useCallback } from 'react';
|
||||
import { VolumeLightingProps } from '../../types/ViewportPresets';
|
||||
import { Numeric } from '@ohif/ui-next';
|
||||
import { useSystem } from '@ohif/core';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export function VolumeLighting({ viewportId, hasShade }: VolumeLightingProps): ReactElement {
|
||||
const { servicesManager, commandsManager } = useSystem();
|
||||
@@ -11,6 +12,7 @@ export function VolumeLighting({ viewportId, hasShade }: VolumeLightingProps): R
|
||||
diffuse: null,
|
||||
specular: null,
|
||||
});
|
||||
const { t } = useTranslation('WindowLevelActionMenu');
|
||||
|
||||
// Single callback to handle all lighting property changes
|
||||
const onLightingChange = useCallback(
|
||||
@@ -45,9 +47,9 @@ export function VolumeLighting({ viewportId, hasShade }: VolumeLightingProps): R
|
||||
|
||||
// Configuration for our lighting properties
|
||||
const lightingProperties = [
|
||||
{ key: 'ambient', label: 'Ambient' },
|
||||
{ key: 'diffuse', label: 'Diffuse' },
|
||||
{ key: 'specular', label: 'Specular' },
|
||||
{ key: 'ambient', label: t('Ambient') },
|
||||
{ key: 'diffuse', label: t('Diffuse') },
|
||||
{ key: 'specular', label: t('Specular') },
|
||||
];
|
||||
|
||||
return (
|
||||
|
||||
+4
-1
@@ -5,10 +5,13 @@ import { VolumeShift } from './VolumeShift';
|
||||
import { VolumeLighting } from './VolumeLighting';
|
||||
import { VolumeShade } from './VolumeShade';
|
||||
import { useViewportRendering } from '../../hooks/useViewportRendering';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export function VolumeRenderingOptions({ viewportId }: { viewportId?: string } = {}): ReactElement {
|
||||
const { volumeRenderingQualityRange } = useViewportRendering(viewportId);
|
||||
const [hasShade, setShade] = useState(false);
|
||||
const { t } = useTranslation('WindowLevelActionMenu');
|
||||
|
||||
return (
|
||||
<AllInOneMenu.ItemPanel>
|
||||
<VolumeRenderingQuality
|
||||
@@ -17,7 +20,7 @@ export function VolumeRenderingOptions({ viewportId }: { viewportId?: string } =
|
||||
/>
|
||||
<VolumeShift viewportId={viewportId} />
|
||||
<div className="mt-2 flex h-8 !h-[20px] w-full flex-shrink-0 items-center justify-start px-2 text-base">
|
||||
<div className="text-muted-foreground text-sm">Lighting</div>
|
||||
<div className="text-muted-foreground text-sm">{t('Lighting')}</div>
|
||||
</div>
|
||||
<div className="bg-background mt-1 mb-1 h-px w-full"></div>
|
||||
<div className="hover:bg-accent flex h-8 w-full flex-shrink-0 items-center px-2 text-base hover:rounded">
|
||||
|
||||
+4
-2
@@ -4,17 +4,19 @@ import React, { ReactElement } from 'react';
|
||||
import { VolumeRenderingPresetsContent } from './VolumeRenderingPresetsContent';
|
||||
import { useSystem } from '@ohif/core';
|
||||
import { useViewportRendering } from '../../hooks/useViewportRendering';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export function VolumeRenderingPresets({ viewportId }: { viewportId?: string } = {}): ReactElement {
|
||||
const { volumeRenderingPresets } = useViewportRendering(viewportId);
|
||||
const { servicesManager } = useSystem();
|
||||
const { uiDialogService } = servicesManager.services;
|
||||
const { t } = useTranslation('WindowLevelActionMenu');
|
||||
|
||||
const onClickPresets = () => {
|
||||
uiDialogService.show({
|
||||
id: 'volume-rendering-presets',
|
||||
content: VolumeRenderingPresetsContent,
|
||||
title: 'Rendering Presets',
|
||||
title: t('Rendering Presets'),
|
||||
isDraggable: true,
|
||||
contentProps: {
|
||||
presets: volumeRenderingPresets,
|
||||
@@ -25,7 +27,7 @@ export function VolumeRenderingPresets({ viewportId }: { viewportId?: string } =
|
||||
|
||||
return (
|
||||
<AllInOneMenu.Item
|
||||
label="Rendering Presets"
|
||||
label={t('Rendering Presets')}
|
||||
icon={<Icons.VolumeRendering />}
|
||||
rightIcon={<Icons.ByName name="action-new-dialog" />}
|
||||
onClick={onClickPresets}
|
||||
|
||||
+4
-2
@@ -3,6 +3,7 @@ import React, { ReactElement, useState, useCallback } from 'react';
|
||||
import { PresetDialog } from '@ohif/ui-next';
|
||||
import { ViewportPreset, VolumeRenderingPresetsContentProps } from '../../types/ViewportPresets';
|
||||
import { useSystem } from '@ohif/core';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
interface Props extends VolumeRenderingPresetsContentProps {
|
||||
hide: () => void;
|
||||
@@ -12,6 +13,7 @@ export function VolumeRenderingPresetsContent({ presets, viewportId, hide }: Pro
|
||||
const { commandsManager } = useSystem();
|
||||
const [searchValue, setSearchValue] = useState('');
|
||||
const [selectedPreset, setSelectedPreset] = useState<ViewportPreset | null>(null);
|
||||
const { t } = useTranslation('WindowLevelActionMenu');
|
||||
|
||||
const handleSearchChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setSearchValue(event.target.value);
|
||||
@@ -41,7 +43,7 @@ export function VolumeRenderingPresetsContent({ presets, viewportId, hide }: Pro
|
||||
<PresetDialog.PresetSearch
|
||||
value={searchValue}
|
||||
onChange={handleSearchChange}
|
||||
placeholder="Search all"
|
||||
placeholder={t('Search all', 'Search all')}
|
||||
/>
|
||||
</PresetDialog.PresetFilter>
|
||||
<PresetDialog.PresetGrid>
|
||||
@@ -71,7 +73,7 @@ export function VolumeRenderingPresetsContent({ presets, viewportId, hide }: Pro
|
||||
</PresetDialog.PresetBody>
|
||||
<FooterAction className="mt-4 flex-shrink-0">
|
||||
<FooterAction.Right>
|
||||
<FooterAction.Secondary onClick={hide}>Cancel</FooterAction.Secondary>
|
||||
<FooterAction.Secondary onClick={hide}>{t('Common:Cancel')}</FooterAction.Secondary>
|
||||
</FooterAction.Right>
|
||||
</FooterAction>
|
||||
</PresetDialog>
|
||||
|
||||
+3
-1
@@ -2,6 +2,7 @@ import React, { ReactElement, useCallback, useState, useEffect } from 'react';
|
||||
import { VolumeRenderingQualityProps } from '../../types/ViewportPresets';
|
||||
import { Numeric } from '@ohif/ui-next';
|
||||
import { useSystem } from '@ohif/core';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export function VolumeRenderingQuality({
|
||||
volumeRenderingQualityRange,
|
||||
@@ -11,6 +12,7 @@ export function VolumeRenderingQuality({
|
||||
const { cornerstoneViewportService } = servicesManager.services;
|
||||
const { min, max, step } = volumeRenderingQualityRange;
|
||||
const [quality, setQuality] = useState(null);
|
||||
const { t } = useTranslation('WindowLevelActionMenu');
|
||||
|
||||
const onChange = useCallback(
|
||||
(value: number) => {
|
||||
@@ -51,7 +53,7 @@ export function VolumeRenderingQuality({
|
||||
onChange={onChange}
|
||||
>
|
||||
<div className="flex flex-row items-center">
|
||||
<Numeric.Label className="w-16">Quality</Numeric.Label>
|
||||
<Numeric.Label className="w-16">{t('Quality')}</Numeric.Label>
|
||||
<Numeric.SingleRange sliderClassName="mx-2 flex-grow" />
|
||||
</div>
|
||||
</Numeric.Container>
|
||||
|
||||
@@ -2,11 +2,13 @@ import React, { ReactElement, useCallback, useEffect, useState } from 'react';
|
||||
import { Switch } from '@ohif/ui-next';
|
||||
import { VolumeShadeProps } from '../../types/ViewportPresets';
|
||||
import { useSystem } from '@ohif/core';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export function VolumeShade({
|
||||
viewportId,
|
||||
onClickShade = bool => {},
|
||||
}: VolumeShadeProps): ReactElement {
|
||||
const { t } = useTranslation('WindowLevelActionMenu');
|
||||
const { servicesManager, commandsManager } = useSystem();
|
||||
const { cornerstoneViewportService } = servicesManager.services;
|
||||
const [shade, setShade] = useState(true);
|
||||
@@ -29,7 +31,7 @@ export function VolumeShade({
|
||||
|
||||
return (
|
||||
<>
|
||||
<span className="flex-grow">Shade</span>
|
||||
<span className="flex-grow">{t('Shade')}</span>
|
||||
<Switch
|
||||
className="ml-2 flex-shrink-0"
|
||||
key={key}
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { ReactElement, useCallback, useEffect, useState, useRef } from 'r
|
||||
import { VolumeShiftProps } from '../../types/ViewportPresets';
|
||||
import { Numeric } from '@ohif/ui-next';
|
||||
import { useSystem } from '@ohif/core';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export function VolumeShift({ viewportId }: VolumeShiftProps): ReactElement {
|
||||
const { servicesManager, commandsManager } = useSystem();
|
||||
@@ -19,6 +20,7 @@ export function VolumeShift({ viewportId }: VolumeShiftProps): ReactElement {
|
||||
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
||||
const { actor } = viewport.getActors()[0];
|
||||
const ofun = actor.getProperty().getScalarOpacity(0);
|
||||
const { t } = useTranslation('WindowLevelActionMenu');
|
||||
|
||||
useEffect(() => {
|
||||
if (isBlocking) {
|
||||
@@ -65,7 +67,7 @@ export function VolumeShift({ viewportId }: VolumeShiftProps): ReactElement {
|
||||
onMouseUp={() => setIsBlocking(false)}
|
||||
>
|
||||
<div className="flex flex-row items-center">
|
||||
<Numeric.Label className="w-16">Shift</Numeric.Label>
|
||||
<Numeric.Label className="w-16">{t('Shift')}</Numeric.Label>
|
||||
<Numeric.SingleRange sliderClassName="mx-2 flex-grow" />
|
||||
</div>
|
||||
</Numeric.Container>
|
||||
|
||||
@@ -2,8 +2,10 @@ 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 { WindowLevelPreset } from '../../types/WindowLevel';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export function WindowLevel({ viewportId }: { viewportId?: string } = {}): ReactElement {
|
||||
const { t } = useTranslation('WindowLevelActionMenu');
|
||||
const { viewportDisplaySets } = useViewportRendering(viewportId);
|
||||
const [activeDisplaySetUID, setActiveDisplaySetUID] = useState<string | undefined>(
|
||||
viewportDisplaySets?.[0]?.displaySetInstanceUID
|
||||
@@ -68,7 +70,7 @@ export function WindowLevel({ viewportId }: { viewportId?: string } = {}): React
|
||||
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}
|
||||
@@ -91,7 +93,7 @@ export function WindowLevel({ viewportId }: { viewportId?: string } = {}): React
|
||||
{windowLevelPresets.map((preset, index) => (
|
||||
<AllInOneMenu.Item
|
||||
key={index}
|
||||
label={preset.description}
|
||||
label={t(preset.description)}
|
||||
secondaryLabel={`${preset.window} / ${preset.level}`}
|
||||
useIconSpace={false}
|
||||
onClick={() => {
|
||||
|
||||
@@ -17,7 +17,7 @@ import { ExportSegmentationSubMenuItem } from '../components/ExportSegmentationS
|
||||
*/
|
||||
export const CustomDropdownMenuContent = () => {
|
||||
const { commandsManager } = useSystem();
|
||||
const { t } = useTranslation('SegmentationTable');
|
||||
const { t } = useTranslation('SegmentationPanel');
|
||||
const {
|
||||
onSegmentationAdd,
|
||||
onSegmentationRemoveFromViewport,
|
||||
|
||||
@@ -19,7 +19,7 @@ export const CustomSegmentStatisticsHeader = ({
|
||||
}: CustomSegmentStatisticsHeaderProps) => {
|
||||
const { servicesManager, commandsManager } = useSystem();
|
||||
const { segmentationService } = servicesManager.services;
|
||||
const { t } = useTranslation('SegmentationTable');
|
||||
const { t } = useTranslation('SegmentationPanel');
|
||||
|
||||
const segmentation = segmentationService.getSegmentation(segmentationId);
|
||||
const segment = segmentation.segments[segmentIndex];
|
||||
|
||||
@@ -95,6 +95,10 @@ function ViewportDownloadFormNew({
|
||||
<ImageModal.ImageSize
|
||||
width={dimensions.width.toString()}
|
||||
height={dimensions.height.toString()}
|
||||
widthLabel={t('Width')}
|
||||
heightLabel={t('Height')}
|
||||
widthPlaceholder={t('Width')}
|
||||
heightPlaceholder={t('Height')}
|
||||
onWidthChange={e => {
|
||||
onDimensionsChange({
|
||||
...dimensions,
|
||||
@@ -110,7 +114,7 @@ function ViewportDownloadFormNew({
|
||||
maxWidth={MAX_TEXTURE_SIZE.toString()}
|
||||
maxHeight={MAX_TEXTURE_SIZE.toString()}
|
||||
>
|
||||
{t('Image size')} <span className="text-muted-foreground">px</span>
|
||||
{t('Image size in pixels')}
|
||||
</ImageModal.ImageSize>
|
||||
|
||||
<ImageModal.SwitchOption
|
||||
|
||||
@@ -44,7 +44,7 @@ const getPanelModule = ({ commandsManager, servicesManager, extensionManager }:
|
||||
};
|
||||
|
||||
const wrappedPanelSegmentationWithTools = props => {
|
||||
const { t } = useTranslation('SegmentationTable');
|
||||
const { t } = useTranslation('SegmentationPanel');
|
||||
const tKey = `${props.segmentationRepresentationType ?? 'Segmentation'} tools`;
|
||||
const tValue = t(tKey);
|
||||
|
||||
@@ -99,7 +99,7 @@ const getPanelModule = ({ commandsManager, servicesManager, extensionManager }:
|
||||
name: 'panelSegmentationWithToolsLabelMap',
|
||||
iconName: 'tab-segmentation',
|
||||
iconLabel: 'Segmentation',
|
||||
label: i18n.t('SegmentationTable:Labelmap'),
|
||||
label: i18n.t('SegmentationPanel:Labelmap'),
|
||||
component: props =>
|
||||
wrappedPanelSegmentationWithTools({
|
||||
...props,
|
||||
@@ -110,7 +110,7 @@ const getPanelModule = ({ commandsManager, servicesManager, extensionManager }:
|
||||
name: 'panelSegmentationWithToolsContour',
|
||||
iconName: 'tab-contours',
|
||||
iconLabel: 'Segmentation',
|
||||
label: i18n.t('SegmentationTable:Contour'),
|
||||
label: i18n.t('SegmentationPanel:Contour'),
|
||||
component: props =>
|
||||
wrappedPanelSegmentationWithTools({
|
||||
...props,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Enums } from '@cornerstonejs/tools';
|
||||
import i18n from '@ohif/i18n';
|
||||
import { utils } from '@ohif/ui-next';
|
||||
import { ViewportDataOverlayMenuWrapper } from './components/ViewportDataOverlaySettingMenu/ViewportDataOverlayMenuWrapper';
|
||||
import { ViewportOrientationMenuWrapper } from './components/ViewportOrientationMenu/ViewportOrientationMenuWrapper';
|
||||
@@ -14,7 +15,7 @@ import AdvancedRenderingControls from './components/AdvancedRenderingControls';
|
||||
|
||||
const getDisabledState = (disabledText?: string) => ({
|
||||
disabled: true,
|
||||
disabledText: disabledText ?? 'Not available on the current viewport',
|
||||
disabledText: disabledText ?? i18n.t('Buttons:Not available on the current viewport'),
|
||||
});
|
||||
|
||||
export default function getToolbarModule({ servicesManager, extensionManager }: withAppTypes) {
|
||||
@@ -396,7 +397,9 @@ export default function getToolbarModule({ servicesManager, extensionManager }:
|
||||
);
|
||||
|
||||
if (!hasAnySupportedModality) {
|
||||
return getDisabledState(disabledText || 'Tool not available for this modality');
|
||||
return getDisabledState(
|
||||
disabledText || i18n.t('Buttons:Tool not available for this modality')
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import debounce from 'lodash.debounce';
|
||||
import { useSystem } from '@ohif/core';
|
||||
import i18n from '@ohif/i18n';
|
||||
|
||||
function mapMeasurementToDisplay(measurement, displaySetService) {
|
||||
const { referenceSeriesUID } = measurement;
|
||||
@@ -14,7 +15,8 @@ function mapMeasurementToDisplay(measurement, displaySetService) {
|
||||
const { findingSites, finding, label: baseLabel, displayText: baseDisplayText } = measurement;
|
||||
|
||||
const firstSite = findingSites?.[0];
|
||||
const label = baseLabel || finding?.text || firstSite?.text || '(empty)';
|
||||
const label =
|
||||
baseLabel || finding?.text || firstSite?.text || i18n.t('MeasurementTable:empty');
|
||||
|
||||
// Initialize displayText with the structure used in Length.ts and CobbAngle.ts
|
||||
const displayText = {
|
||||
|
||||
@@ -67,7 +67,12 @@ const CornerstoneViewportDownloadForm = ({
|
||||
return () => {
|
||||
Object.keys(toolModeAndBindings).forEach(toolName => {
|
||||
const { mode, bindings } = toolModeAndBindings[toolName];
|
||||
toolGroup.setToolMode(toolName, mode, { bindings });
|
||||
try {
|
||||
toolGroup.setToolMode(toolName, mode, { bindings });
|
||||
} catch (error) {
|
||||
// Handle errors when restoring tool mode during cleanup (e.g., when tool state is undefined)
|
||||
console.debug('Error restoring tool mode during cleanup:', toolName, error);
|
||||
}
|
||||
});
|
||||
};
|
||||
}, []);
|
||||
|
||||
Reference in new issue
Block a user