chore: update French i18n (#5561)
This commit is contained in:
parent
ba140a05f7
commit
181c0f32c5
@ -19,6 +19,7 @@ import {
|
||||
} from '@ohif/ui-next';
|
||||
import { Icons } from '@ohif/ui-next';
|
||||
import { contourSegmentation } from '@cornerstonejs/tools/utilities';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Segment } from '@cornerstonejs/tools/types';
|
||||
|
||||
const { LogicalOperation } = contourSegmentation;
|
||||
@ -60,6 +61,7 @@ function SegmentSelector({
|
||||
segments: Segment[];
|
||||
placeholder?: string;
|
||||
}) {
|
||||
const { t } = useTranslation('SegmentationPanel');
|
||||
return (
|
||||
<div className="flex justify-between gap-6">
|
||||
<div>{label}</div>
|
||||
@ -69,7 +71,7 @@ function SegmentSelector({
|
||||
value={value}
|
||||
>
|
||||
<SelectTrigger className="overflow-hidden">
|
||||
<SelectValue placeholder={placeholder} />
|
||||
<SelectValue placeholder={t(placeholder)} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{segments.map(segment => (
|
||||
@ -89,6 +91,7 @@ function SegmentSelector({
|
||||
function LogicalContourOperationOptions() {
|
||||
const { servicesManager } = useSystem();
|
||||
const { segmentationService } = servicesManager.services;
|
||||
const { t } = useTranslation('SegmentationPanel');
|
||||
const { segmentationsWithRepresentations } = useActiveViewportSegmentationRepresentations();
|
||||
|
||||
const activeRepresentation = segmentationsWithRepresentations?.find(
|
||||
@ -184,7 +187,7 @@ function LogicalContourOperationOptions() {
|
||||
})}
|
||||
</TabsList>
|
||||
</Tabs>
|
||||
<div>{operation.label}</div>
|
||||
<div>{t(operation.label)}</div>
|
||||
</div>
|
||||
<div className="bg-primary-dark flex h-[62px] w-[88px] items-center justify-center rounded-lg">
|
||||
<Icons.ByName name={operation.helperIcon}></Icons.ByName>
|
||||
@ -210,7 +213,7 @@ function LogicalContourOperationOptions() {
|
||||
applyLogicalContourOperation();
|
||||
}}
|
||||
>
|
||||
{operation.label}
|
||||
{t(operation.label)}
|
||||
</Button>
|
||||
</div>
|
||||
<Separator className="bg-input mt-2 h-[1px]" />
|
||||
@ -221,7 +224,7 @@ function LogicalContourOperationOptions() {
|
||||
onCheckedChange={setCreateNewSegment}
|
||||
></Switch>
|
||||
<Label htmlFor="logical-contour-operations-create-new-segment-switch">
|
||||
Create a new segment
|
||||
{t('Create a new segment')}
|
||||
</Label>
|
||||
</div>
|
||||
<div className="pl-9">
|
||||
@ -230,7 +233,7 @@ function LogicalContourOperationOptions() {
|
||||
disabled={!createNewSegment}
|
||||
id="logical-contour-operations-create-new-segment-input"
|
||||
type="text"
|
||||
placeholder="New segment name"
|
||||
placeholder={t('New segment name')}
|
||||
value={newSegmentName}
|
||||
onChange={e => setNewSegmentName(e.target.value)}
|
||||
/>
|
||||
|
||||
@ -1,16 +1,18 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Button, Input, Label, Separator } from '@ohif/ui-next';
|
||||
import { useRunCommand } from '@ohif/core';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
function SimplifyContourOptions() {
|
||||
const [areaThreshold, setAreaThreshold] = useState(10);
|
||||
|
||||
const runCommand = useRunCommand();
|
||||
const { t } = useTranslation('SegmentationPanel');
|
||||
|
||||
return (
|
||||
<div className="flex w-auto w-[252px] flex-col gap-[8px] text-base font-normal leading-none">
|
||||
<div className="flex w-auto flex-col gap-[10px] text-base font-normal leading-none">
|
||||
<div>Fill contour holes</div>
|
||||
<div>{t('Fill contour holes')}</div>
|
||||
<Button
|
||||
className="border-primary/60 border"
|
||||
variant="ghost"
|
||||
@ -18,18 +20,18 @@ function SimplifyContourOptions() {
|
||||
runCommand('removeContourHoles');
|
||||
}}
|
||||
>
|
||||
Fill Holes
|
||||
{t('Fill Holes')}
|
||||
</Button>
|
||||
<Separator className="bg-input mt-[20px] h-[1px]" />
|
||||
</div>
|
||||
<div className="flex w-auto flex-col gap-[10px] text-base font-normal leading-none">
|
||||
<div>Remove Small Contours</div>
|
||||
<div>{t('Remove Small Contours')}</div>
|
||||
<div className="flex items-center gap-2 self-end">
|
||||
<Label
|
||||
htmlFor="simplify-contour-options"
|
||||
className="text-muted-foreground"
|
||||
>
|
||||
Area Threshold
|
||||
{t('Area Threshold')}
|
||||
</Label>
|
||||
<Input
|
||||
id="simplify-contour-options"
|
||||
@ -48,12 +50,12 @@ function SimplifyContourOptions() {
|
||||
});
|
||||
}}
|
||||
>
|
||||
Remove Small Contours
|
||||
{t('Remove Small Contours')}
|
||||
</Button>
|
||||
<Separator className="bg-input mt-[20px] h-[1px]" />
|
||||
</div>
|
||||
<div className="flex w-auto flex-col gap-[10px] text-base font-normal leading-none">
|
||||
<div>Create New Segment from Holes</div>
|
||||
<div>{t('Create New Segment from Holes')}</div>
|
||||
<Button
|
||||
className="border-primary/60 border"
|
||||
variant="ghost"
|
||||
@ -61,7 +63,7 @@ function SimplifyContourOptions() {
|
||||
runCommand('convertContourHoles');
|
||||
}}
|
||||
>
|
||||
Create New Segment
|
||||
{t('Create New Segment')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,14 +1,16 @@
|
||||
import React from 'react';
|
||||
import { Button, Separator } from '@ohif/ui-next';
|
||||
import { useRunCommand } from '@ohif/core';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
function SmoothContoursOptions() {
|
||||
const runCommand = useRunCommand();
|
||||
const { t } = useTranslation('SegmentationPanel');
|
||||
|
||||
return (
|
||||
<div className="flex w-auto w-[245px] flex-col gap-[8px] text-base font-normal leading-none">
|
||||
<div className="flex w-auto flex-col gap-[10px] text-base font-normal leading-none">
|
||||
<div>Smooth all edges</div>
|
||||
<div>{t('Smooth all edges')}</div>
|
||||
<Button
|
||||
className="border-primary/60 border"
|
||||
variant="ghost"
|
||||
@ -16,12 +18,12 @@ function SmoothContoursOptions() {
|
||||
runCommand('smoothContours');
|
||||
}}
|
||||
>
|
||||
Smooth Edges
|
||||
{t('Smooth Edges')}
|
||||
</Button>
|
||||
<Separator className="bg-input mt-[20px] h-[1px]" />
|
||||
</div>
|
||||
<div className="flex w-auto flex-col gap-[10px] text-base font-normal leading-none">
|
||||
<div>Remove extra points</div>
|
||||
<div>{t('Remove extra points')}</div>
|
||||
<Button
|
||||
className="border-primary/60 border"
|
||||
variant="ghost"
|
||||
@ -29,7 +31,7 @@ function SmoothContoursOptions() {
|
||||
runCommand('decimateContours');
|
||||
}}
|
||||
>
|
||||
Remove Points
|
||||
{t('Remove Points')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { utilities as cstUtils } from '@cornerstonejs/tools';
|
||||
import i18n from '@ohif/i18n';
|
||||
import { useUIStateStore } from '@ohif/extension-default';
|
||||
|
||||
import LogicalContourOperationsOptions from './components/LogicalContourOperationsOptions';
|
||||
@ -46,7 +47,7 @@ export function getToolbarModule({ servicesManager }: withAppTypes) {
|
||||
if (!segmentations?.length) {
|
||||
return {
|
||||
disabled: true,
|
||||
disabledText: 'No segmentations available',
|
||||
disabledText: i18n.t('SegmentationPanel:No segmentations available'),
|
||||
};
|
||||
}
|
||||
|
||||
@ -73,7 +74,7 @@ export function getToolbarModule({ servicesManager }: withAppTypes) {
|
||||
if (!segmentations?.length) {
|
||||
return {
|
||||
disabled: true,
|
||||
disabledText: disabledText ?? 'No segmentations available',
|
||||
disabledText: disabledText ?? i18n.t('SegmentationPanel:No segmentations available'),
|
||||
};
|
||||
}
|
||||
|
||||
@ -81,7 +82,7 @@ export function getToolbarModule({ servicesManager }: withAppTypes) {
|
||||
if (!Object.keys(activeSegmentation.segments).length) {
|
||||
return {
|
||||
disabled: true,
|
||||
disabledText: 'Add segment to enable this tool',
|
||||
disabledText: i18n.t('SegmentationPanel:Add segment to enable this tool'),
|
||||
};
|
||||
}
|
||||
|
||||
@ -90,7 +91,7 @@ export function getToolbarModule({ servicesManager }: withAppTypes) {
|
||||
if (!toolGroup) {
|
||||
return {
|
||||
disabled: true,
|
||||
disabledText: disabledText ?? 'Not available on the current viewport',
|
||||
disabledText: disabledText ?? i18n.t('SegmentationPanel:Not available on the current viewport'),
|
||||
};
|
||||
}
|
||||
|
||||
@ -106,7 +107,7 @@ export function getToolbarModule({ servicesManager }: withAppTypes) {
|
||||
if (!toolGroup.hasTool(toolName) && !toolNames) {
|
||||
return {
|
||||
disabled: true,
|
||||
disabledText: disabledText ?? 'Not available on the current viewport',
|
||||
disabledText: disabledText ?? i18n.t('SegmentationPanel:Not available on the current viewport'),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@ function getPanelModule({ commandsManager, extensionManager, servicesManager, co
|
||||
<>
|
||||
<Toolbox
|
||||
buttonSectionId={toolbarService.sections.dynamicToolbox}
|
||||
title="Threshold Tools"
|
||||
title="Buttons:Threshold Tools"
|
||||
/>
|
||||
<PanelSegmentation
|
||||
servicesManager={servicesManager}
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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 (
|
||||
|
||||
@ -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,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}
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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);
|
||||
}
|
||||
});
|
||||
};
|
||||
}, []);
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
import React from 'react';
|
||||
import { AboutModal } from '@ohif/ui-next';
|
||||
import detect from 'browser-detect';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
function AboutModalDefault() {
|
||||
const { t } = useTranslation('AboutModal');
|
||||
const { os, version, name } = detect();
|
||||
const browser = `${name[0].toUpperCase()}${name.substr(1)} ${version}`;
|
||||
const versionNumber = process.env.VERSION_NUMBER;
|
||||
@ -18,11 +20,11 @@ function AboutModalDefault() {
|
||||
|
||||
<AboutModal.Body>
|
||||
<AboutModal.DetailItem
|
||||
label="Commit Hash"
|
||||
label={t('Commit Hash')}
|
||||
value={commitHash}
|
||||
/>
|
||||
<AboutModal.DetailItem
|
||||
label="Current Browser & OS"
|
||||
label={t('Current Browser & OS')}
|
||||
value={`${browser}, ${os}`}
|
||||
/>
|
||||
<AboutModal.SocialItem
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import i18n from '@ohif/i18n';
|
||||
|
||||
function waitForElement(selector, maxAttempts = 20, interval = 25) {
|
||||
return new Promise(resolve => {
|
||||
let attempts = 0;
|
||||
@ -23,8 +25,8 @@ export default {
|
||||
steps: [
|
||||
{
|
||||
id: 'scroll',
|
||||
title: 'Scrolling Through Images',
|
||||
text: 'You can scroll through the images using the mouse wheel or scrollbar.',
|
||||
title: i18n.t('Onboarding:Scrolling Through Images'),
|
||||
text: i18n.t('Onboarding:You can scroll through the images using the mouse wheel or scrollbar.'),
|
||||
attachTo: {
|
||||
element: '.viewport-element',
|
||||
on: 'top',
|
||||
@ -37,8 +39,8 @@ export default {
|
||||
},
|
||||
{
|
||||
id: 'zoom',
|
||||
title: 'Zooming In and Out',
|
||||
text: 'You can zoom the images using the right click.',
|
||||
title: i18n.t('Onboarding:Zooming In and Out'),
|
||||
text: i18n.t('Onboarding:You can zoom the images using the right click.'),
|
||||
attachTo: {
|
||||
element: '.viewport-element',
|
||||
on: 'left',
|
||||
@ -51,8 +53,8 @@ export default {
|
||||
},
|
||||
{
|
||||
id: 'pan',
|
||||
title: 'Panning the Image',
|
||||
text: 'You can pan the images using the middle click.',
|
||||
title: i18n.t('Onboarding:Panning the Image'),
|
||||
text: i18n.t('Onboarding:You can pan the images using the middle click.'),
|
||||
attachTo: {
|
||||
element: '.viewport-element',
|
||||
on: 'top',
|
||||
@ -65,8 +67,8 @@ export default {
|
||||
},
|
||||
{
|
||||
id: 'windowing',
|
||||
title: 'Adjusting Window Level',
|
||||
text: 'You can modify the window level using the left click.',
|
||||
title: i18n.t('Onboarding:Adjusting Window Level'),
|
||||
text: i18n.t('Onboarding:You can modify the window level using the left click.'),
|
||||
attachTo: {
|
||||
element: '.viewport-element',
|
||||
on: 'left',
|
||||
@ -79,8 +81,8 @@ export default {
|
||||
},
|
||||
{
|
||||
id: 'length',
|
||||
title: 'Using the Measurement Tools',
|
||||
text: 'You can measure the length of a region using the Length tool.',
|
||||
title: i18n.t('Onboarding:Using the Measurement Tools'),
|
||||
text: i18n.t('Onboarding:You can measure the length of a region using the Length tool.'),
|
||||
attachTo: {
|
||||
element: '[data-cy="MeasurementTools-split-button-primary"]',
|
||||
on: 'bottom',
|
||||
@ -90,12 +92,12 @@ export default {
|
||||
event: 'click',
|
||||
},
|
||||
beforeShowPromise: () =>
|
||||
waitForElement('[data-cy="MeasurementTools-split-button-primary]'),
|
||||
waitForElement('[data-cy="MeasurementTools-split-button-primary"]'),
|
||||
},
|
||||
{
|
||||
id: 'drawAnnotation',
|
||||
title: 'Drawing Length Annotations',
|
||||
text: 'Use the length tool on the viewport to measure the length of a region.',
|
||||
title: i18n.t('Onboarding:Drawing Length Annotations'),
|
||||
text: i18n.t('Onboarding:Use the length tool on the viewport to measure the length of a region.'),
|
||||
attachTo: {
|
||||
element: '.viewport-element',
|
||||
on: 'right',
|
||||
@ -108,8 +110,8 @@ export default {
|
||||
},
|
||||
{
|
||||
id: 'trackMeasurement',
|
||||
title: 'Tracking Measurements in the Panel',
|
||||
text: 'Click yes to track the measurements in the measurement panel.',
|
||||
title: i18n.t('Onboarding:Tracking Measurements in the Panel'),
|
||||
text: i18n.t('Onboarding:Click yes to track the measurements in the measurement panel.'),
|
||||
attachTo: {
|
||||
element: '[data-cy="prompt-begin-tracking-yes-btn"]',
|
||||
on: 'bottom',
|
||||
@ -122,8 +124,8 @@ export default {
|
||||
},
|
||||
{
|
||||
id: 'openMeasurementPanel',
|
||||
title: 'Opening the Measurements Panel',
|
||||
text: 'Click the measurements button to open the measurements panel.',
|
||||
title: i18n.t('Onboarding:Opening the Measurements Panel'),
|
||||
text: i18n.t('Onboarding:Click the measurements button to open the measurements panel.'),
|
||||
attachTo: {
|
||||
element: '#trackedMeasurements-btn',
|
||||
on: 'left-start',
|
||||
@ -136,8 +138,8 @@ export default {
|
||||
},
|
||||
{
|
||||
id: 'scrollAwayFromMeasurement',
|
||||
title: 'Scrolling Away from a Measurement',
|
||||
text: 'Scroll the images using the mouse wheel away from the measurement.',
|
||||
title: i18n.t('Onboarding:Scrolling Away from a Measurement'),
|
||||
text: i18n.t('Onboarding:Scroll the images using the mouse wheel away from the measurement.'),
|
||||
attachTo: {
|
||||
element: '.viewport-element',
|
||||
on: 'left',
|
||||
@ -150,8 +152,8 @@ export default {
|
||||
},
|
||||
{
|
||||
id: 'jumpToMeasurement',
|
||||
title: 'Jumping to Measurements in the Panel',
|
||||
text: 'Click the measurement in the measurement panel to jump to it.',
|
||||
title: i18n.t('Onboarding:Jumping to Measurements in the Panel'),
|
||||
text: i18n.t('Onboarding:Click the measurement in the measurement panel to jump to it.'),
|
||||
attachTo: {
|
||||
element: '[data-cy="data-row"]',
|
||||
on: 'left-start',
|
||||
@ -164,8 +166,8 @@ export default {
|
||||
},
|
||||
{
|
||||
id: 'changeLayout',
|
||||
title: 'Changing Layout',
|
||||
text: 'You can change the layout of the viewer using the layout button.',
|
||||
title: i18n.t('Onboarding:Changing Layout'),
|
||||
text: i18n.t('Onboarding:You can change the layout of the viewer using the layout button.'),
|
||||
attachTo: {
|
||||
element: '[data-cy="Layout"]',
|
||||
on: 'bottom',
|
||||
@ -178,8 +180,8 @@ export default {
|
||||
},
|
||||
{
|
||||
id: 'selectLayout',
|
||||
title: 'Selecting the MPR Layout',
|
||||
text: 'Select the MPR layout to view the images in MPR mode.',
|
||||
title: i18n.t('Onboarding:Selecting the MPR Layout'),
|
||||
text: i18n.t('Onboarding:Select the MPR layout to view the images in MPR mode.'),
|
||||
attachTo: {
|
||||
element: '[data-cy="MPR"]',
|
||||
on: 'left-start',
|
||||
@ -196,7 +198,7 @@ export default {
|
||||
defaultStepOptions: {
|
||||
buttons: [
|
||||
{
|
||||
text: 'Skip all',
|
||||
text: i18n.t('Onboarding:Skip all'),
|
||||
action() {
|
||||
this.complete();
|
||||
},
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useMemo, useState, useEffect } from 'react';
|
||||
import { useSystem, hotkeys as hotkeysModule } from '@ohif/core';
|
||||
import { UserPreferencesModal, FooterAction } from '@ohif/ui-next';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -19,14 +19,40 @@ interface HotkeyDefinitions {
|
||||
|
||||
function UserPreferencesModalDefault({ hide }: { hide: () => void }) {
|
||||
const { hotkeysManager } = useSystem();
|
||||
const { t } = useTranslation('UserPreferencesModal');
|
||||
const { t, i18n: i18nextInstance } = useTranslation('UserPreferencesModal');
|
||||
|
||||
const { hotkeyDefinitions = {}, hotkeyDefaults = {} } = hotkeysManager;
|
||||
|
||||
const fallbackHotkeyDefinitions = useMemo(
|
||||
() =>
|
||||
hotkeysManager.getValidHotkeyDefinitions(
|
||||
hotkeysModule.defaults.hotkeyBindings
|
||||
) as HotkeyDefinitions,
|
||||
[hotkeysManager]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!Object.keys(hotkeyDefaults).length) {
|
||||
hotkeysManager.setDefaultHotKeys(hotkeysModule.defaults.hotkeyBindings);
|
||||
}
|
||||
|
||||
if (!Object.keys(hotkeyDefinitions).length) {
|
||||
hotkeysManager.setHotkeys(fallbackHotkeyDefinitions);
|
||||
}
|
||||
}, [hotkeysManager, hotkeyDefaults, hotkeyDefinitions, fallbackHotkeyDefinitions]);
|
||||
|
||||
const resolvedHotkeyDefaults = Object.keys(hotkeyDefaults).length
|
||||
? (hotkeyDefaults as HotkeyDefinitions)
|
||||
: fallbackHotkeyDefinitions;
|
||||
|
||||
const initialHotkeyDefinitions = Object.keys(hotkeyDefinitions).length
|
||||
? (hotkeyDefinitions as HotkeyDefinitions)
|
||||
: resolvedHotkeyDefaults;
|
||||
|
||||
const currentLanguage = currentLanguageFn();
|
||||
|
||||
const [state, setState] = useState({
|
||||
hotkeyDefinitions: hotkeyDefinitions as HotkeyDefinitions,
|
||||
hotkeyDefinitions: initialHotkeyDefinitions,
|
||||
languageValue: currentLanguage.value,
|
||||
});
|
||||
|
||||
@ -51,12 +77,52 @@ function UserPreferencesModalDefault({ hide }: { hide: () => void }) {
|
||||
setState(state => ({
|
||||
...state,
|
||||
languageValue: defaultLanguage.value,
|
||||
hotkeyDefinitions: hotkeyDefaults as HotkeyDefinitions,
|
||||
hotkeyDefinitions: resolvedHotkeyDefaults,
|
||||
}));
|
||||
|
||||
hotkeysManager.restoreDefaultBindings();
|
||||
};
|
||||
|
||||
const displayNames = React.useMemo(() => {
|
||||
if (typeof Intl === 'undefined' || typeof Intl.DisplayNames !== 'function') {
|
||||
return null;
|
||||
}
|
||||
|
||||
const locales = [state.languageValue, currentLanguage.value, i18nextInstance.language, 'en'];
|
||||
const uniqueLocales = Array.from(new Set(locales.filter(Boolean)));
|
||||
|
||||
try {
|
||||
return new Intl.DisplayNames(uniqueLocales, { type: 'language', fallback: 'none' });
|
||||
} catch (error) {
|
||||
console.warn('Intl.DisplayNames not supported for locales', uniqueLocales, error);
|
||||
}
|
||||
|
||||
return null;
|
||||
}, [state.languageValue, currentLanguage.value, i18nextInstance.language]);
|
||||
|
||||
const getLanguageLabel = React.useCallback(
|
||||
(languageValue: string, fallbackLabel: string) => {
|
||||
const translationKey = `LanguageName.${languageValue}`;
|
||||
if (i18nextInstance.exists(translationKey, { ns: 'UserPreferencesModal' })) {
|
||||
return t(translationKey);
|
||||
}
|
||||
|
||||
if (displayNames) {
|
||||
try {
|
||||
const localized = displayNames.of(languageValue);
|
||||
if (localized && localized.toLowerCase() !== languageValue.toLowerCase()) {
|
||||
return localized.charAt(0).toUpperCase() + localized.slice(1);
|
||||
}
|
||||
} catch (error) {
|
||||
console.debug(`Unable to resolve display name for ${languageValue}`, error);
|
||||
}
|
||||
}
|
||||
|
||||
return fallbackLabel;
|
||||
},
|
||||
[displayNames, i18nextInstance, t]
|
||||
);
|
||||
|
||||
return (
|
||||
<UserPreferencesModal>
|
||||
<UserPreferencesModal.Body>
|
||||
@ -79,7 +145,7 @@ function UserPreferencesModalDefault({ hide }: { hide: () => void }) {
|
||||
key={lang.value}
|
||||
value={lang.value}
|
||||
>
|
||||
{lang.label}
|
||||
{getLanguageLabel(lang.value, lang.label)}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
@ -120,6 +186,9 @@ function UserPreferencesModalDefault({ hide }: { hide: () => void }) {
|
||||
onClick={() => {
|
||||
if (state.languageValue !== currentLanguage.value) {
|
||||
i18n.changeLanguage(state.languageValue);
|
||||
// Force page reload after language change to ensure all translations are applied
|
||||
window.location.reload();
|
||||
return; // Exit early since we're reloading
|
||||
}
|
||||
hotkeysManager.setHotkeys(state.hotkeyDefinitions);
|
||||
hotkeysModule.stopRecord();
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { Types } from '@ohif/core';
|
||||
import i18n from 'i18next';
|
||||
|
||||
const defaultDisplaySetSelector = {
|
||||
studyMatchingRules: [
|
||||
@ -113,8 +114,8 @@ const priorViewport1 = {
|
||||
*/
|
||||
const hpMNCompare: Types.HangingProtocol.Protocol = {
|
||||
id: '@ohif/hpCompare',
|
||||
description: 'Compare two studies in various layouts',
|
||||
name: 'Compare Two Studies',
|
||||
description: i18n.t('Hps:Compare two studies in various layouts'),
|
||||
name: i18n.t('Hps:Compare Two Studies'),
|
||||
numberOfPriorsReferenced: 1,
|
||||
protocolMatchingRules: [
|
||||
{
|
||||
|
||||
@ -8,6 +8,7 @@ import {
|
||||
RMLOPrior,
|
||||
LMLOPrior,
|
||||
} from './utils/mammoDisplaySetSelector';
|
||||
import i18n from 'i18next';
|
||||
|
||||
const rightDisplayArea = {
|
||||
storeAsInitialCamera: true,
|
||||
@ -30,7 +31,7 @@ const leftDisplayArea = {
|
||||
const hpMammography = {
|
||||
id: '@ohif/hpMammo',
|
||||
hasUpdatedPriorsInformation: false,
|
||||
name: 'Mammography Breast Screening',
|
||||
name: i18n.t('Hps:Mammography Breast Screening'),
|
||||
protocolMatchingRules: [
|
||||
{
|
||||
id: 'Mammography',
|
||||
|
||||
@ -3,7 +3,8 @@ import classnames from 'classnames';
|
||||
|
||||
import listComponentGenerator from './listComponentGenerator';
|
||||
import './ViewportOverlay.css';
|
||||
import { formatDICOMDate, formatDICOMTime, formatNumberPrecision } from './utils';
|
||||
import { formatDICOMDate } from '@ohif/ui-next';
|
||||
import { formatDICOMTime, formatNumberPrecision } from './utils';
|
||||
import { utils } from '@ohif/core';
|
||||
|
||||
const { formatPN } = utils;
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import moment from 'moment';
|
||||
import i18n from 'i18next';
|
||||
import * as cornerstone from '@cornerstonejs/core';
|
||||
import { formatDICOMDate } from '@ohif/ui-next';
|
||||
|
||||
/**
|
||||
* Checks if value is valid.
|
||||
@ -24,17 +26,6 @@ export function formatNumberPrecision(number, precision) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 };
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import moment from 'moment';
|
||||
|
||||
/**
|
||||
* Formats DICOM date.
|
||||
* Re-exported from @ohif/ui-next for backward compatibility.
|
||||
*
|
||||
* @param {string} date
|
||||
* @param {string} strFormat
|
||||
*/
|
||||
export default function formatDICOMDate(date, strFormat = 'MMM D, YYYY') {
|
||||
return moment(date, 'YYYYMMDD').format(strFormat);
|
||||
}
|
||||
import { formatDICOMDate } from '@ohif/ui-next';
|
||||
|
||||
export { formatDICOMDate };
|
||||
export default formatDICOMDate;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import formatDICOMPatientName from './formatDICOMPatientName';
|
||||
import formatDICOMDate from './formatDICOMDate';
|
||||
import { formatDICOMDate } from '@ohif/ui-next';
|
||||
import formatDICOMTime from './formatDICOMTime';
|
||||
import formatNumberPrecision from './formatNumberPrecision';
|
||||
import isValidNumber from './isValidNumber';
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import areaOfPolygon from './areaOfPolygon';
|
||||
|
||||
import { PubSubService } from '@ohif/core';
|
||||
import i18n from '@ohif/i18n';
|
||||
|
||||
const EVENTS = {
|
||||
LABEL_UPDATED: 'labelUpdated',
|
||||
@ -168,7 +169,8 @@ class RoiAnnotation extends PubSubService {
|
||||
* @returns {String} Text with geometry type and label
|
||||
*/
|
||||
getDetailedLabel() {
|
||||
const label = this.label ? `${this.label}` : '(empty)';
|
||||
const translatedEmpty = i18n?.t('MeasurementTable:empty') || '(empty)';
|
||||
const label = this.label ? `${this.label}` : translatedEmpty;
|
||||
return label;
|
||||
}
|
||||
|
||||
|
||||
@ -253,10 +253,10 @@ export default function PanelPetSUV() {
|
||||
<Button
|
||||
variant="default"
|
||||
size="sm"
|
||||
className="w-28 self-end"
|
||||
className="self-end px-4"
|
||||
onClick={updateMetadata}
|
||||
>
|
||||
Reload Data
|
||||
{t('Reload Data')}
|
||||
</Button>
|
||||
</div>
|
||||
</PanelSection.Content>
|
||||
|
||||
@ -14,14 +14,14 @@ import { useTranslation } from 'react-i18next';
|
||||
export const ROI_STAT = 'roi_stat';
|
||||
const RANGE = 'range';
|
||||
|
||||
const options = [
|
||||
{ value: ROI_STAT, label: 'Max', placeHolder: 'Max' },
|
||||
{ value: RANGE, label: 'Range', placeHolder: 'Range' },
|
||||
];
|
||||
|
||||
function ROIThresholdConfiguration({ config, dispatch, runCommand }) {
|
||||
const { t } = useTranslation('ROIThresholdConfiguration');
|
||||
|
||||
const options = [
|
||||
{ value: ROI_STAT, label: t('Max'), placeHolder: t('Max') },
|
||||
{ value: RANGE, label: t('Range'), placeHolder: t('Range') },
|
||||
];
|
||||
|
||||
const handlePercentageOfMaxSUVChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
let value = e.target.value;
|
||||
|
||||
@ -101,7 +101,7 @@ function ROIThresholdConfiguration({ config, dispatch, runCommand }) {
|
||||
<div className="mr-2 text-sm">
|
||||
<div className="flex flex-col space-y-2">
|
||||
{/* Header */}
|
||||
<Label>Lower & Upper Ranges</Label>
|
||||
<Label>{t('Lower & Upper Ranges')}</Label>
|
||||
|
||||
{/* CT Row */}
|
||||
<div className="flex items-center">
|
||||
|
||||
@ -6,6 +6,7 @@ import ROIThresholdConfiguration, {
|
||||
import * as cs3dTools from '@cornerstonejs/tools';
|
||||
import { useSystem } from '@ohif/core';
|
||||
import { useSegmentations } from '@ohif/extension-cornerstone';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const LOWER_CT_THRESHOLD_DEFAULT = -1024;
|
||||
const UPPER_CT_THRESHOLD_DEFAULT = 1024;
|
||||
@ -46,6 +47,7 @@ function RectangleROIOptions() {
|
||||
const { commandsManager } = useSystem();
|
||||
const segmentations = useSegmentations();
|
||||
const activeSegmentation = segmentations[0];
|
||||
const { t } = useTranslation('ROIThresholdConfiguration');
|
||||
|
||||
const runCommand = useCallback(
|
||||
(commandName, commandOptions = {}) => {
|
||||
@ -92,7 +94,7 @@ function RectangleROIOptions() {
|
||||
className="my-3 mr-auto w-20"
|
||||
onClick={handleROIThresholding}
|
||||
>
|
||||
Run
|
||||
{t('Run')}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@ -2,6 +2,7 @@ import React from 'react';
|
||||
import { PanelPetSUV, PanelROIThresholdExport } from './Panels';
|
||||
import { Toolbox } from '@ohif/extension-default';
|
||||
import PanelTMTV from './Panels/PanelTMTV';
|
||||
import i18n from '@ohif/i18n';
|
||||
|
||||
function getPanelModule({ commandsManager, extensionManager, servicesManager }) {
|
||||
const { toolbarService } = servicesManager.services;
|
||||
@ -14,7 +15,7 @@ function getPanelModule({ commandsManager, extensionManager, servicesManager })
|
||||
return (
|
||||
<Toolbox
|
||||
buttonSectionId={toolbarService.sections.roiThresholdToolbox}
|
||||
title="Threshold Tools"
|
||||
title={i18n.t('ROIThresholdConfiguration:Threshold Tools')}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@ -28,7 +29,7 @@ function getPanelModule({ commandsManager, extensionManager, servicesManager })
|
||||
<>
|
||||
<Toolbox
|
||||
buttonSectionId={toolbarService.sections.roiThresholdToolbox}
|
||||
title="Threshold Tools"
|
||||
title={i18n.t('ROIThresholdConfiguration:Threshold Tools')}
|
||||
/>
|
||||
<PanelTMTV
|
||||
commandsManager={commandsManager}
|
||||
|
||||
@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react';
|
||||
import { Enums as csToolsEnums, UltrasoundPleuraBLineTool } from '@cornerstonejs/tools';
|
||||
import { eventTarget, utilities } from '@cornerstonejs/core';
|
||||
import { useSystem } from '@ohif/core';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import {
|
||||
/* Layout */
|
||||
@ -29,6 +30,7 @@ import {
|
||||
* @returns The USAnnotationPanel component
|
||||
*/
|
||||
export default function USAnnotationPanel() {
|
||||
const { t } = useTranslation('USAnnotationPanel');
|
||||
const { servicesManager, commandsManager } = useSystem();
|
||||
|
||||
/** ──────────────────────────────────────────────────────
|
||||
@ -166,7 +168,7 @@ export default function USAnnotationPanel() {
|
||||
className="cursor-pointer"
|
||||
onClick={() => setDepthGuideCommand(!depthGuide)}
|
||||
>
|
||||
Depth guide toggle
|
||||
{t('Depth guide toggle')}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@ -198,7 +200,7 @@ export default function USAnnotationPanel() {
|
||||
className="cursor-pointer"
|
||||
onClick={() => setShowPleuraPercentageCommand(!showPleuraPct)}
|
||||
>
|
||||
Show pleura percentage
|
||||
{t('Show pleura percentage')}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@ -208,7 +210,7 @@ export default function USAnnotationPanel() {
|
||||
const renderSectorAnnotations = () => (
|
||||
<PanelSection.Content>
|
||||
<div className="flex flex-col gap-4 p-2">
|
||||
<Label>Sector Annotations</Label>
|
||||
<Label>{t('Sector Annotations')}</Label>
|
||||
<div className="flex items-center gap-2">
|
||||
<Tabs
|
||||
defaultValue={UltrasoundPleuraBLineTool.USPleuraBLineAnnotationType.BLINE}
|
||||
@ -216,10 +218,10 @@ export default function USAnnotationPanel() {
|
||||
>
|
||||
<TabsList>
|
||||
<TabsTrigger value={UltrasoundPleuraBLineTool.USPleuraBLineAnnotationType.PLEURA}>
|
||||
<Icons.Plus /> Pleura line
|
||||
<Icons.Plus /> {t('Pleura line')}
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value={UltrasoundPleuraBLineTool.USPleuraBLineAnnotationType.BLINE}>
|
||||
<Icons.Plus /> B-line
|
||||
<Icons.Plus /> {t('B-line')}
|
||||
</TabsTrigger>
|
||||
<Separator orientation="vertical" />
|
||||
<Separator orientation="vertical" />
|
||||
@ -239,7 +241,7 @@ export default function USAnnotationPanel() {
|
||||
}
|
||||
>
|
||||
<Icons.Delete className="text-foreground" />
|
||||
<span className="pl-2">B-line annotation</span>
|
||||
<span className="pl-2">{t('B-line annotation')}</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
onClick={() =>
|
||||
@ -247,7 +249,7 @@ export default function USAnnotationPanel() {
|
||||
}
|
||||
>
|
||||
<Icons.Delete className="text-foreground" />
|
||||
<span className="pl-2">Pleura annotation</span>
|
||||
<span className="pl-2">{t('Pleura annotation')}</span>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
@ -261,7 +263,7 @@ export default function USAnnotationPanel() {
|
||||
className="data-[state=checked]:bg-blue-500"
|
||||
/>
|
||||
<label htmlFor="show-overlay-switch" className="cursor-pointer text-blue-300">
|
||||
Show Overlay
|
||||
{t('Show Overlay')}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@ -286,7 +288,7 @@ export default function USAnnotationPanel() {
|
||||
</Button> */}
|
||||
<Button variant="ghost" onClick={() => downloadJSON()}>
|
||||
<Icons.Download className="h-5 w-5" />
|
||||
<span>JSON</span>
|
||||
<span>{t('JSON')}</span>
|
||||
</Button>
|
||||
<Button variant="ghost" onClick={() => setShowOverlayCommand(!showOverlay)}>
|
||||
{showOverlay ? <Icons.Hide className="h-5 w-5" /> : <Icons.Show className="h-5 w-5" />}
|
||||
@ -297,9 +299,9 @@ export default function USAnnotationPanel() {
|
||||
<thead>
|
||||
<tr className="border-b border-blue-900 text-blue-300">
|
||||
<th></th>
|
||||
<th className="py-2 px-3 text-left">Frame</th>
|
||||
<th className="py-2 px-3 text-center">Pleura lines</th>
|
||||
<th className="py-2 px-3 text-center">B-lines</th>
|
||||
<th className="py-2 px-3 text-left">{t('Frame')}</th>
|
||||
<th className="py-2 px-3 text-center">{t('Pleura lines')}</th>
|
||||
<th className="py-2 px-3 text-center">{t('B-lines')}</th>
|
||||
<th className="w-10"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -399,7 +401,7 @@ export default function USAnnotationPanel() {
|
||||
>
|
||||
{/* Workflow */}
|
||||
<PanelSection>
|
||||
<PanelSection.Header>Workflow</PanelSection.Header>
|
||||
<PanelSection.Header>{t('Workflow')}</PanelSection.Header>
|
||||
{renderWorkflowToggles()}
|
||||
</PanelSection>
|
||||
|
||||
@ -411,13 +413,13 @@ export default function USAnnotationPanel() {
|
||||
|
||||
{/* Annotations */}
|
||||
<PanelSection>
|
||||
<PanelSection.Header> Annotations </PanelSection.Header>
|
||||
<PanelSection.Header>{t('Annotations')}</PanelSection.Header>
|
||||
{renderSectorAnnotations()}
|
||||
</PanelSection>
|
||||
|
||||
{/* Annotated frames */}
|
||||
<PanelSection className="flex-1">
|
||||
<PanelSection.Header> Annotated Frames </PanelSection.Header>
|
||||
<PanelSection.Header>{t('Annotated Frames')}</PanelSection.Header>
|
||||
{renderAnnotatedFrames()}
|
||||
</PanelSection>
|
||||
</div>
|
||||
|
||||
@ -611,7 +611,7 @@ const toolbarButtons: Button[] = [
|
||||
commands: setToolActiveToolbar,
|
||||
evaluate: {
|
||||
name: 'evaluate.cornerstoneTool',
|
||||
disabledText: 'Select a 3D viewport to enable this tool',
|
||||
disabledText: i18n.t('Buttons:Select a 3D viewport to enable this tool'),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -655,7 +655,7 @@ const toolbarButtons: Button[] = [
|
||||
},
|
||||
evaluate: {
|
||||
name: 'evaluate.cornerstoneTool',
|
||||
disabledText: 'Select an MPR viewport to enable this tool',
|
||||
disabledText: i18n.t('Buttons:Select an MPR viewport to enable this tool'),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@ -265,13 +265,13 @@ const toolbarButtons = [
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Shape',
|
||||
name: i18n.t('Buttons:Shape'),
|
||||
type: 'radio',
|
||||
id: 'brush-mode',
|
||||
value: 'CircularBrush',
|
||||
values: [
|
||||
{ value: 'CircularBrush', label: 'Circle' },
|
||||
{ value: 'SphereBrush', label: 'Sphere' },
|
||||
{ value: 'CircularBrush', label: i18n.t('Buttons:Circle') },
|
||||
{ value: 'SphereBrush', label: i18n.t('Buttons:Sphere') },
|
||||
],
|
||||
commands: 'setToolActiveToolbar',
|
||||
},
|
||||
@ -290,7 +290,7 @@ const toolbarButtons = [
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Radius (mm)',
|
||||
name: i18n.t('Buttons:Radius (mm)'),
|
||||
id: 'eraser-radius',
|
||||
type: 'range',
|
||||
min: 0.5,
|
||||
@ -303,13 +303,13 @@ const toolbarButtons = [
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Shape',
|
||||
name: i18n.t('Buttons:Shape'),
|
||||
type: 'radio',
|
||||
id: 'eraser-mode',
|
||||
value: 'CircularEraser',
|
||||
values: [
|
||||
{ value: 'CircularEraser', label: 'Circle' },
|
||||
{ value: 'SphereEraser', label: 'Sphere' },
|
||||
{ value: 'CircularEraser', label: i18n.t('Buttons:Circle') },
|
||||
{ value: 'SphereEraser', label: i18n.t('Buttons:Sphere') },
|
||||
],
|
||||
commands: 'setToolActiveToolbar',
|
||||
},
|
||||
@ -328,7 +328,7 @@ const toolbarButtons = [
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Radius (mm)',
|
||||
name: i18n.t('Buttons:Radius (mm)'),
|
||||
id: 'threshold-radius',
|
||||
type: 'range',
|
||||
min: 0.5,
|
||||
@ -343,13 +343,13 @@ const toolbarButtons = [
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Shape',
|
||||
name: i18n.t('Buttons:Shape'),
|
||||
type: 'radio',
|
||||
id: 'eraser-mode',
|
||||
value: 'ThresholdCircularBrush',
|
||||
values: [
|
||||
{ value: 'ThresholdCircularBrush', label: 'Circle' },
|
||||
{ value: 'ThresholdSphereBrush', label: 'Sphere' },
|
||||
{ value: 'ThresholdCircularBrush', label: i18n.t('Buttons:Circle') },
|
||||
{ value: 'ThresholdSphereBrush', label: i18n.t('Buttons:Sphere') },
|
||||
],
|
||||
commands: 'setToolActiveToolbar',
|
||||
},
|
||||
@ -383,14 +383,14 @@ const toolbarButtons = [
|
||||
icon: 'icon-tool-shape',
|
||||
options: [
|
||||
{
|
||||
name: 'Shape',
|
||||
name: i18n.t('Buttons:Shape'),
|
||||
type: 'radio',
|
||||
value: 'CircleScissor',
|
||||
id: 'shape-mode',
|
||||
values: [
|
||||
{ value: 'CircleScissor', label: 'Circle' },
|
||||
{ value: 'SphereScissor', label: 'Sphere' },
|
||||
{ value: 'RectangleScissor', label: 'Rectangle' },
|
||||
{ value: 'CircleScissor', label: i18n.t('Buttons:Circle') },
|
||||
{ value: 'SphereScissor', label: i18n.t('Buttons:Sphere') },
|
||||
{ value: 'RectangleScissor', label: i18n.t('Buttons:Rectangle') },
|
||||
],
|
||||
commands: 'setToolActiveToolbar',
|
||||
},
|
||||
|
||||
@ -420,13 +420,13 @@ export const toolbarButtons: Button[] = [
|
||||
uiType: 'ohif.toolBoxButton',
|
||||
props: {
|
||||
icon: 'icon-tool-freehand-roi',
|
||||
label: 'Freehand Segmentation',
|
||||
tooltip: 'Freehand Segmentation',
|
||||
label: i18n.t('Buttons:Freehand Segmentation'),
|
||||
tooltip: i18n.t('Buttons:Freehand Segmentation'),
|
||||
evaluate: [
|
||||
{
|
||||
name: 'evaluate.cornerstone.segmentation',
|
||||
toolNames: ['PlanarFreehandContourSegmentationTool'],
|
||||
disabledText: 'Create new segmentation to enable this tool.',
|
||||
disabledText: i18n.t('Buttons:Create new segmentation to enable this tool.'),
|
||||
},
|
||||
{
|
||||
name: 'evaluate.cornerstone.hasSegmentationOfType',
|
||||
@ -457,7 +457,7 @@ export const toolbarButtons: Button[] = [
|
||||
],
|
||||
options: [
|
||||
{
|
||||
name: 'Interpolate Contours',
|
||||
name: i18n.t('Buttons:Interpolate Contours'),
|
||||
type: 'switch',
|
||||
id: 'planarFreehandInterpolateContours',
|
||||
value: false,
|
||||
@ -473,13 +473,13 @@ export const toolbarButtons: Button[] = [
|
||||
uiType: 'ohif.toolBoxButton',
|
||||
props: {
|
||||
icon: 'icon-tool-livewire',
|
||||
label: 'Livewire Contour',
|
||||
tooltip: 'Livewire Contour',
|
||||
label: i18n.t('Buttons:Livewire Contour'),
|
||||
tooltip: i18n.t('Buttons:Livewire Contour'),
|
||||
evaluate: [
|
||||
{
|
||||
name: 'evaluate.cornerstone.segmentation',
|
||||
toolNames: ['LivewireContourSegmentationTool'],
|
||||
disabledText: 'Create new segmentation to enable this tool.',
|
||||
disabledText: i18n.t('Buttons:Create new segmentation to enable this tool.'),
|
||||
},
|
||||
{
|
||||
name: 'evaluate.cornerstone.hasSegmentationOfType',
|
||||
@ -510,7 +510,7 @@ export const toolbarButtons: Button[] = [
|
||||
],
|
||||
options: [
|
||||
{
|
||||
name: 'Interpolate Contours',
|
||||
name: i18n.t('Buttons:Interpolate Contours'),
|
||||
type: 'switch',
|
||||
id: 'livewireInterpolateContours',
|
||||
value: false,
|
||||
@ -526,13 +526,13 @@ export const toolbarButtons: Button[] = [
|
||||
uiType: 'ohif.toolBoxButton',
|
||||
props: {
|
||||
icon: 'icon-tool-spline-roi',
|
||||
label: 'Spline Contour Segmentation Tool',
|
||||
tooltip: 'Spline Contour Segmentation Tool',
|
||||
label: i18n.t('Buttons:Spline Contour Segmentation Tool'),
|
||||
tooltip: i18n.t('Buttons:Spline Contour Segmentation Tool'),
|
||||
evaluate: [
|
||||
{
|
||||
name: 'evaluate.cornerstone.segmentation',
|
||||
toolNames: ['CatmullRomSplineROI', 'LinearSplineROI', 'BSplineROI'],
|
||||
disabledText: 'Create new segmentation to enable this tool.',
|
||||
disabledText: i18n.t('Buttons:Create new segmentation to enable this tool.'),
|
||||
},
|
||||
{
|
||||
name: 'evaluate.cornerstone.hasSegmentationOfType',
|
||||
@ -549,7 +549,7 @@ export const toolbarButtons: Button[] = [
|
||||
],
|
||||
options: [
|
||||
{
|
||||
name: 'Spline Type',
|
||||
name: i18n.t('Buttons:Spline Type'),
|
||||
type: 'select',
|
||||
id: 'splineTypeSelect',
|
||||
value: 'CatmullRomSplineROI',
|
||||
@ -557,10 +557,10 @@ export const toolbarButtons: Button[] = [
|
||||
{
|
||||
id: 'CatmullRomSplineROI',
|
||||
value: 'CatmullRomSplineROI',
|
||||
label: 'Catmull Rom Spline',
|
||||
label: i18n.t('Buttons:Catmull Rom Spline'),
|
||||
},
|
||||
{ id: 'LinearSplineROI', value: 'LinearSplineROI', label: 'Linear Spline' },
|
||||
{ id: 'BSplineROI', value: 'BSplineROI', label: 'B-Spline' },
|
||||
{ id: 'LinearSplineROI', value: 'LinearSplineROI', label: i18n.t('Buttons:Linear Spline') },
|
||||
{ id: 'BSplineROI', value: 'BSplineROI', label: i18n.t('Buttons:B-Spline') },
|
||||
],
|
||||
commands: {
|
||||
commandName: 'setToolActiveToolbar',
|
||||
@ -578,7 +578,7 @@ export const toolbarButtons: Button[] = [
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Simplified Spline',
|
||||
name: i18n.t('Buttons:Simplified Spline'),
|
||||
type: 'switch',
|
||||
id: 'simplifiedSpline',
|
||||
value: true,
|
||||
@ -587,7 +587,7 @@ export const toolbarButtons: Button[] = [
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Interpolate Contours',
|
||||
name: i18n.t('Buttons:Interpolate Contours'),
|
||||
type: 'switch',
|
||||
id: 'splineInterpolateContours',
|
||||
value: false,
|
||||
@ -606,13 +606,13 @@ export const toolbarButtons: Button[] = [
|
||||
uiType: 'ohif.toolBoxButton',
|
||||
props: {
|
||||
icon: 'icon-tool-sculptor',
|
||||
label: 'Sculptor Tool',
|
||||
tooltip: 'Sculptor Tool',
|
||||
label: i18n.t('Buttons:Sculptor Tool'),
|
||||
tooltip: i18n.t('Buttons:Sculptor Tool'),
|
||||
evaluate: [
|
||||
{
|
||||
name: 'evaluate.cornerstone.segmentation',
|
||||
toolNames: ['SculptorTool'],
|
||||
disabledText: 'Create new segmentation to enable this tool.',
|
||||
disabledText: i18n.t('Buttons:Create new segmentation to enable this tool.'),
|
||||
},
|
||||
{
|
||||
name: 'evaluate.cornerstone.hasSegmentationOfType',
|
||||
@ -630,7 +630,7 @@ export const toolbarButtons: Button[] = [
|
||||
],
|
||||
options: [
|
||||
{
|
||||
name: 'Dynamic Cursor Size',
|
||||
name: i18n.t('Buttons:Dynamic Cursor Size'),
|
||||
type: 'switch',
|
||||
id: 'dynamicCursorSize',
|
||||
value: true,
|
||||
@ -670,7 +670,7 @@ export const toolbarButtons: Button[] = [
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Radius (mm)',
|
||||
name: i18n.t('Buttons:Radius (mm)'),
|
||||
id: 'brush-radius',
|
||||
type: 'range',
|
||||
explicitRunOnly: true,
|
||||
@ -686,13 +686,13 @@ export const toolbarButtons: Button[] = [
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Shape',
|
||||
name: i18n.t('Buttons:Shape'),
|
||||
type: 'radio',
|
||||
id: 'brush-mode',
|
||||
value: 'CircularBrush',
|
||||
values: [
|
||||
{ value: 'CircularBrush', label: 'Circle' },
|
||||
{ value: 'SphereBrush', label: 'Sphere' },
|
||||
{ value: 'CircularBrush', label: i18n.t('Buttons:Circle') },
|
||||
{ value: 'SphereBrush', label: i18n.t('Buttons:Sphere') },
|
||||
],
|
||||
commands: ['setToolActiveToolbar'],
|
||||
},
|
||||
@ -860,13 +860,13 @@ export const toolbarButtons: Button[] = [
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Marker Mode',
|
||||
name: i18n.t('Buttons:Marker Mode'),
|
||||
type: 'radio',
|
||||
id: 'marker-mode',
|
||||
value: 'markerInclude',
|
||||
values: [
|
||||
{ value: 'markerInclude', label: 'Include' },
|
||||
{ value: 'markerExclude', label: 'Exclude' },
|
||||
{ value: 'markerInclude', label: i18n.t('Buttons:Include') },
|
||||
{ value: 'markerExclude', label: i18n.t('Buttons:Exclude') },
|
||||
],
|
||||
commands: ({ commandsManager, options }) => {
|
||||
const markerModeOption = options.find(option => option.id === 'marker-mode');
|
||||
@ -882,7 +882,7 @@ export const toolbarButtons: Button[] = [
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Clear Markers',
|
||||
name: i18n.t('Buttons:Clear Markers'),
|
||||
type: 'button',
|
||||
id: 'clear-markers',
|
||||
commands: 'clearMarkersForMarkerLabelmap',
|
||||
@ -912,7 +912,7 @@ export const toolbarButtons: Button[] = [
|
||||
],
|
||||
options: [
|
||||
{
|
||||
name: 'Radius (mm)',
|
||||
name: i18n.t('Buttons:Radius (mm)'),
|
||||
id: 'eraser-radius',
|
||||
type: 'range',
|
||||
explicitRunOnly: true,
|
||||
@ -926,13 +926,13 @@ export const toolbarButtons: Button[] = [
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Shape',
|
||||
name: i18n.t('Buttons:Shape'),
|
||||
type: 'radio',
|
||||
id: 'eraser-mode',
|
||||
value: 'CircularEraser',
|
||||
values: [
|
||||
{ value: 'CircularEraser', label: 'Circle' },
|
||||
{ value: 'SphereEraser', label: 'Sphere' },
|
||||
{ value: 'CircularEraser', label: i18n.t('Buttons:Circle') },
|
||||
{ value: 'SphereEraser', label: i18n.t('Buttons:Sphere') },
|
||||
],
|
||||
commands: 'setToolActiveToolbar',
|
||||
},
|
||||
@ -950,7 +950,7 @@ export const toolbarButtons: Button[] = [
|
||||
uiType: 'ohif.toolBoxButton',
|
||||
props: {
|
||||
icon: 'icon-tool-threshold',
|
||||
label: 'Threshold Tool',
|
||||
label: i18n.t('Buttons:Threshold Tool'),
|
||||
evaluate: [
|
||||
{
|
||||
name: 'evaluate.cornerstone.segmentation',
|
||||
@ -978,7 +978,7 @@ export const toolbarButtons: Button[] = [
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Radius (mm)',
|
||||
name: i18n.t('Buttons:Radius (mm)'),
|
||||
id: 'threshold-radius',
|
||||
type: 'range',
|
||||
explicitRunOnly: true,
|
||||
@ -999,13 +999,13 @@ export const toolbarButtons: Button[] = [
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Shape',
|
||||
name: i18n.t('Buttons:Shape'),
|
||||
type: 'radio',
|
||||
id: 'threshold-shape',
|
||||
value: 'ThresholdCircularBrush',
|
||||
values: [
|
||||
{ value: 'ThresholdCircularBrush', label: 'Circle' },
|
||||
{ value: 'ThresholdSphereBrush', label: 'Sphere' },
|
||||
{ value: 'ThresholdCircularBrush', label: i18n.t('Buttons:Circle') },
|
||||
{ value: 'ThresholdSphereBrush', label: i18n.t('Buttons:Sphere') },
|
||||
],
|
||||
commands: ({ value, commandsManager, options }) => {
|
||||
const optionsDynamic = options.find(option => option.id === 'dynamic-mode');
|
||||
@ -1025,13 +1025,13 @@ export const toolbarButtons: Button[] = [
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Threshold',
|
||||
name: i18n.t('Buttons:Threshold'),
|
||||
type: 'radio',
|
||||
id: 'dynamic-mode',
|
||||
value: 'ThresholdDynamic',
|
||||
values: [
|
||||
{ value: 'ThresholdDynamic', label: 'Dynamic' },
|
||||
{ value: 'ThresholdRange', label: 'Range' },
|
||||
{ value: 'ThresholdDynamic', label: i18n.t('Buttons:Dynamic') },
|
||||
{ value: 'ThresholdRange', label: i18n.t('Buttons:Range') },
|
||||
],
|
||||
commands: ({ value, commandsManager, options }) => {
|
||||
const thresholdRangeOption = options.find(option => option.id === 'threshold-shape');
|
||||
@ -1104,14 +1104,14 @@ export const toolbarButtons: Button[] = [
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Shape',
|
||||
name: i18n.t('Buttons:Shape'),
|
||||
type: 'radio',
|
||||
value: 'CircleScissor',
|
||||
id: 'shape-mode',
|
||||
values: [
|
||||
{ value: 'CircleScissor', label: 'Circle' },
|
||||
{ value: 'SphereScissor', label: 'Sphere' },
|
||||
{ value: 'RectangleScissor', label: 'Rectangle' },
|
||||
{ value: 'CircleScissor', label: i18n.t('Buttons:Circle') },
|
||||
{ value: 'SphereScissor', label: i18n.t('Buttons:Sphere') },
|
||||
{ value: 'RectangleScissor', label: i18n.t('Buttons:Rectangle') },
|
||||
],
|
||||
commands: 'setToolActiveToolbar',
|
||||
},
|
||||
@ -1171,8 +1171,8 @@ export const toolbarButtons: Button[] = [
|
||||
uiType: 'ohif.toolBoxButton',
|
||||
props: {
|
||||
icon: 'tool-labelmap-edit-with-contour',
|
||||
label: 'Labelmap Edit with Contour Tool',
|
||||
tooltip: 'Labelmap Edit with Contour Tool',
|
||||
label: i18n.t('Buttons:Labelmap Edit with Contour Tool'),
|
||||
tooltip: i18n.t('Buttons:Labelmap Edit with Contour Tool'),
|
||||
commands: [
|
||||
'setToolActiveToolbar',
|
||||
{
|
||||
|
||||
@ -220,7 +220,7 @@ const toolbarButtons = [
|
||||
],
|
||||
options: [
|
||||
{
|
||||
name: 'Radius (mm)',
|
||||
name: i18n.t('Buttons:Radius (mm)'),
|
||||
id: 'brush-radius',
|
||||
type: 'range',
|
||||
explicitRunOnly: true,
|
||||
@ -234,13 +234,13 @@ const toolbarButtons = [
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Shape',
|
||||
name: i18n.t('Buttons:Shape'),
|
||||
type: 'radio',
|
||||
id: 'brush-mode',
|
||||
value: 'CircularBrush',
|
||||
values: [
|
||||
{ value: 'CircularBrush', label: 'Circle' },
|
||||
{ value: 'SphereBrush', label: 'Sphere' },
|
||||
{ value: 'CircularBrush', label: i18n.t('Buttons:Circle') },
|
||||
{ value: 'SphereBrush', label: i18n.t('Buttons:Sphere') },
|
||||
],
|
||||
commands: 'setToolActiveToolbar',
|
||||
},
|
||||
@ -265,7 +265,7 @@ const toolbarButtons = [
|
||||
],
|
||||
options: [
|
||||
{
|
||||
name: 'Radius (mm)',
|
||||
name: i18n.t('Buttons:Radius (mm)'),
|
||||
id: 'eraser-radius',
|
||||
type: 'range',
|
||||
explicitRunOnly: true,
|
||||
@ -279,13 +279,13 @@ const toolbarButtons = [
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Shape',
|
||||
name: i18n.t('Buttons:Shape'),
|
||||
type: 'radio',
|
||||
id: 'eraser-mode',
|
||||
value: 'CircularEraser',
|
||||
values: [
|
||||
{ value: 'CircularEraser', label: 'Circle' },
|
||||
{ value: 'SphereEraser', label: 'Sphere' },
|
||||
{ value: 'CircularEraser', label: i18n.t('Buttons:Circle') },
|
||||
{ value: 'SphereEraser', label: i18n.t('Buttons:Sphere') },
|
||||
],
|
||||
commands: 'setToolActiveToolbar',
|
||||
},
|
||||
@ -310,7 +310,7 @@ const toolbarButtons = [
|
||||
],
|
||||
options: [
|
||||
{
|
||||
name: 'Radius (mm)',
|
||||
name: i18n.t('Buttons:Radius (mm)'),
|
||||
id: 'threshold-radius',
|
||||
type: 'range',
|
||||
explicitRunOnly: true,
|
||||
@ -330,13 +330,13 @@ const toolbarButtons = [
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Threshold',
|
||||
name: i18n.t('Buttons:Threshold'),
|
||||
type: 'radio',
|
||||
id: 'dynamic-mode',
|
||||
value: 'ThresholdRange',
|
||||
values: [
|
||||
{ value: 'ThresholdDynamic', label: 'Dynamic' },
|
||||
{ value: 'ThresholdRange', label: 'Range' },
|
||||
{ value: 'ThresholdDynamic', label: i18n.t('Buttons:Dynamic') },
|
||||
{ value: 'ThresholdRange', label: i18n.t('Buttons:Range') },
|
||||
],
|
||||
commands: ({ value, commandsManager }) => {
|
||||
if (value === 'ThresholdDynamic') {
|
||||
@ -351,20 +351,20 @@ const toolbarButtons = [
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Shape',
|
||||
name: i18n.t('Buttons:Shape'),
|
||||
type: 'radio',
|
||||
id: 'eraser-mode',
|
||||
value: 'ThresholdCircularBrush',
|
||||
values: [
|
||||
{ value: 'ThresholdCircularBrush', label: 'Circle' },
|
||||
{ value: 'ThresholdSphereBrush', label: 'Sphere' },
|
||||
{ value: 'ThresholdCircularBrush', label: i18n.t('Buttons:Circle') },
|
||||
{ value: 'ThresholdSphereBrush', label: i18n.t('Buttons:Sphere') },
|
||||
],
|
||||
condition: ({ options }) =>
|
||||
options.find(option => option.id === 'dynamic-mode').value === 'ThresholdRange',
|
||||
commands: 'setToolActiveToolbar',
|
||||
},
|
||||
{
|
||||
name: 'ThresholdRange',
|
||||
name: i18n.t('ROIThresholdConfiguration:ThresholdRange'),
|
||||
type: 'double-range',
|
||||
id: 'threshold-range',
|
||||
min: 0,
|
||||
|
||||
@ -628,7 +628,7 @@ const toolbarButtons: Button[] = [
|
||||
commands: setToolActiveToolbar,
|
||||
evaluate: {
|
||||
name: 'evaluate.cornerstoneTool',
|
||||
disabledText: 'Select a 3D viewport to enable this tool',
|
||||
disabledText: i18n.t('Buttons:Select a 3D viewport to enable this tool'),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -672,7 +672,7 @@ const toolbarButtons: Button[] = [
|
||||
},
|
||||
evaluate: {
|
||||
name: 'evaluate.cornerstoneTool',
|
||||
disabledText: 'Select an MPR viewport to enable this tool',
|
||||
disabledText: i18n.t('Buttons:Select an MPR viewport to enable this tool'),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
import { useSystem } from '../contextProviders/SystemProvider';
|
||||
import i18n from 'i18next';
|
||||
import { seriesSortCriteria } from './sortStudy';
|
||||
|
||||
|
||||
/**
|
||||
* Tab properties that drive which tab group is used for thumbnail display.
|
||||
*/
|
||||
@ -98,17 +100,17 @@ export function createStudyBrowserTabs(
|
||||
const tabs = [
|
||||
{
|
||||
name: 'primary',
|
||||
label: 'Primary',
|
||||
label: i18n.t('StudyBrowser:Primary'),
|
||||
studies: primaryStudies.sort((studyA, studyB) => _byDate(studyA.date, studyB.date)),
|
||||
},
|
||||
{
|
||||
name: 'recent',
|
||||
label: 'Recent',
|
||||
label: i18n.t('StudyBrowser:Recent'),
|
||||
studies: recentStudies.sort((studyA, studyB) => _byDate(studyA.date, studyB.date)),
|
||||
},
|
||||
{
|
||||
name: 'all',
|
||||
label: 'All',
|
||||
label: i18n.t('StudyBrowser:All'),
|
||||
studies: allStudies.sort((studyA, studyB) => _byDate(studyA.date, studyB.date)),
|
||||
},
|
||||
];
|
||||
|
||||
@ -8,7 +8,17 @@ import i18n from 'i18next';
|
||||
* @param {string} format Desired date format
|
||||
* @returns {string} Formatted date
|
||||
*/
|
||||
export default (date, format = i18n.t('Common:localDateFormat','DD-MMM-YYYY')) => {
|
||||
// moment(undefined) returns the current date, so return the empty string instead
|
||||
return date ? moment(date).format(format) : '';
|
||||
export default (date, format = i18n.t('Common:localDateFormat', 'DD-MMM-YYYY')) => {
|
||||
if (!date) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const locale = i18n.language || 'en';
|
||||
const parsed = moment(date, ['YYYYMMDD', 'YYYY.MM.DD'], true);
|
||||
|
||||
if (!parsed.isValid()) {
|
||||
return moment(date).locale(locale).format(format);
|
||||
}
|
||||
|
||||
return parsed.locale(locale).format(format);
|
||||
};
|
||||
|
||||
10
platform/i18n/src/locales/ar/DataRow.json
Normal file
10
platform/i18n/src/locales/ar/DataRow.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"Hide": "إخفاء",
|
||||
"Show": "إظهار",
|
||||
"Rename": "إعادة تسمية",
|
||||
"Duplicate": "تكرار",
|
||||
"Delete": "حذف",
|
||||
"Change Color": "تغيير اللون",
|
||||
"Lock": "قفل",
|
||||
"Unlock": "إلغاء القفل"
|
||||
}
|
||||
@ -14,5 +14,8 @@
|
||||
"Outline": "حدود",
|
||||
"Rename": "إعادة تسمية",
|
||||
"Segmentation": "تجزئة",
|
||||
"Size": "الحجم"
|
||||
}
|
||||
"Size": "الحجم",
|
||||
"No segmentations available": "لا توجد تجزئات متاحة",
|
||||
"Not available on the current viewport": "غير متاح في نافذة العرض الحالية",
|
||||
"Add segment to enable this tool": "أضف مقطعًا لتمكين هذه الأداة"
|
||||
}
|
||||
@ -8,8 +8,9 @@ import ErrorBoundary from './ErrorBoundary.json';
|
||||
import Header from './Header.json';
|
||||
import HotkeysValidators from './HotkeysValidators.json';
|
||||
import MeasurementTable from './MeasurementTable.json';
|
||||
import DataRow from './DataRow.json';
|
||||
import Modes from './Modes.json';
|
||||
import SegmentationTable from './SegmentationTable.json';
|
||||
import SegmentationPanel from './SegmentationPanel.json';
|
||||
import SidePanel from './SidePanel.json';
|
||||
import StudyBrowser from './StudyBrowser.json';
|
||||
import StudyItem from './StudyItem.json';
|
||||
@ -34,8 +35,9 @@ export default {
|
||||
Header,
|
||||
HotkeysValidators,
|
||||
MeasurementTable,
|
||||
DataRow,
|
||||
Modes,
|
||||
SegmentationTable,
|
||||
SegmentationPanel,
|
||||
SidePanel,
|
||||
StudyBrowser,
|
||||
StudyItem,
|
||||
|
||||
10
platform/i18n/src/locales/de/DataRow.json
Normal file
10
platform/i18n/src/locales/de/DataRow.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"Hide": "Verbergen",
|
||||
"Show": "Anzeigen",
|
||||
"Rename": "Umbenennen",
|
||||
"Duplicate": "Duplizieren",
|
||||
"Delete": "Löschen",
|
||||
"Change Color": "Farbe ändern",
|
||||
"Lock": "Sperren",
|
||||
"Unlock": "Entsperren"
|
||||
}
|
||||
@ -5,6 +5,7 @@ import Common from './Common.json';
|
||||
import DatePicker from './DatePicker.json';
|
||||
import Header from './Header.json';
|
||||
import MeasurementTable from './MeasurementTable.json';
|
||||
import DataRow from './DataRow.json';
|
||||
import StudyList from './StudyList.json';
|
||||
import UserPreferencesModal from './UserPreferencesModal.json';
|
||||
import ViewportDownloadForm from './ViewportDownloadForm.json';
|
||||
@ -18,6 +19,7 @@ export default {
|
||||
DatePicker,
|
||||
Header,
|
||||
MeasurementTable,
|
||||
DataRow,
|
||||
StudyList,
|
||||
UserPreferencesModal,
|
||||
ViewportDownloadForm,
|
||||
|
||||
@ -3,6 +3,8 @@
|
||||
"Browser": "Browser",
|
||||
"Build number": "Build Number",
|
||||
"Commit hash": "Commit hash",
|
||||
"Commit Hash": "Commit Hash",
|
||||
"Current Browser & OS": "Current Browser & OS",
|
||||
"Data citation": "Data citation",
|
||||
"Important links": "Important links",
|
||||
"Last master commits": "Latest Master Commits",
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
"Cancel": "Cancel",
|
||||
"Capture": "Capture",
|
||||
"Circle": "Circle",
|
||||
"Sphere": "Sphere",
|
||||
"Clear": "Clear",
|
||||
"Coronal": "Coronal",
|
||||
"Crosshairs": "Crosshairs",
|
||||
@ -60,6 +61,7 @@
|
||||
"Freehand ROI": "Freehand ROI",
|
||||
"Spline ROI": "Spline ROI",
|
||||
"Livewire tool": "Livewire tool",
|
||||
"Livewire Contour": "Livewire Contour",
|
||||
"Segment Label Display": "Segment Label Display",
|
||||
"Data Overlay": "Data Overlay",
|
||||
"Configure data overlay options and manage foreground/background display sets": "Configure data overlay options and manage foreground/background display sets",
|
||||
@ -116,15 +118,37 @@
|
||||
"Line": "Line",
|
||||
"Line Tool": "Line Tool",
|
||||
"3D Rotate": "3D Rotate",
|
||||
"Shape": "Shape",
|
||||
"MPR": "MPR",
|
||||
"Rectangle ROI Threshold": "Rectangle ROI Threshold",
|
||||
"Select the PT Axial to enable this tool": "Select the PT Axial to enable this tool",
|
||||
"Create new segmentation to enable this tool.": "Create new segmentation to enable this tool.",
|
||||
"Freehand Segmentation": "Freehand Segmentation",
|
||||
"Spline Contour Segmentation Tool": "Spline Contour Segmentation Tool",
|
||||
"Sculptor Tool": "Sculptor Tool",
|
||||
"Interpolate Contours": "Interpolate Contours",
|
||||
"Marker Mode": "Marker Mode",
|
||||
"Include": "Include",
|
||||
"Exclude": "Exclude",
|
||||
"Clear Markers": "Clear Markers",
|
||||
"Radius (mm)": "Radius (mm)",
|
||||
"Dynamic": "Dynamic",
|
||||
"Range": "Range",
|
||||
"Spline Type": "Spline Type",
|
||||
"Catmull Rom Spline": "Catmull Rom Spline",
|
||||
"Linear Spline": "Linear Spline",
|
||||
"B-Spline": "B-Spline",
|
||||
"Simplified Spline": "Simplified Spline",
|
||||
"Dynamic Cursor Size": "Dynamic Cursor Size",
|
||||
"No segmentations available": "No segmentations available",
|
||||
"Threshold Tool": "Threshold Tool",
|
||||
"Threshold Tools": "Threshold Tools",
|
||||
"Select a 3D viewport to enable this tool": "Select a 3D viewport to enable this tool",
|
||||
"Not available on the current viewport": "Not available on the current viewport",
|
||||
"Select an MPR viewport to enable this tool": "Select an MPR viewport to enable this tool",
|
||||
"Interpolate Labelmap": "Interpolate Labelmap",
|
||||
"Segment Bidirectional": "Segment Bidirectional",
|
||||
"Tool not available for this modality": "Tool not available for this modality",
|
||||
"One Click Segment": "One Click Segment",
|
||||
"Labelmap Assist": "Labelmap Assist",
|
||||
"Marker Guided Labelmap": "Marker Guided Labelmap",
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
{
|
||||
"File name": "File name",
|
||||
"Image size": "Image size",
|
||||
"Image size in pixels": "Image size in pixels",
|
||||
"Include annotations": "Include annotations",
|
||||
"Include warning message": "Include warning message"
|
||||
"Include warning message": "Include warning message",
|
||||
"Width": "Width",
|
||||
"Height": "Height"
|
||||
}
|
||||
|
||||
15
platform/i18n/src/locales/en-US/Colormaps.json
Normal file
15
platform/i18n/src/locales/en-US/Colormaps.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"Grayscale": "Grayscale",
|
||||
"X Ray": "X Ray",
|
||||
"Isodose": "Isodose",
|
||||
"hsv": "HSV",
|
||||
"hot_iron": "Hot Iron",
|
||||
"red_hot": "Red Hot",
|
||||
"s_pet": "PET",
|
||||
"perfusion": "Perfusion",
|
||||
"rainbow_2": "Rainbow 2",
|
||||
"suv": "SUV",
|
||||
"ge_256": "GE 256",
|
||||
"ge": "GE",
|
||||
"siemens": "Siemens"
|
||||
}
|
||||
@ -22,5 +22,8 @@
|
||||
"Cancel": "Cancel",
|
||||
"Save": "Save",
|
||||
"localDateFormat": "DD-MMM-YYYY",
|
||||
"Back": "Back"
|
||||
"Back": "Back",
|
||||
"Foreground": "Foreground",
|
||||
"SELECT A FOREGROUND": "SELECT A FOREGROUND",
|
||||
"SELECT A SEGMENTATION": "SELECT A SEGMENTATION"
|
||||
}
|
||||
|
||||
10
platform/i18n/src/locales/en-US/DataRow.json
Normal file
10
platform/i18n/src/locales/en-US/DataRow.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"Hide": "Hide",
|
||||
"Show": "Show",
|
||||
"Rename": "Rename",
|
||||
"Duplicate": "Duplicate",
|
||||
"Delete": "Delete",
|
||||
"Change Color": "Change Color",
|
||||
"Lock": "Lock",
|
||||
"Unlock": "Unlock"
|
||||
}
|
||||
@ -5,5 +5,9 @@
|
||||
"Last 7 days": "Last 7 days",
|
||||
"Last 30 days": "Last 30 days",
|
||||
"Start Date": "Start Date",
|
||||
"Today": "Today"
|
||||
"Today": "Today",
|
||||
"Previous Month": "Previous Month",
|
||||
"Next Month": "Next Month",
|
||||
"Select Month": "Select Month",
|
||||
"Select Year": "Select Year"
|
||||
}
|
||||
|
||||
@ -7,5 +7,8 @@
|
||||
"mpr": "mpr",
|
||||
"3D only": "3D only",
|
||||
"3D primary": "3D primary",
|
||||
"Axial Primary": "Axial Primary"
|
||||
"Axial Primary": "Axial Primary",
|
||||
"Compare Two Studies": "Compare Two Studies",
|
||||
"Compare two studies in various layouts": "Compare two studies in various layouts",
|
||||
"Mammography Breast Screening": "Mammography Breast Screening"
|
||||
}
|
||||
|
||||
@ -8,6 +8,15 @@
|
||||
"NonTargets": "NonTargets",
|
||||
"Relabel": "Relabel",
|
||||
"Targets": "Targets",
|
||||
"Rename": "Rename",
|
||||
"Duplicate": "Duplicate",
|
||||
"Change Color": "Change Color",
|
||||
"Lock": "Lock",
|
||||
"Unlock": "Unlock",
|
||||
"Hide": "Hide",
|
||||
"Show": "Show",
|
||||
"Create SR": "Create SR",
|
||||
"empty": "(empty)",
|
||||
"Track measurements for this series?": "Track measurements for this series?",
|
||||
"Do you want to add this measurement to the existing report?": "Do you want to add this measurement to the existing report?",
|
||||
"You have existing tracked measurements. What would you like to do with your existing tracked measurements?": "You have existing tracked measurements. What would you like to do with your existing tracked measurements?",
|
||||
|
||||
@ -4,5 +4,6 @@
|
||||
"Basic Viewer": "Basic Viewer",
|
||||
"Microscopy": "Microscopy",
|
||||
"Segmentation": "Segmentation",
|
||||
"Total Metabolic Tumor Volume": "Total Metabolic Tumor Volume"
|
||||
"Total Metabolic Tumor Volume": "Total Metabolic Tumor Volume",
|
||||
"US Pleura B-line Annotations": "US Pleura B-line Annotations"
|
||||
}
|
||||
|
||||
27
platform/i18n/src/locales/en-US/Onboarding.json
Normal file
27
platform/i18n/src/locales/en-US/Onboarding.json
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"Scrolling Through Images": "Scrolling Through Images",
|
||||
"You can scroll through the images using the mouse wheel or scrollbar.": "You can scroll through the images using the mouse wheel or scrollbar.",
|
||||
"Zooming In and Out": "Zooming In and Out",
|
||||
"You can zoom the images using the right click.": "You can zoom the images using the right click.",
|
||||
"Panning the Image": "Panning the Image",
|
||||
"You can pan the images using the middle click.": "You can pan the images using the middle click.",
|
||||
"Adjusting Window Level": "Adjusting Window Level",
|
||||
"You can modify the window level using the left click.": "You can modify the window level using the left click.",
|
||||
"Using the Measurement Tools": "Using the Measurement Tools",
|
||||
"You can measure the length of a region using the Length tool.": "You can measure the length of a region using the Length tool.",
|
||||
"Drawing Length Annotations": "Drawing Length Annotations",
|
||||
"Use the length tool on the viewport to measure the length of a region.": "Use the length tool on the viewport to measure the length of a region.",
|
||||
"Tracking Measurements in the Panel": "Tracking Measurements in the Panel",
|
||||
"Click yes to track the measurements in the measurement panel.": "Click yes to track the measurements in the measurement panel.",
|
||||
"Opening the Measurements Panel": "Opening the Measurements Panel",
|
||||
"Click the measurements button to open the measurements panel.": "Click the measurements button to open the measurements panel.",
|
||||
"Scrolling Away from a Measurement": "Scrolling Away from a Measurement",
|
||||
"Scroll the images using the mouse wheel away from the measurement.": "Scroll the images using the mouse wheel away from the measurement.",
|
||||
"Jumping to Measurements in the Panel": "Jumping to Measurements in the Panel",
|
||||
"Click the measurement in the measurement panel to jump to it.": "Click the measurement in the measurement panel to jump to it.",
|
||||
"Changing Layout": "Changing Layout",
|
||||
"You can change the layout of the viewer using the layout button.": "You can change the layout of the viewer using the layout button.",
|
||||
"Selecting the MPR Layout": "Selecting the MPR Layout",
|
||||
"Select the MPR layout to view the images in MPR mode.": "Select the MPR layout to view the images in MPR mode.",
|
||||
"Skip all": "Skip all"
|
||||
}
|
||||
10
platform/i18n/src/locales/en-US/PanelSUV.json
Normal file
10
platform/i18n/src/locales/en-US/PanelSUV.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"Patient Information": "Patient Information",
|
||||
"Patient Sex": "Patient Sex",
|
||||
"Weight": "Weight",
|
||||
"Total Dose": "Total Dose",
|
||||
"Half Life": "Half Life",
|
||||
"Injection Time": "Injection Time",
|
||||
"Acquisition Time": "Acquisition Time",
|
||||
"Reload Data": "Reload Data"
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
{
|
||||
"Max": "Max",
|
||||
"Range": "Range",
|
||||
"Start": "Start",
|
||||
"End": "End",
|
||||
"Percentage of Max SUV": "Percentage of Max SUV",
|
||||
"Lower & Upper Ranges": "Lower & Upper Ranges",
|
||||
"Run": "Run",
|
||||
"Threshold Tools": "Threshold Tools",
|
||||
"ThresholdRange": "Threshold Range"
|
||||
}
|
||||
67
platform/i18n/src/locales/en-US/SegmentationPanel.json
Normal file
67
platform/i18n/src/locales/en-US/SegmentationPanel.json
Normal file
@ -0,0 +1,67 @@
|
||||
{
|
||||
"Active": "Active",
|
||||
"Add new segmentation": "Add new segmentation",
|
||||
"Add segment": "Add segment",
|
||||
"Add segmentation": "Add segmentation",
|
||||
"Contour": "Contour",
|
||||
"Contour tools": "Contour tools",
|
||||
"Contour Segmentations": "Contour segmentations",
|
||||
"Delete": "Delete",
|
||||
"Display inactive segmentations": "Display inactive segmentations",
|
||||
"Add Segment": "Add Segment",
|
||||
"Download DICOM RTSS": "Download DICOM RTSS",
|
||||
"Export DICOM SEG": "Export DICOM SEG",
|
||||
"Download DICOM SEG": "Download DICOM SEG",
|
||||
"Download DICOM RTSTRUCT": "Download DICOM RTSTRUCT",
|
||||
"Fill": "Fill",
|
||||
"Inactive segmentations": "Inactive segmentations",
|
||||
"Labelmap": "Label map",
|
||||
"Labelmap tools": "Label map tools",
|
||||
"Labelmap Segmentations": "Label map segmentations",
|
||||
"Opacity": "Opacity",
|
||||
"Border": "Border",
|
||||
"Show": "Show",
|
||||
"Fill & Outline": "Fill & Outline",
|
||||
"Outline Only": "Outline Only",
|
||||
"Fill Only": "Fill Only",
|
||||
"Outline": "Outline",
|
||||
"Rename": "Rename",
|
||||
"Segmentation": "Segmentation",
|
||||
"Segmentations": "Segmentations",
|
||||
"Segmentation not supported": "Segmentation not supported",
|
||||
"Size": "Size",
|
||||
"Preview edits before creating": "Preview edits before creating",
|
||||
"Use center as segment index": "Use center as segment index",
|
||||
"Hover on segment border to activate": "Hover on segment border to activate",
|
||||
"Show segment name on hover": "Show segment name on hover",
|
||||
"Create New Segmentation": "Create New Segmentation",
|
||||
"Manage Current Segmentation": "Manage Current Segmentation",
|
||||
"Remove from Viewport": "Remove from Viewport",
|
||||
"Download & Export": "Download & Export",
|
||||
"Download": "Download",
|
||||
"Export": "Export",
|
||||
"CSV Report": "CSV Report",
|
||||
"DICOM SEG": "DICOM SEG",
|
||||
"DICOM RTSS": "DICOM RTSS"
|
||||
,
|
||||
"Fill contour holes": "Fill contour holes",
|
||||
"Fill Holes": "Fill Holes",
|
||||
"Remove Small Contours": "Remove Small Contours",
|
||||
"Area Threshold": "Area Threshold",
|
||||
"Create New Segment from Holes": "Create New Segment from Holes",
|
||||
"Create New Segment": "Create New Segment",
|
||||
"Smooth all edges": "Smooth all edges",
|
||||
"Smooth Edges": "Smooth Edges",
|
||||
"Remove extra points": "Remove extra points",
|
||||
"Remove Points": "Remove Points",
|
||||
"Merge": "Merge",
|
||||
"Intersect": "Intersect",
|
||||
"Subtract": "Subtract",
|
||||
"Select a segment": "Select a segment",
|
||||
"Select a segmentation": "Select a segmentation",
|
||||
"Create a new segment": "Create a new segment",
|
||||
"New segment name": "New segment name",
|
||||
"No segmentations available": "No segmentations available",
|
||||
"Not available on the current viewport": "Not available on the current viewport",
|
||||
"Add segment to enable this tool": "Add segment to enable this tool"
|
||||
}
|
||||
@ -1,27 +0,0 @@
|
||||
{
|
||||
"Active": "Active",
|
||||
"Add new segmentation": "Add new segmentation",
|
||||
"Add segment": "Add segment",
|
||||
"Add segmentation": "Add segmentation",
|
||||
"Contour": "Contour",
|
||||
"Contour tools": "Contour tools",
|
||||
"Contour Segmentations": "Contour segmentations",
|
||||
"Delete": "Delete",
|
||||
"Display inactive segmentations": "Display inactive segmentations",
|
||||
"Download DICOM RTSS": "Download DICOM RTSS",
|
||||
"Export DICOM SEG": "Export DICOM SEG",
|
||||
"Download DICOM SEG": "Download DICOM SEG",
|
||||
"Download DICOM RTSTRUCT": "Download DICOM RTSTRUCT",
|
||||
"Fill": "Fill",
|
||||
"Inactive segmentations": "Inactive segmentations",
|
||||
"Labelmap": "Label map",
|
||||
"Labelmap tools": "Label map tools",
|
||||
"Labelmap Segmentations": "Label map segmentations",
|
||||
"Opacity": "Opacity",
|
||||
"Outline": "Outline",
|
||||
"Rename": "Rename",
|
||||
"Segmentation": "Segmentation",
|
||||
"Segmentations": "Segmentations",
|
||||
"Segmentation not supported": "Segmentation not supported",
|
||||
"Size": "Size"
|
||||
}
|
||||
@ -14,6 +14,7 @@
|
||||
"PatientName": "Patient Name",
|
||||
"Previous": "< Back",
|
||||
"Results per page": "Results per page",
|
||||
"Studies": "Studies",
|
||||
"StudyDate": "Study Date",
|
||||
"StudyList": "Study List",
|
||||
"Upload": "Upload"
|
||||
|
||||
17
platform/i18n/src/locales/en-US/USAnnotationPanel.json
Normal file
17
platform/i18n/src/locales/en-US/USAnnotationPanel.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"Workflow": "Workflow",
|
||||
"Depth guide toggle": "Depth guide toggle",
|
||||
"Show pleura percentage": "Show pleura percentage",
|
||||
"Sector Annotations": "Sector Annotations",
|
||||
"Pleura line": "Pleura line",
|
||||
"B-line": "B-line",
|
||||
"B-line annotation": "B-line annotation",
|
||||
"Pleura annotation": "Pleura annotation",
|
||||
"Show Overlay": "Show Overlay",
|
||||
"Annotated Frames": "Annotated Frames",
|
||||
"Frame": "Frame",
|
||||
"Pleura lines": "Pleura lines",
|
||||
"B-lines": "B-lines",
|
||||
"JSON": "JSON",
|
||||
"Annotations": "Annotations"
|
||||
}
|
||||
@ -5,5 +5,80 @@
|
||||
"ResetDefaultMessage": "Preferences successfully reset to default. <br /> You must <strong>Save</strong> to perform this action.",
|
||||
"Save": "$t(Buttons:Save)",
|
||||
"SaveMessage": "Preferences saved",
|
||||
"User preferences": "User Preferences"
|
||||
"User preferences": "User Preferences",
|
||||
"Language": "Language",
|
||||
"Select language": "Select language",
|
||||
"Hotkeys": "Hotkeys",
|
||||
"Zoom": "Zoom",
|
||||
"Zoom In": "Zoom In",
|
||||
"Zoom Out": "Zoom Out",
|
||||
"Zoom to Fit": "Zoom to Fit",
|
||||
"Rotate Right": "Rotate Right",
|
||||
"Rotate Left": "Rotate Left",
|
||||
"Flip Horizontally": "Flip Horizontally",
|
||||
"Flip Vertically": "Flip Vertically",
|
||||
"Cine": "Cine",
|
||||
"Invert": "Invert",
|
||||
"Next Image Viewport": "Next Image Viewport",
|
||||
"Previous Image Viewport": "Previous Image Viewport",
|
||||
"Previous Series": "Previous Series",
|
||||
"Next Series": "Next Series",
|
||||
"Next Stage": "Next Stage",
|
||||
"Previous Stage": "Previous Stage",
|
||||
"Next Image": "Next Image",
|
||||
"Previous Image": "Previous Image",
|
||||
"First Image": "First Image",
|
||||
"Last Image": "Last Image",
|
||||
"Reset": "Reset",
|
||||
"Cancel Measurement": "Cancel Measurement",
|
||||
"W/L Preset 1": "W/L Preset 1",
|
||||
"W/L Preset 2": "W/L Preset 2",
|
||||
"W/L Preset 3": "W/L Preset 3",
|
||||
"W/L Preset 4": "W/L Preset 4",
|
||||
"Delete Annotation": "Delete Annotation",
|
||||
"Accept Preview": "Accept Preview",
|
||||
"Reject Preview": "Reject Preview",
|
||||
"Undo": "Undo",
|
||||
"Redo": "Redo",
|
||||
"Interpolate Scroll": "Interpolate Scroll",
|
||||
"Increase Brush Size": "Increase Brush Size",
|
||||
"Decrease Brush Size": "Decrease Brush Size",
|
||||
"Eraser": "Eraser",
|
||||
"Brush": "Brush",
|
||||
"Add New Segment": "Add New Segment",
|
||||
"Press keys": "Press keys...",
|
||||
"LanguageName.en-US": "English (US)",
|
||||
"LanguageName.fr": "French",
|
||||
"HotkeyKeys.ctrl": "Ctrl",
|
||||
"HotkeyKeys.shift": "Shift",
|
||||
"HotkeyKeys.alt": "Alt",
|
||||
"HotkeyKeys.option": "Option",
|
||||
"HotkeyKeys.meta": "Cmd",
|
||||
"HotkeyKeys.enter": "Enter",
|
||||
"HotkeyKeys.esc": "Esc",
|
||||
"HotkeyKeys.space": "Space",
|
||||
"HotkeyKeys.tab": "Tab",
|
||||
"HotkeyKeys.backspace": "Backspace",
|
||||
"HotkeyKeys.delete": "Delete",
|
||||
"HotkeyKeys.insert": "Insert",
|
||||
"HotkeyKeys.home": "Home",
|
||||
"HotkeyKeys.end": "End",
|
||||
"HotkeyKeys.pageup": "Page Up",
|
||||
"HotkeyKeys.pagedown": "Page Down",
|
||||
"HotkeyKeys.up": "Up Arrow",
|
||||
"HotkeyKeys.down": "Down Arrow",
|
||||
"HotkeyKeys.left": "Left Arrow",
|
||||
"HotkeyKeys.right": "Right Arrow",
|
||||
"HotkeyKeys.capslock": "Caps Lock",
|
||||
"HotkeyKeys.plus": "Plus",
|
||||
"HotkeyKeys.minus": "Minus",
|
||||
"HotkeyKeys.comma": "Comma",
|
||||
"HotkeyKeys.period": "Period",
|
||||
"HotkeyKeys.slash": "Slash",
|
||||
"HotkeyKeys.backslash": "Backslash",
|
||||
"HotkeyKeys.semicolon": "Semicolon",
|
||||
"HotkeyKeys.quote": "Quote",
|
||||
"HotkeyKeys.backquote": "Backtick",
|
||||
"HotkeyKeys.bracketleft": "Left Bracket",
|
||||
"HotkeyKeys.bracketright": "Right Bracket"
|
||||
}
|
||||
|
||||
@ -6,5 +6,14 @@
|
||||
"Color LUT": "Color LUT",
|
||||
"Preview in viewport": "Preview in viewport",
|
||||
"Grayscale": "Grayscale",
|
||||
"Rendering Options": "Rendering Options"
|
||||
"Rendering Options": "Rendering Options",
|
||||
"Rendering Presets": "Rendering Presets",
|
||||
"Search all": "Search all",
|
||||
"Quality": "Quality",
|
||||
"Lighting": "Lighting",
|
||||
"Shade": "Shade",
|
||||
"Ambient": "Ambient",
|
||||
"Diffuse": "Diffuse",
|
||||
"Specular": "Specular",
|
||||
"Shift": "Shift"
|
||||
}
|
||||
|
||||
@ -8,8 +8,9 @@ import ErrorBoundary from './ErrorBoundary.json';
|
||||
import Header from './Header.json';
|
||||
import HotkeysValidators from './HotkeysValidators.json';
|
||||
import MeasurementTable from './MeasurementTable.json';
|
||||
import DataRow from './DataRow.json';
|
||||
import Modes from './Modes.json';
|
||||
import SegmentationTable from './SegmentationTable.json';
|
||||
import SegmentationPanel from './SegmentationPanel.json';
|
||||
import SidePanel from './SidePanel.json';
|
||||
import StudyBrowser from './StudyBrowser.json';
|
||||
import StudyItem from './StudyItem.json';
|
||||
@ -25,6 +26,11 @@ import CaptureViewportModal from './CaptureViewportModal.json';
|
||||
import Hps from './Hps.json';
|
||||
import ToolbarLayoutSelector from './ToolbarLayoutSelector.json';
|
||||
import Tools from './Tools.json';
|
||||
import Onboarding from './Onboarding.json';
|
||||
import Colormaps from './Colormaps.json';
|
||||
import PanelSUV from './PanelSUV.json';
|
||||
import ROIThresholdConfiguration from './ROIThresholdConfiguration.json';
|
||||
import USAnnotationPanel from './USAnnotationPanel.json';
|
||||
|
||||
export default {
|
||||
'en-US': {
|
||||
@ -38,8 +44,9 @@ export default {
|
||||
Header,
|
||||
HotkeysValidators,
|
||||
MeasurementTable,
|
||||
DataRow,
|
||||
Modes,
|
||||
SegmentationTable,
|
||||
SegmentationPanel,
|
||||
SidePanel,
|
||||
StudyBrowser,
|
||||
StudyItem,
|
||||
@ -55,5 +62,10 @@ export default {
|
||||
Hps,
|
||||
ToolbarLayoutSelector,
|
||||
Tools,
|
||||
Onboarding,
|
||||
Colormaps,
|
||||
PanelSUV,
|
||||
ROIThresholdConfiguration,
|
||||
USAnnotationPanel,
|
||||
},
|
||||
};
|
||||
|
||||
10
platform/i18n/src/locales/es/DataRow.json
Normal file
10
platform/i18n/src/locales/es/DataRow.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"Hide": "Ocultar",
|
||||
"Show": "Mostrar",
|
||||
"Rename": "Renombrar",
|
||||
"Duplicate": "Duplicar",
|
||||
"Delete": "Borrar",
|
||||
"Change Color": "Cambiar color",
|
||||
"Lock": "Bloquear",
|
||||
"Unlock": "Desbloquear"
|
||||
}
|
||||
@ -5,6 +5,7 @@ import Common from './Common.json';
|
||||
import DatePicker from './DatePicker.json';
|
||||
import Header from './Header.json';
|
||||
import MeasurementTable from './MeasurementTable.json';
|
||||
import DataRow from './DataRow.json';
|
||||
import SidePanel from './SidePanel.json';
|
||||
import StudyBrowser from './StudyBrowser.json';
|
||||
import StudyList from './StudyList.json';
|
||||
@ -20,6 +21,7 @@ export default {
|
||||
DatePicker,
|
||||
Header,
|
||||
MeasurementTable,
|
||||
DataRow,
|
||||
SidePanel,
|
||||
StudyBrowser,
|
||||
StudyList,
|
||||
|
||||
16
platform/i18n/src/locales/fr/AboutModal.json
Normal file
16
platform/i18n/src/locales/fr/AboutModal.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"About OHIF Viewer": "À propos d'OHIF Viewer",
|
||||
"Browser": "Navigateur",
|
||||
"Build number": "Numéro de build",
|
||||
"Last master commits": "Derniers commits sur master",
|
||||
"More details": "Plus de détails",
|
||||
"Name": "Nom",
|
||||
"OS": "Système d'exploitation",
|
||||
"Report an issue": "Signaler un problème",
|
||||
"Repository URL": "URL du dépôt",
|
||||
"Value": "Valeur",
|
||||
"Version information": "Informations sur la version",
|
||||
"Visit the forum": "Visiter le forum",
|
||||
"Commit Hash": "Numéro hash du commit",
|
||||
"Current Browser & OS": "Navigateur et système d'exploitation actuels"
|
||||
}
|
||||
@ -1,42 +1,131 @@
|
||||
{
|
||||
"Acquired": "Acquis",
|
||||
"Angle": "Angle",
|
||||
"Annotation": "Annotation",
|
||||
"Arrow Annotate": "Annotation en flèche",
|
||||
"Axial": "Axial",
|
||||
"Bidirectional": "Bi-directionel",
|
||||
"Bidirectional Tool": "Outil bidirectionnel",
|
||||
"Bidirectional": "Bidirectionnel",
|
||||
"Bone": "Osseux",
|
||||
"Brain": "Cérébral",
|
||||
"Brush": "Brosse",
|
||||
"CINE": "Ciné",
|
||||
"Cancel": "Annuler",
|
||||
"Capture": "Capturer",
|
||||
"Cine": "Ciné",
|
||||
"CINE": "Ciné",
|
||||
"Circle": "Cercle",
|
||||
"Sphere": "Sphère",
|
||||
"Cobb Angle": "Angle Cobb",
|
||||
"Clear": "Effacer",
|
||||
"Coronal": "Coronal",
|
||||
"Crosshairs": "Repère",
|
||||
"Dicom Tag Browser": "Explorateur DICOM",
|
||||
"Dismiss Aspect": "Désactiver l'aspect",
|
||||
"Ellipse Tool": "Outil ellipse",
|
||||
"Ellipse": "Ellipse",
|
||||
"Elliptical": "Elliptique",
|
||||
"Flip H": "Flip H",
|
||||
"Flip V": "Flip V",
|
||||
"Flip H": "Retourner H",
|
||||
"Flip Horizontal": "Retourner horizontalement",
|
||||
"Flip Horizontally": "Retourner horizontalement",
|
||||
"Flip V": "Retourner V",
|
||||
"Freehand": "Main levée",
|
||||
"Freehand ROI": "ROI à main levée",
|
||||
"Spline ROI": "ROI spline",
|
||||
"Livewire tool": "Outil Livewire",
|
||||
"Livewire Contour": "Contour Livewire",
|
||||
"Grid Layout": "Disposition en grille",
|
||||
"Invert Colors": "Inverser les couleurs",
|
||||
"Invert": "Inverser",
|
||||
"Image Overlay": "Superposition d'image",
|
||||
"Image Slice Sync": "Synchronisation des coupes d'image",
|
||||
"Keep Aspect": "Conserver les proportions",
|
||||
"Layout": "$t(Common:Layout)",
|
||||
"Length Tool": "Outil de longueur",
|
||||
"Length": "Longueur",
|
||||
"Levels": "Niveaux",
|
||||
"Liver": "Foie",
|
||||
"Lung": "Poumon",
|
||||
"Magnify": "Agrandir",
|
||||
"Magnify Probe": "Sonde de grossissement",
|
||||
"Manual": "Manuel",
|
||||
"Measurements": "Mesures",
|
||||
"More Measure Tools": "Plus d'outils de mesure",
|
||||
"More Tools": "Plus d'outils",
|
||||
"More": "$t(Common:More)",
|
||||
"Next": "$t(Common:Next)",
|
||||
"Pan": "Déplacer",
|
||||
"Play": "$t(Common:Play)",
|
||||
"Previous": "$t(Common:Previous)",
|
||||
"Probe": "Sonde",
|
||||
"ROI Window": "ROI fenêtrage",
|
||||
"Colorbar": "Barre de couleurs",
|
||||
"Rectangle": "Rectangle",
|
||||
"Rectangle ROI Threshold": "Seuil ROI rectangle",
|
||||
"Reference Lines": "Lignes de référence",
|
||||
"Reset to defaults": "Réinitialiser les valeurs par défaut",
|
||||
"Reset View": "Réinitialiser la vue",
|
||||
"Reset": "$t(Common:Reset)",
|
||||
"Reset to defaults": "Valeurs d'usine",
|
||||
"ROI Window": "Fenêtre ROI",
|
||||
"Rotate +90": "Rotation +90°",
|
||||
"Rotate Right": "Tourner à droite",
|
||||
"Sagittal": "Sagittal",
|
||||
"Save": "Sauvegarder",
|
||||
"Stack Scroll": "Défilement",
|
||||
"Soft tissue": "Tissus mous",
|
||||
"Stack Image Sync": "Synchronisation des piles",
|
||||
"Stack Scroll": "Défilement de pile",
|
||||
"Stop": "$t(Common:Stop)",
|
||||
"Themes": "Themes",
|
||||
"Zoom": "Zoom"
|
||||
"Themes": "Thèmes",
|
||||
"Toggle Image Overlay": "Basculer la superposition d'image",
|
||||
"Click to show or hide segment labels when hovering with your mouse.": "Cliquez pour afficher ou masquer les étiquettes de segment lorsque vous survolez avec la souris.",
|
||||
"Ultrasound Directional": "Ultrason directionnel",
|
||||
"Window Level Region": "Fenêtre/Niveau régional",
|
||||
"W/L Presets": "Préréglages W/L",
|
||||
"Window Level": "Fenêtre/Niveau",
|
||||
"Segment Label Display": "Affichage des étiquettes de segment",
|
||||
"Zoom": "Zoom",
|
||||
"3D Rotate": "Rotation 3D",
|
||||
"Shape": "Forme",
|
||||
"Eraser": "Gomme",
|
||||
"Threshold Tool": "Outil seuil",
|
||||
"Threshold Tools": "Outils",
|
||||
"Threshold": "Seuil",
|
||||
"Shapes": "Formes",
|
||||
"Not available on the current viewport": "Non disponible sur la fenêtre d'affichage actuelle",
|
||||
"Select an MPR viewport to enable this tool": "Sélectionnez une vue MPR pour activer cet outil",
|
||||
"Select a 3D viewport to enable this tool": "Sélectionnez une vue 3D pour activer cet outil",
|
||||
"Select the PT Axial to enable this tool": "Sélectionnez la coupe axiale PT pour activer cet outil",
|
||||
"Tool not available for this modality": "Outil non disponible pour cette modalité",
|
||||
"Create new segmentation to enable this tool.": "Créez une segmentation pour activer cet outil.",
|
||||
"Freehand Segmentation": "Segmentation à main levée",
|
||||
"Spline Contour Segmentation Tool": "Outil de segmentation de contour spline",
|
||||
"Sculptor Tool": "Outil de sculpture",
|
||||
"Interpolate Contours": "Interpoler les contours",
|
||||
"Spline Type": "Type de spline",
|
||||
"Catmull Rom Spline": "Spline Catmull-Rom",
|
||||
"Linear Spline": "Spline linéaire",
|
||||
"B-Spline": "B-spline",
|
||||
"Simplified Spline": "Spline simplifiée",
|
||||
"Dynamic Cursor Size": "Taille du curseur dynamique",
|
||||
"No segmentations available": "Aucune segmentation disponible",
|
||||
"US Pleura B-line Annotation": "US Pleura B-line Annotation",
|
||||
"Arrow Annotate Tool": "Arrow Annotate Tool",
|
||||
"Labelmap Assist": "Assistance Labelmap",
|
||||
"Interpolate Labelmap": "Interpolation du labelmap",
|
||||
"One Click Segment": "Segmentation en un clic",
|
||||
"Marker Guided Labelmap": "Labelmap guidé par marqueurs",
|
||||
"Labelmap Edit with Contour Tool": "Outil d'édition de labelmap avec contour",
|
||||
"Toggle AI assistance for segmenting nearby slices. After drawing on a slice, scroll to preview predictions. Press Enter to accept or Esc to skip.": "Activer l'assistance IA pour segmenter les coupes voisines. Après avoir dessiné sur une coupe, faites défiler pour prévisualiser les prédictions. Appuyez sur Entrée pour accepter ou Échap pour ignorer.",
|
||||
"Automatically detects the largest length and width across slices for the selected segment and displays a bidirectional measurement.": "Détecte automatiquement la plus grande longueur et la plus grande largeur à travers les coupes pour le segment sélectionné et affiche une mesure bidirectionnelle.",
|
||||
"Detects segmentable regions with one click. Hover for visual feedback—click when a plus sign appears to auto-segment the lesion.": "Détecte les régions segmentables en un clic. Survolez pour un retour visuel — cliquez lorsque le signe plus apparaît pour segmenter automatiquement la lésion.",
|
||||
"Use include/exclude markers to guide AI (SAM) segmentation. Click to place markers, Enter to accept results, Esc to reject, and N to go to the next slice while keeping markers.": "Utilisez des marqueurs d'inclusion/exclusion pour guider la segmentation IA (SAM). Cliquez pour placer des marqueurs, Entrée pour accepter les résultats, Échap pour rejeter, et N pour passer à la coupe suivante en conservant les marqueurs."
|
||||
,
|
||||
"Automatically fill in missing slices between drawn segments. Use brush or threshold tools on at least two slices, then click to interpolate across slices. Works in any direction. Volume must be reconstructable.": "Remplit automatiquement les coupes manquantes entre les segments dessinés. Utilisez les outils brosse ou seuillage sur au moins deux coupes, puis cliquez pour interpoler entre les coupes. Fonctionne dans toutes les directions. Le volume doit être reconstruisible."
|
||||
,
|
||||
"Marker Mode": "Mode marqueur",
|
||||
"Include": "Inclure",
|
||||
"Exclude": "Exclure",
|
||||
"Clear Markers": "Effacer les marqueurs"
|
||||
,
|
||||
"Radius (mm)": "Rayon (mm)",
|
||||
"Dynamic": "Dynamique",
|
||||
"Range": "Plage"
|
||||
}
|
||||
|
||||
54
platform/i18n/src/locales/fr/CaptureViewportModal.json
Normal file
54
platform/i18n/src/locales/fr/CaptureViewportModal.json
Normal file
@ -0,0 +1,54 @@
|
||||
{
|
||||
"Capture": "Capture",
|
||||
"Cancel": "$t(Common:Cancel)",
|
||||
"Download": "$t(Common:Download)",
|
||||
"Image size": "Taille de l'image",
|
||||
"Image size in pixels": "Taille de l'image en pixels",
|
||||
"File name": "Nom du fichier",
|
||||
"Viewport to capture": "Fenêtre à capturer",
|
||||
"Viewport Settings": "Paramètres de la fenêtre",
|
||||
"General Settings": "Paramètres généraux",
|
||||
"Resolution": "Résolution",
|
||||
"Aspect Ratio": "Rapport d'aspect",
|
||||
"Region of interest": "Région d'intérêt",
|
||||
"Include annotations": "Inclure les annotations",
|
||||
"Include measurements": "Inclure les mesures",
|
||||
"Include patient info": "Inclure les informations patient",
|
||||
"Include warning message": "Inclure un message d'avertissement",
|
||||
"Width": "Largeur",
|
||||
"Height": "Hauteur",
|
||||
"Annotate on the capture": "Annoter sur la capture",
|
||||
"Reset to defaults": "$t(Common:Reset)",
|
||||
"Capture Options": "Options de capture",
|
||||
"Add capture to reports": "Ajouter la capture aux rapports",
|
||||
"Name": "Nom",
|
||||
"Description": "Description",
|
||||
"Create a new report or select an existing one to add the capture to": "Créer un nouveau rapport ou en sélectionner un existant pour y ajouter la capture",
|
||||
"Create new report": "Créer un nouveau rapport",
|
||||
"Add to existing report": "Ajouter à un rapport existant",
|
||||
"Select report": "Sélectionner un rapport",
|
||||
"Add capture": "Ajouter la capture",
|
||||
"New report name": "Nom du nouveau rapport",
|
||||
"New report description": "Description du nouveau rapport",
|
||||
"Add capture to": "Ajouter la capture à",
|
||||
"Selected report": "Rapport sélectionné",
|
||||
"Capture options": "Options de capture",
|
||||
"Fill background color": "Remplir avec la couleur de fond",
|
||||
"Set to black": "Définir sur noir",
|
||||
"Set to white": "Définir sur blanc",
|
||||
"Set to image": "Définir selon l'image",
|
||||
"Reset": "$t(Common:Reset)",
|
||||
"Invert colors": "Inverser les couleurs",
|
||||
"Apply changes": "Appliquer les modifications",
|
||||
"Active viewport": "Fenêtre active",
|
||||
"Thumbnail": "Vignette",
|
||||
"Capture viewport": "Capturer la fenêtre",
|
||||
"Apply ROI": "Appliquer le ROI",
|
||||
"Actions": "Actions",
|
||||
"Reset capture options": "Réinitialiser les options de capture",
|
||||
"Clear selection": "Effacer la sélection",
|
||||
"Add capture to report": "Ajouter la capture au rapport",
|
||||
"Report name": "Nom du rapport",
|
||||
"Report description": "Description du rapport",
|
||||
"Error capturing viewport": "Erreur lors de la capture de la fenêtre"
|
||||
}
|
||||
15
platform/i18n/src/locales/fr/Colormaps.json
Normal file
15
platform/i18n/src/locales/fr/Colormaps.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"Grayscale": "Niveaux de gris",
|
||||
"X Ray": "Rayons X",
|
||||
"Isodose": "Isodose",
|
||||
"hsv": "HSV",
|
||||
"hot_iron": "Fer chaud",
|
||||
"red_hot": "Rouge incandescent",
|
||||
"s_pet": "TEP",
|
||||
"perfusion": "Perfusion",
|
||||
"rainbow_2": "Arc-en-ciel",
|
||||
"suv": "SUV",
|
||||
"ge_256": "GE 256",
|
||||
"ge": "GE",
|
||||
"siemens": "Siemens"
|
||||
}
|
||||
@ -1,10 +1,29 @@
|
||||
{
|
||||
"Back to": "Retour à {{location}}",
|
||||
"Cancel": "Annuler",
|
||||
"Close": "Fermer",
|
||||
"Enter your annotation": "Saisissez votre annotation",
|
||||
"Image": "Image",
|
||||
"Layout": "Disposition",
|
||||
"LOAD": "CHARGER",
|
||||
"Measurements": "Mesures",
|
||||
"mm": "mm",
|
||||
"More": "Plus",
|
||||
"Next": "Suivant",
|
||||
"Play": "Play",
|
||||
"No": "Non",
|
||||
"NoStudyDate": "Pas de date d'étude",
|
||||
"localDateFormat": "DD MMM YYYY",
|
||||
"Play": "Lecture",
|
||||
"Previous": "Précédent",
|
||||
"Reset": "Reset",
|
||||
"Stop": "Stop"
|
||||
"Reset": "Réinitialiser",
|
||||
"RowsPerPage": "Lignes par page",
|
||||
"Save": "Enregistrer",
|
||||
"Series": "Séries",
|
||||
"Show": "Afficher",
|
||||
"Stop": "Arrêter",
|
||||
"StudyDate": "Date d'étude",
|
||||
"Yes": "Oui",
|
||||
"Foreground": "Avant-plan",
|
||||
"SELECT A FOREGROUND": "SÉLECTIONNER UN AVANT-PLAN",
|
||||
"SELECT A SEGMENTATION": "SÉLECTIONNER UNE SEGMENTATION"
|
||||
}
|
||||
|
||||
4
platform/i18n/src/locales/fr/ContextMenu.json
Normal file
4
platform/i18n/src/locales/fr/ContextMenu.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"Add Label": "Ajouter une étiquette",
|
||||
"Delete measurement": "Supprimer la mesure"
|
||||
}
|
||||
10
platform/i18n/src/locales/fr/DataRow.json
Normal file
10
platform/i18n/src/locales/fr/DataRow.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"Hide": "Masquer",
|
||||
"Show": "Afficher",
|
||||
"Rename": "Renommer",
|
||||
"Duplicate": "Dupliquer",
|
||||
"Delete": "Supprimer",
|
||||
"Change Color": "Changer la couleur",
|
||||
"Lock": "Verrouiller",
|
||||
"Unlock": "Déverrouiller"
|
||||
}
|
||||
13
platform/i18n/src/locales/fr/DatePicker.json
Normal file
13
platform/i18n/src/locales/fr/DatePicker.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"Clear dates": "Effacer les dates",
|
||||
"Close": "$t(Common:Close)",
|
||||
"End Date": "Date de fin",
|
||||
"Last 7 days": "7 derniers jours",
|
||||
"Last 30 days": "30 derniers jours",
|
||||
"Start Date": "Date de début",
|
||||
"Today": "Aujourd'hui",
|
||||
"Previous Month": "Mois précédent",
|
||||
"Next Month": "Mois suivant",
|
||||
"Select Month": "Sélectionner un mois",
|
||||
"Select Year": "Sélectionner une année"
|
||||
}
|
||||
6
platform/i18n/src/locales/fr/Dialog.json
Normal file
6
platform/i18n/src/locales/fr/Dialog.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"Enter your annotation": "$t(Common:Enter your annotation)",
|
||||
"Cancel": "$t(Common:Cancel)",
|
||||
"Save": "$t(Common:Save)",
|
||||
"Provide a name for your report": "Indiquez un nom pour votre rapport"
|
||||
}
|
||||
7
platform/i18n/src/locales/fr/ErrorBoundary.json
Normal file
7
platform/i18n/src/locales/fr/ErrorBoundary.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"Sorry, something went wrong there. Try again.": "Désolé, une erreur est survenue. Réessayez.",
|
||||
"Context": "Contexte",
|
||||
"Error Message": "Message d'erreur",
|
||||
"Stack": "Pile",
|
||||
"Something went wrong": "Une erreur s'est produite"
|
||||
}
|
||||
14
platform/i18n/src/locales/fr/Hps.json
Normal file
14
platform/i18n/src/locales/fr/Hps.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"MPR": "MPR",
|
||||
"3D four up": "3D quatre vues",
|
||||
"Frame View": "Vue par image",
|
||||
"Frame view for the active series": "Vue image par image pour la série active",
|
||||
"3D main": "Vue principale 3D",
|
||||
"mpr": "mpr",
|
||||
"3D only": "3D seulement",
|
||||
"3D primary": "3D principale",
|
||||
"Axial Primary": "Axial principal",
|
||||
"Compare Two Studies": "Comparer deux études",
|
||||
"Compare two studies in various layouts": "Comparer deux études avec différentes dispositions",
|
||||
"Mammography Breast Screening": "Dépistage mammographique"
|
||||
}
|
||||
4
platform/i18n/src/locales/fr/Local.json
Normal file
4
platform/i18n/src/locales/fr/Local.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"Load files": "Charger des fichiers",
|
||||
"Load folders": "Charger des dossiers"
|
||||
}
|
||||
26
platform/i18n/src/locales/fr/MeasurementTable.json
Normal file
26
platform/i18n/src/locales/fr/MeasurementTable.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"Criteria nonconformities": "Non-conformités aux critères",
|
||||
"Delete": "Supprimer",
|
||||
"Description": "Description",
|
||||
"MAX": "MAX",
|
||||
"NonTargets": "Non-cibles",
|
||||
"Relabel": "Renommer",
|
||||
"Measurements": "Mesures",
|
||||
"Targets": "Cibles",
|
||||
"Rename": "Renommer",
|
||||
"Duplicate": "Dupliquer",
|
||||
"Change Color": "Changer la couleur",
|
||||
"Lock": "Verrouiller",
|
||||
"Unlock": "Déverrouiller",
|
||||
"Hide": "Masquer",
|
||||
"Show": "Afficher",
|
||||
"No, do not ask again": "Non, ne plus demander",
|
||||
"Create SR": "Créer SR",
|
||||
"empty": "(vide)",
|
||||
"Export CSV": "Exporter CSV",
|
||||
"No tracked measurements": "Aucune mesure suivie",
|
||||
"Export": "Exporter",
|
||||
"Create Report": "Créer un rapport",
|
||||
"Do you want to add this measurement to the existing report?": "Souhaitez-vous ajouter cette mesure au rapport existant ?",
|
||||
"Track measurements for this series?": "Suivre les mesures pour cette série ?"
|
||||
}
|
||||
19
platform/i18n/src/locales/fr/Modals.json
Normal file
19
platform/i18n/src/locales/fr/Modals.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"Active viewport has no displayed image": "La vue active n'affiche aucune image",
|
||||
"Cancel": "$t(Common:Cancel)",
|
||||
"Download": "Télécharger",
|
||||
"The file name cannot be empty.": "Le nom du fichier ne peut pas être vide.",
|
||||
"File Type": "Type de fichier",
|
||||
"File Name": "Nom du fichier",
|
||||
"formTitle": "Veuillez préciser les dimensions, le nom de fichier et le type souhaité pour l'image exportée.",
|
||||
"Image height (px)": "Hauteur de l'image (px)",
|
||||
"Image Preview": "Aperçu de l'image",
|
||||
"Image preview": "Aperçu de l'image",
|
||||
"Image width (px)": "Largeur de l'image (px)",
|
||||
"keepAspectRatio": "Conserver les proportions",
|
||||
"loadingPreview": "Chargement de l'aperçu de l'image...",
|
||||
"The minimum valid height is 100px.": "La hauteur minimale autorisée est de 100 px.",
|
||||
"The minimum valid width is 100px.": "La largeur minimale autorisée est de 100 px.",
|
||||
"Show Annotations": "Afficher les annotations",
|
||||
"Please specify the dimensions, filename, and desired type for the output image.": "Veuillez préciser les dimensions, le nom de fichier et le type souhaité pour l'image exportée."
|
||||
}
|
||||
6
platform/i18n/src/locales/fr/Modes.json
Normal file
6
platform/i18n/src/locales/fr/Modes.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"Basic Viewer": "Visionneuse de base",
|
||||
"Total Metabolic Tumor Volume": "Volume tumoral métabolique total",
|
||||
"Download High Quality Image": "Télécharger une image haute qualité",
|
||||
"US Pleura B-line Annotations": "Annotations de plèvre et lignes B en échographie"
|
||||
}
|
||||
18
platform/i18n/src/locales/fr/Notification.json
Normal file
18
platform/i18n/src/locales/fr/Notification.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"Do you want to add this measurement to the existing report?": "Souhaitez-vous ajouter cette mesure au rapport existant ?",
|
||||
"Create new report": "Créer un nouveau rapport",
|
||||
"Add to existing report": "Ajouter au rapport existant",
|
||||
"Discard": "Ignorer",
|
||||
"You have existing tracked measurements. What would you like to do with your existing tracked measurements?": "Des mesures suivies existent déjà. Que souhaitez-vous en faire ?",
|
||||
"No, do not ask again for this series": "Non, ne plus demander pour cette série",
|
||||
"No": "$t(Common:No)",
|
||||
"Track measurements for this series?": "Suivre les mesures pour cette série ?",
|
||||
"Yes": "$t(Common:Yes)",
|
||||
"Cancel": "$t(Common:Cancel)",
|
||||
"Measurements cannot span across multiple studies. Do you want to save your tracked measurements?": "Les mesures ne peuvent pas couvrir plusieurs études. Voulez-vous enregistrer vos mesures suivies ?",
|
||||
"No, discard previously tracked series & measurements": "Non, abandonner les séries et mesures suivies précédemment",
|
||||
"Do you want to continue tracking measurements for this study?": "Souhaitez-vous continuer à suivre les mesures pour cette étude ?",
|
||||
"Create Report": "Créer un rapport",
|
||||
"Measurements saved successfully": "Mesures enregistrées avec succès",
|
||||
"Failed to store measurements": "Échec de l'enregistrement des mesures"
|
||||
}
|
||||
27
platform/i18n/src/locales/fr/Onboarding.json
Normal file
27
platform/i18n/src/locales/fr/Onboarding.json
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"Scrolling Through Images": "Défilement des images",
|
||||
"You can scroll through the images using the mouse wheel or scrollbar.": "Vous pouvez faire défiler les images avec la molette de la souris ou la barre de défilement.",
|
||||
"Zooming In and Out": "Zoom avant et arrière",
|
||||
"You can zoom the images using the right click.": "Vous pouvez zoomer sur les images avec le clic droit.",
|
||||
"Panning the Image": "Déplacement de l'image",
|
||||
"You can pan the images using the middle click.": "Vous pouvez déplacer l'image avec le clic du milieu.",
|
||||
"Adjusting Window Level": "Ajuster la fenêtre et le niveau",
|
||||
"You can modify the window level using the left click.": "Vous pouvez modifier la fenêtre et le niveau avec le clic gauche.",
|
||||
"Using the Measurement Tools": "Utiliser les outils de mesure",
|
||||
"You can measure the length of a region using the Length tool.": "Vous pouvez mesurer la longueur d'une région avec l'outil Longueur.",
|
||||
"Drawing Length Annotations": "Tracer des annotations de longueur",
|
||||
"Use the length tool on the viewport to measure the length of a region.": "Utilisez l'outil Longueur dans la vue pour mesurer une région.",
|
||||
"Tracking Measurements in the Panel": "Suivre les mesures dans le panneau",
|
||||
"Click yes to track the measurements in the measurement panel.": "Cliquez sur Oui pour suivre les mesures dans le panneau des mesures.",
|
||||
"Opening the Measurements Panel": "Ouvrir le panneau des mesures",
|
||||
"Click the measurements button to open the measurements panel.": "Cliquez sur le bouton Mesures pour ouvrir le panneau des mesures.",
|
||||
"Scrolling Away from a Measurement": "Défiler loin d'une mesure",
|
||||
"Scroll the images using the mouse wheel away from the measurement.": "Défilez avec la molette pour vous éloigner de la mesure.",
|
||||
"Jumping to Measurements in the Panel": "Aller à une mesure depuis le panneau",
|
||||
"Click the measurement in the measurement panel to jump to it.": "Cliquez sur la mesure dans le panneau pour y accéder.",
|
||||
"Changing Layout": "Changer de disposition",
|
||||
"You can change the layout of the viewer using the layout button.": "Vous pouvez changer la disposition via le bouton Disposition.",
|
||||
"Selecting the MPR Layout": "Sélectionner la disposition MPR",
|
||||
"Select the MPR layout to view the images in MPR mode.": "Sélectionnez la disposition MPR pour afficher les images en mode MPR.",
|
||||
"Skip all": "Tout passer"
|
||||
}
|
||||
10
platform/i18n/src/locales/fr/PanelSUV.json
Normal file
10
platform/i18n/src/locales/fr/PanelSUV.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"Patient Information": "Informations patient",
|
||||
"Patient Sex": "Sexe du patient",
|
||||
"Weight": "Poids",
|
||||
"Total Dose": "Dose totale",
|
||||
"Half Life": "Demi-vie",
|
||||
"Injection Time": "Heure d'injection",
|
||||
"Acquisition Time": "Heure d'acquisition",
|
||||
"Reload Data": "Recharger les données"
|
||||
}
|
||||
8
platform/i18n/src/locales/fr/PatientInfo.json
Normal file
8
platform/i18n/src/locales/fr/PatientInfo.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"Sex": "Sexe",
|
||||
"Age": "Âge",
|
||||
"MRN": "MRN",
|
||||
"Thickness": "Épaisseur",
|
||||
"Spacing": "Espacement",
|
||||
"Scanner": "Scanner"
|
||||
}
|
||||
11
platform/i18n/src/locales/fr/ROIThresholdConfiguration.json
Normal file
11
platform/i18n/src/locales/fr/ROIThresholdConfiguration.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"Max": "Max",
|
||||
"Range": "Plage",
|
||||
"Start": "Début",
|
||||
"End": "Fin",
|
||||
"Percentage of Max SUV": "Pourcentage du SUV max",
|
||||
"Lower & Upper Ranges": "Plages inférieure et supérieure",
|
||||
"Run": "Exécuter",
|
||||
"Threshold Tools": "Outils de seuillage",
|
||||
"ThresholdRange": "Seuillage"
|
||||
}
|
||||
52
platform/i18n/src/locales/fr/SegmentationPanel.json
Normal file
52
platform/i18n/src/locales/fr/SegmentationPanel.json
Normal file
@ -0,0 +1,52 @@
|
||||
{
|
||||
"Opacity": "Opacité",
|
||||
"Border": "Bordure",
|
||||
"Show": "Afficher",
|
||||
"Fill & Outline": "Remplissage et contour",
|
||||
"Outline Only": "Contour uniquement",
|
||||
"Fill Only": "Remplissage uniquement",
|
||||
"Display inactive segmentations": "Afficher les segmentations inactives",
|
||||
"Select a segmentation": "Sélectionner une segmentation",
|
||||
"Segmentation": "Segmentation",
|
||||
"Segmentations": "Segmentations",
|
||||
"Add Segment": "Ajouter un segment",
|
||||
"Contour tools": "Outils contour",
|
||||
"Preview edits before creating": "Prévisualiser les modifications avant la création",
|
||||
"Use center as segment index": "Utiliser le centre comme indice de segment",
|
||||
"Hover on segment border to activate": "Survoler le bord du segment pour activer",
|
||||
"Show segment name on hover": "Afficher le nom du segment au survol",
|
||||
"Add segmentation": "Ajouter une segmentation",
|
||||
"Create New Segmentation": "Créer une nouvelle segmentation",
|
||||
"Manage Current Segmentation": "Gérer la segmentation actuelle",
|
||||
"Remove from Viewport": "Retirer de la vue",
|
||||
"Rename": "Renommer",
|
||||
"Delete": "Supprimer",
|
||||
"Labelmap tools": "Outils labelmap",
|
||||
"Labelmap Segmentations": "Segmentations du labelmap",
|
||||
"Download & Export": "Télécharger et exporter",
|
||||
"Download": "Télécharger",
|
||||
"Export": "Exporter",
|
||||
"CSV Report": "Rapport CSV",
|
||||
"DICOM SEG": "DICOM SEG",
|
||||
"DICOM RTSS": "DICOM RTSS",
|
||||
"Download DICOM RTSS": "Télécharger DICOM RTSS",
|
||||
"Fill contour holes": "Remplir les trous de contour",
|
||||
"Fill Holes": "Remplir les trous",
|
||||
"Remove Small Contours": "Supprimer les petits contours",
|
||||
"Area Threshold": "Seuil de surface",
|
||||
"Create New Segment from Holes": "Créer un nouveau segment à partir des trous",
|
||||
"Create New Segment": "Créer un nouveau segment",
|
||||
"Smooth all edges": "Lisser tous les bords",
|
||||
"Smooth Edges": "Lisser les bords",
|
||||
"Remove extra points": "Supprimer les points supplémentaires",
|
||||
"Remove Points": "Supprimer les points",
|
||||
"Merge": "Fusionner",
|
||||
"Intersect": "Intersection",
|
||||
"Subtract": "Soustraire",
|
||||
"Select a segment": "Sélectionner un segment",
|
||||
"Create a new segment": "Créer un nouveau segment",
|
||||
"New segment name": "Nom du nouveau segment",
|
||||
"No segmentations available": "Aucune segmentation disponible",
|
||||
"Not available on the current viewport": "Non disponible sur la fenêtre d'affichage actuelle",
|
||||
"Add segment to enable this tool": "Ajoutez un segment pour activer cet outil"
|
||||
}
|
||||
6
platform/i18n/src/locales/fr/SidePanel.json
Normal file
6
platform/i18n/src/locales/fr/SidePanel.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"Studies": "Études",
|
||||
"Measurements": "Mesures",
|
||||
"Measure": "Mesurer",
|
||||
"Segmentation": "Segmentation"
|
||||
}
|
||||
12
platform/i18n/src/locales/fr/StudyBrowser.json
Normal file
12
platform/i18n/src/locales/fr/StudyBrowser.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"Primary": "Principal",
|
||||
"Recent": "Récents",
|
||||
"All": "Tous",
|
||||
"Tracked Series": "Séries suivies",
|
||||
"Tag Browser": "Explorateur DICOM",
|
||||
"Add as Layer": "Ajouter en tant que couche",
|
||||
"Series Number": "Numéro de série",
|
||||
"Series Date": "Date de la série",
|
||||
"Thumbnail Double Click": "Double-clic sur la vignette",
|
||||
"The selected display sets could not be added to the viewport.": "Les ensembles d'affichage sélectionnés n'ont pas pu être ajoutés à la fenêtre."
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user