From 1bf651e7639673461f0efbfa2b288a76bef9bc87 Mon Sep 17 00:00:00 2001 From: Alireza Date: Tue, 15 Jun 2021 10:56:33 -0400 Subject: [PATCH] feat: Added support for i18n (#2439) * Added translation for various react components in OHIF-v3 * Added a test language for debugging- test-LNG * Added copy for test language to not get overwritten --- extensions/default/src/ViewerLayout/index.jsx | 10 +++- .../ActionButtons.jsx | 10 ++-- platform/core/src/utils/Queue.test.js | 26 ++++----- platform/i18n/pullTranslations.sh | 2 + .../i18n/src/locales/es/MeasurementTable.json | 6 ++- platform/i18n/src/locales/index.js | 2 + .../src/locales/pt-BR/MeasurementTable.json | 4 ++ platform/i18n/src/locales/pt-BR/index.js | 2 + .../i18n/src/locales/test-LNG/AboutModal.json | 14 +++++ .../i18n/src/locales/test-LNG/Buttons.json | 54 +++++++++++++++++++ .../i18n/src/locales/test-LNG/CineDialog.json | 8 +++ .../i18n/src/locales/test-LNG/Common.json | 16 ++++++ .../i18n/src/locales/test-LNG/DatePicker.json | 5 ++ .../i18n/src/locales/test-LNG/Header.json | 6 +++ .../locales/test-LNG/MeasurementTable.json | 12 +++++ .../i18n/src/locales/test-LNG/Modals.json | 13 +++++ platform/i18n/src/locales/test-LNG/Modes.json | 3 ++ .../src/locales/test-LNG/PatientInfo.json | 8 +++ .../i18n/src/locales/test-LNG/SidePanel.json | 4 ++ .../src/locales/test-LNG/StudyBrowser.json | 5 ++ .../i18n/src/locales/test-LNG/StudyList.json | 21 ++++++++ .../i18n/src/locales/test-LNG/ToolTip.json | 3 ++ .../test-LNG/UserPreferencesModal.json | 14 +++++ .../test-LNG/ViewportDownloadForm.json | 14 +++++ platform/i18n/src/locales/test-LNG/index.js | 37 +++++++++++++ platform/i18n/src/utils.js | 1 + platform/ui/src/components/Header/Header.jsx | 4 +- .../HotkeysPreferences/HotkeysPreferences.jsx | 8 ++- .../InputLabelWrapper/InputLabelWrapper.jsx | 5 +- .../MeasurementTable/MeasurementTable.jsx | 7 ++- .../ui/src/components/SidePanel/SidePanel.jsx | 7 ++- .../components/SplitButton/SplitButton.jsx | 9 ++-- .../components/StudyBrowser/StudyBrowser.jsx | 5 +- .../StudyListExpandedRow.js | 6 ++- .../StudyListFilter/StudyListFilter.jsx | 10 ++-- .../StudyListPagination.js | 9 ++-- .../ui/src/components/Tooltip/Tooltip.jsx | 4 +- .../UserPreferences/UserPreferences.jsx | 8 +-- .../ViewportActionBar/ViewportActionBar.jsx | 15 +++--- .../ViewportDownloadForm.jsx | 24 +++++---- .../ui/src/contextProviders/ModalProvider.jsx | 5 +- .../viewer/src/routes/WorkList/WorkList.jsx | 2 +- 42 files changed, 365 insertions(+), 63 deletions(-) create mode 100644 platform/i18n/src/locales/pt-BR/MeasurementTable.json create mode 100644 platform/i18n/src/locales/test-LNG/AboutModal.json create mode 100644 platform/i18n/src/locales/test-LNG/Buttons.json create mode 100644 platform/i18n/src/locales/test-LNG/CineDialog.json create mode 100644 platform/i18n/src/locales/test-LNG/Common.json create mode 100644 platform/i18n/src/locales/test-LNG/DatePicker.json create mode 100644 platform/i18n/src/locales/test-LNG/Header.json create mode 100644 platform/i18n/src/locales/test-LNG/MeasurementTable.json create mode 100644 platform/i18n/src/locales/test-LNG/Modals.json create mode 100644 platform/i18n/src/locales/test-LNG/Modes.json create mode 100644 platform/i18n/src/locales/test-LNG/PatientInfo.json create mode 100644 platform/i18n/src/locales/test-LNG/SidePanel.json create mode 100644 platform/i18n/src/locales/test-LNG/StudyBrowser.json create mode 100644 platform/i18n/src/locales/test-LNG/StudyList.json create mode 100644 platform/i18n/src/locales/test-LNG/ToolTip.json create mode 100644 platform/i18n/src/locales/test-LNG/UserPreferencesModal.json create mode 100644 platform/i18n/src/locales/test-LNG/ViewportDownloadForm.json create mode 100644 platform/i18n/src/locales/test-LNG/index.js diff --git a/extensions/default/src/ViewerLayout/index.jsx b/extensions/default/src/ViewerLayout/index.jsx index 8069a7ba9..ae1c64618 100644 --- a/extensions/default/src/ViewerLayout/index.jsx +++ b/extensions/default/src/ViewerLayout/index.jsx @@ -10,6 +10,10 @@ import { useModal, } from '@ohif/ui'; +import i18n from '@ohif/i18n'; + +const { availableLanguages, defaultLanguage, currentLanguage } = i18n; + import { useAppConfig } from '@state'; function Toolbar({ servicesManager }) { @@ -108,8 +112,12 @@ function ViewerLayout({ hotkeyDefaults ), hotkeyDefinitions, + currentLanguage: currentLanguage(), + availableLanguages, + defaultLanguage, onCancel: hide, - onSubmit: ({ hotkeyDefinitions }) => { + onSubmit: ({ hotkeyDefinitions, language }) => { + i18n.changeLanguage(language.value); hotkeysManager.setHotkeys(hotkeyDefinitions); hide(); }, diff --git a/extensions/measurement-tracking/src/panels/PanelMeasurementTableTracking/ActionButtons.jsx b/extensions/measurement-tracking/src/panels/PanelMeasurementTableTracking/ActionButtons.jsx index 5842fe3c3..dfa35aaa8 100644 --- a/extensions/measurement-tracking/src/panels/PanelMeasurementTableTracking/ActionButtons.jsx +++ b/extensions/measurement-tracking/src/panels/PanelMeasurementTableTracking/ActionButtons.jsx @@ -1,13 +1,17 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Button, ButtonGroup, Icon, IconButton } from '@ohif/ui'; +import { useTranslation } from 'react-i18next'; + +import { Button, ButtonGroup } from '@ohif/ui'; function ActionButtons({ onExportClick, onCreateReportClick }) { + const { t } = useTranslation('MeasurementTable'); + return ( ); diff --git a/platform/core/src/utils/Queue.test.js b/platform/core/src/utils/Queue.test.js index c3c8401c1..23b31448d 100644 --- a/platform/core/src/utils/Queue.test.js +++ b/platform/core/src/utils/Queue.test.js @@ -15,18 +15,20 @@ function timeout(delay) { * Tests */ +const threshold = 2400 + describe('Queue', () => { it('should bind functions to the queue', async () => { const queue = new Queue(2); const mockedTimeout = jest.fn(timeout); const timer = queue.bind(mockedTimeout); const start = Date.now(); - timer(1200).then(now => { + timer(threshold).then(now => { const elapsed = now - start; - expect(elapsed >= 1200 && elapsed < 2400).toBe(true); + expect(elapsed >= threshold && elapsed < 2 * threshold).toBe(true); }); - const end = await timer(1200); - expect(end - start > 2400).toBe(true); + const end = await timer(threshold); + expect(end - start > 2 * threshold).toBe(true); expect(mockedTimeout).toBeCalledTimes(2); }); it('should prevent task execution when queue limit is reached', async () => { @@ -34,15 +36,15 @@ describe('Queue', () => { const mockedTimeout = jest.fn(timeout); const timer = queue.bind(mockedTimeout); const start = Date.now(); - const promise = timer(1200).then(time => time - start); + const promise = timer(threshold).then(time => time - start); try { - await timer(1200); + await timer(threshold); } catch (e) { - expect(Date.now() - start < 1200).toBe(true); + expect(Date.now() - start < threshold).toBe(true); expect(e.message).toBe('Queue limit reached'); } const elapsed = await promise; - expect(elapsed >= 1200 && elapsed < 2400).toBe(true); + expect(elapsed >= threshold && elapsed < 2 * threshold).toBe(true); expect(mockedTimeout).toBeCalledTimes(1); }); it('should safely bind tasks to the queue', async () => { @@ -51,16 +53,16 @@ describe('Queue', () => { const mockedTimeout = jest.fn(timeout); const timer = queue.bindSafe(mockedTimeout, mockedErrorHandler); const start = Date.now(); - const promise = timer(1200).then(time => time - start); - await timer(1200); - expect(Date.now() - start < 1200).toBe(true); + const promise = timer(threshold).then(time => time - start); + await timer(threshold); + expect(Date.now() - start < threshold).toBe(true); expect(mockedErrorHandler).toBeCalledTimes(1); expect(mockedErrorHandler).nthCalledWith( 1, expect.objectContaining({ message: 'Queue limit reached' }) ); const elapsed = await promise; - expect(elapsed >= 1200 && elapsed < 2400).toBe(true); + expect(elapsed >= threshold && elapsed < 2 * threshold).toBe(true); expect(mockedTimeout).toBeCalledTimes(1); }); }); diff --git a/platform/i18n/pullTranslations.sh b/platform/i18n/pullTranslations.sh index c22e6be53..4cd0d9815 100755 --- a/platform/i18n/pullTranslations.sh +++ b/platform/i18n/pullTranslations.sh @@ -1,6 +1,8 @@ +cp -r src/locales/test-LNG src/temp rm -rf src/locales/ mkdir -p src/locales/ cd src/locales/ npx locize --config-path ../../.locize download --ver latest cd ../../ node ./writeLocaleIndexFiles.js +cp -r src/temp src/locales/test-LNG diff --git a/platform/i18n/src/locales/es/MeasurementTable.json b/platform/i18n/src/locales/es/MeasurementTable.json index d00dce1d6..a67bada0a 100644 --- a/platform/i18n/src/locales/es/MeasurementTable.json +++ b/platform/i18n/src/locales/es/MeasurementTable.json @@ -5,5 +5,7 @@ "MAX": "Máximo", "NonTargets": "No objetivos", "Relabel": "Re-etiquetar", - "Targets": "Objetivos" -} \ No newline at end of file + "Targets": "Objetivos", + "Export": "Exportar", + "Create Report": "Crear reporte" +} diff --git a/platform/i18n/src/locales/index.js b/platform/i18n/src/locales/index.js index 06844360f..b950f9ab8 100644 --- a/platform/i18n/src/locales/index.js +++ b/platform/i18n/src/locales/index.js @@ -7,6 +7,7 @@ import nl from './nl/'; import pt_BR from './pt-BR/'; import vi from './vi/'; import zh from './zh/'; +import test_lng from './test-LNG/'; export default { ...ar, @@ -18,4 +19,5 @@ export default { ...pt_BR, ...vi, ...zh, + ...test_lng }; diff --git a/platform/i18n/src/locales/pt-BR/MeasurementTable.json b/platform/i18n/src/locales/pt-BR/MeasurementTable.json new file mode 100644 index 000000000..b1cd2bdad --- /dev/null +++ b/platform/i18n/src/locales/pt-BR/MeasurementTable.json @@ -0,0 +1,4 @@ +{ + "Export": "Exportar", + "Create Report": "Criar relatório" +} diff --git a/platform/i18n/src/locales/pt-BR/index.js b/platform/i18n/src/locales/pt-BR/index.js index 1b37dc9a6..0695b6869 100644 --- a/platform/i18n/src/locales/pt-BR/index.js +++ b/platform/i18n/src/locales/pt-BR/index.js @@ -5,6 +5,7 @@ import Common from './Common.json'; import DatePicker from './DatePicker.json'; import Header from './Header.json'; import UserPreferencesModal from './UserPreferencesModal.json'; +import MeasurementTable from './MeasurementTable.json'; export default { 'pt-BR': { @@ -15,5 +16,6 @@ export default { DatePicker, Header, UserPreferencesModal, + MeasurementTable, }, }; diff --git a/platform/i18n/src/locales/test-LNG/AboutModal.json b/platform/i18n/src/locales/test-LNG/AboutModal.json new file mode 100644 index 000000000..5ee8b5e24 --- /dev/null +++ b/platform/i18n/src/locales/test-LNG/AboutModal.json @@ -0,0 +1,14 @@ +{ + "Browser": "Browser", + "Build Number": "Build Number", + "Latest Master Commits": "Latest Master Commits", + "More details": "More details", + "Name": "Name", + "OHIF Viewer - About": "OHIF Viewer - About", + "OS": "OS", + "Report an issue": "Report an issue", + "Repository URL": "Repository URL", + "Value": "Value", + "Version Information": "Version Information", + "Visit the forum": "Visit the forum" +} \ No newline at end of file diff --git a/platform/i18n/src/locales/test-LNG/Buttons.json b/platform/i18n/src/locales/test-LNG/Buttons.json new file mode 100644 index 000000000..62e1cf81f --- /dev/null +++ b/platform/i18n/src/locales/test-LNG/Buttons.json @@ -0,0 +1,54 @@ +{ + "Acquired": "Test Acquired", + "Angle": "Test Angle", + "Axial": "Test Axial", + "Bidirectional": "Test Bidirectional", + "Brush": "Test Brush", + "CINE": "Test CINE", + "Cancel": "Test Cancel", + "Circle": "Test Circle", + "Clear": "Test Clear", + "Coronal": "Test Coronal", + "Crosshairs": "Test Crosshairs", + "Download": "Test Download", + "Ellipse": "Test Ellipse", + "Elliptical": "Test Elliptical", + "Flip H": "Test Flip H", + "Flip V": "Test Flip V", + "Freehand": "Test Freehand", + "Invert": "Test Invert", + "Layout": "Test $t(Common:Layout)", + "Length": "Test Length", + "Levels": "Test Levels", + "Magnify": "Test Magnify", + "Manual": "Test Manual", + "Measurements": "Test Measurements", + "More": "Test $t(Common:More)", + "Next": "Test $t(Common:Next)", + "Pan": "Test Pan", + "Play": "Test $t(Common:Play)", + "Previous": "Test $t(Common:Previous)", + "Probe": "Test Probe", + "ROI Window": "Test ROI Window", + "Rectangle": "Test Rectangle", + "Reset": "Test $t(Common:Reset)", + "Reset to Defaults": "Test $t(Common:Reset) to Defaults", + "Rotate Right": "Test Rotate Right", + "Sagittal": "Test Sagittal", + "Save": "Test Save", + "Stack Scroll": "Test Stack Scroll", + "Stop": "Test $t(Common:Stop)", + "Themes": "Test Themes", + "Zoom": "Test Zoom", + "Grid Layout": "Test Grid Layout", + "W/L Presets": "Test W/L Presets", + "More Measure Tools": "Test More Measure Tools", + "More Tools": "Test More Tools", + "Capture": "Test Capture", + "Annotation": "Test Annotation", + "Soft Tissue": "Test Soft Tissue", + "Lung": "Test Lung", + "Liver": "Test Liver", + "Bone": "Test Bone", + "Cine": "Test Cine" +} diff --git a/platform/i18n/src/locales/test-LNG/CineDialog.json b/platform/i18n/src/locales/test-LNG/CineDialog.json new file mode 100644 index 000000000..b9f6667a7 --- /dev/null +++ b/platform/i18n/src/locales/test-LNG/CineDialog.json @@ -0,0 +1,8 @@ +{ + "Next image": "$t(Common:Next) $t(Common:Image)", + "Play / Stop": "$t(Common:Play) / $t(Common:Stop)", + "Previous image": "$t(Common:Previous) $t(Common:Image)", + "Skip to first image": "Skip to first $t(Common:Image)", + "Skip to last image": "Skip to last $t(Common:Image)", + "fps": "fps" +} \ No newline at end of file diff --git a/platform/i18n/src/locales/test-LNG/Common.json b/platform/i18n/src/locales/test-LNG/Common.json new file mode 100644 index 000000000..9c29646fe --- /dev/null +++ b/platform/i18n/src/locales/test-LNG/Common.json @@ -0,0 +1,16 @@ +{ + "Close": "Test Close", + "Image": "Test Image", + "Layout": "Test Layout", + "Measurements": "Test Measurements", + "More": "Test More", + "Next": "Test Next", + "Play": "Test Play", + "Previous": "Test Previous", + "Reset": "Test Reset", + "RowsPerPage": "Test rows per page", + "Series": "Test Series", + "Show": "Test Show", + "Stop": "Test Stop", + "StudyDate": "Test Study Date" +} diff --git a/platform/i18n/src/locales/test-LNG/DatePicker.json b/platform/i18n/src/locales/test-LNG/DatePicker.json new file mode 100644 index 000000000..e2eb258de --- /dev/null +++ b/platform/i18n/src/locales/test-LNG/DatePicker.json @@ -0,0 +1,5 @@ +{ + "Clear dates": "Clear dates", + "End Date": "End Date", + "Start Date": "Start Date" +} \ No newline at end of file diff --git a/platform/i18n/src/locales/test-LNG/Header.json b/platform/i18n/src/locales/test-LNG/Header.json new file mode 100644 index 000000000..b36dcaedd --- /dev/null +++ b/platform/i18n/src/locales/test-LNG/Header.json @@ -0,0 +1,6 @@ +{ + "About": "Test About", + "INVESTIGATIONAL USE ONLY": "Test Investigational", + "Options": "Test Options", + "Preferences": "Test Preferences" +} diff --git a/platform/i18n/src/locales/test-LNG/MeasurementTable.json b/platform/i18n/src/locales/test-LNG/MeasurementTable.json new file mode 100644 index 000000000..70e04dea0 --- /dev/null +++ b/platform/i18n/src/locales/test-LNG/MeasurementTable.json @@ -0,0 +1,12 @@ +{ + "Measurements": "Test Measurements", + "No tracked measurements": "Test No tracked measurements", + "Create Report": "Test Create Report", + "Export": "Test Export", + "Delete": "Delete", + "Description": "Description", + "MAX": "MAX", + "NonTargets": "NonTargets", + "Relabel": "Relabel", + "Targets": "Targets" +} diff --git a/platform/i18n/src/locales/test-LNG/Modals.json b/platform/i18n/src/locales/test-LNG/Modals.json new file mode 100644 index 000000000..7bbbe0838 --- /dev/null +++ b/platform/i18n/src/locales/test-LNG/Modals.json @@ -0,0 +1,13 @@ +{ + "Download High Quality Image": "Test Download High Quality Image", + "Cancel": "Test Cancel", + "Download": "Test Download", + "File Name": "Test File Name", + "Active viewport has no displayed image": "Test Active viewport has no displayed image", + "Image preview": "Test Image preview", + "Show Annotations": "Test Show Annotations", + "File Type": "Test File Type", + "Image height (px)": "Test Image height (px)", + "Image width (px)": "Test Image width (px)", + "Please specify the dimensions, filename, and desired type for the output image.": "Test Please specify the dimensions, filename, and desired type for the output image." +} diff --git a/platform/i18n/src/locales/test-LNG/Modes.json b/platform/i18n/src/locales/test-LNG/Modes.json new file mode 100644 index 000000000..058e7d5c2 --- /dev/null +++ b/platform/i18n/src/locales/test-LNG/Modes.json @@ -0,0 +1,3 @@ +{ + "Basic Viewer": "Test Basic Viewer" +} diff --git a/platform/i18n/src/locales/test-LNG/PatientInfo.json b/platform/i18n/src/locales/test-LNG/PatientInfo.json new file mode 100644 index 000000000..658013fa1 --- /dev/null +++ b/platform/i18n/src/locales/test-LNG/PatientInfo.json @@ -0,0 +1,8 @@ +{ + "Age": "Test Age", + "Sex": "Test Sex", + "MRN": "Test MRN", + "Thickness": "Test Thickness", + "Spacing": "Test Spacing", + "Scanner": "Test Scanner" +} diff --git a/platform/i18n/src/locales/test-LNG/SidePanel.json b/platform/i18n/src/locales/test-LNG/SidePanel.json new file mode 100644 index 000000000..be2671802 --- /dev/null +++ b/platform/i18n/src/locales/test-LNG/SidePanel.json @@ -0,0 +1,4 @@ +{ + "Studies": "Test Studies", + "Measurements": "Test Measurements" +} diff --git a/platform/i18n/src/locales/test-LNG/StudyBrowser.json b/platform/i18n/src/locales/test-LNG/StudyBrowser.json new file mode 100644 index 000000000..160a466df --- /dev/null +++ b/platform/i18n/src/locales/test-LNG/StudyBrowser.json @@ -0,0 +1,5 @@ +{ + "Primary": "Test Primary", + "Recent": "Test Recent", + "All": "Test All" +} diff --git a/platform/i18n/src/locales/test-LNG/StudyList.json b/platform/i18n/src/locales/test-LNG/StudyList.json new file mode 100644 index 000000000..5e06459fb --- /dev/null +++ b/platform/i18n/src/locales/test-LNG/StudyList.json @@ -0,0 +1,21 @@ +{ + "AccessionNumber": "Test Accession #", + "Accession": "Test Accession", + "Next >": "Test Next >", + "< Previous": "Test < Previous", + "Results per page": "Test Results per page", + "Empty": "Test Empty", + "MRN": "Test MRN", + "Modality": "Test Modality", + "PatientName": "Test PatientName", + "Patient Name": "Test Patient Name", + "Description": "Test Description", + "StudyDate": "Test Study Date", + "Study date": "Test Study Date", + "Studies": "Test Studies", + "Series": "Test Series", + "Instances": "Test Instances", + "Study List": "Test Study List", + "Study list": "Test Study list", + "Filter list to 100 studies or less to enable sorting": "Test Filter list to 100 studies or less to enable sorting" +} diff --git a/platform/i18n/src/locales/test-LNG/ToolTip.json b/platform/i18n/src/locales/test-LNG/ToolTip.json new file mode 100644 index 000000000..d3d657420 --- /dev/null +++ b/platform/i18n/src/locales/test-LNG/ToolTip.json @@ -0,0 +1,3 @@ +{ + "Zoom": "toolTip1" +} diff --git a/platform/i18n/src/locales/test-LNG/UserPreferencesModal.json b/platform/i18n/src/locales/test-LNG/UserPreferencesModal.json new file mode 100644 index 000000000..c5ae4fde8 --- /dev/null +++ b/platform/i18n/src/locales/test-LNG/UserPreferencesModal.json @@ -0,0 +1,14 @@ +{ + "Cancel": "$t(Buttons:Cancel)", + "No hotkeys found": "No hotkeys are configured for this application. Hotkeys can be configured in the application's app-config.js file.", + "Reset to Defaults": "$t(Buttons:Reset to Defaults)", + "ResetDefaultMessage": "Preferences successfully reset to default.
You must Save to perform this action.", + "Save": "$t(Buttons:Save)", + "SaveMessage": "Test Preferences saved", + "User Preferences": "Test User Preferences", + "Function": "Test function", + "Shortcut": "Test shortcut", + "Language": "Test language", + "Hotkeys": "Test hotkeys", + "General": "Test general" +} diff --git a/platform/i18n/src/locales/test-LNG/ViewportDownloadForm.json b/platform/i18n/src/locales/test-LNG/ViewportDownloadForm.json new file mode 100644 index 000000000..cd1624b4b --- /dev/null +++ b/platform/i18n/src/locales/test-LNG/ViewportDownloadForm.json @@ -0,0 +1,14 @@ +{ + "emptyFilenameError": "The file name cannot be empty.", + "fileType": "File Type", + "filename": "File Name", + "formTitle": "Please specify the dimensions, filename, and desired type for the output image.", + "imageHeight": "Image height (px)", + "imagePreview": "Image Preview", + "imageWidth": "Image width (px)", + "keepAspectRatio": "Keep aspect ratio", + "loadingPreview": "Loading Image Preview...", + "minHeightError": "The minimum valid height is 100px.", + "minWidthError": "The minimum valid width is 100px.", + "showAnnotations": "Show Annotations" +} \ No newline at end of file diff --git a/platform/i18n/src/locales/test-LNG/index.js b/platform/i18n/src/locales/test-LNG/index.js new file mode 100644 index 000000000..315deb5d3 --- /dev/null +++ b/platform/i18n/src/locales/test-LNG/index.js @@ -0,0 +1,37 @@ +import AboutModal from './AboutModal.json'; +import Buttons from './Buttons.json'; +import CineDialog from './CineDialog.json'; +import Common from './Common.json'; +import DatePicker from './DatePicker.json'; +import Header from './Header.json'; +import MeasurementTable from './MeasurementTable.json'; +import StudyList from './StudyList.json'; +import UserPreferencesModal from './UserPreferencesModal.json'; +import ViewportDownloadForm from './ViewportDownloadForm.json'; +import ToolTip from './ToolTip.json'; +import StudyBrowser from './StudyBrowser.json'; +import SidePanel from './SidePanel.json'; +import PatientInfo from './PatientInfo.json'; +import Modes from './Modes.json'; +import Modals from './Modals.json'; + +export default { + 'test-LNG': { + AboutModal, + Buttons, + CineDialog, + Common, + DatePicker, + Header, + MeasurementTable, + StudyList, + UserPreferencesModal, + ViewportDownloadForm, + ToolTip, + StudyBrowser, + PatientInfo, + Modes, + SidePanel, + Modals + }, +}; diff --git a/platform/i18n/src/utils.js b/platform/i18n/src/utils.js index b62eedca1..245013dac 100644 --- a/platform/i18n/src/utils.js +++ b/platform/i18n/src/utils.js @@ -54,6 +54,7 @@ const languagesMap = { zh: 'Chinese', 'zh-CN': 'Chinese (China)', 'zh-TW': 'Chinese (Taiwan)', + 'test-LNG': 'Test Language', }; const getLanguageLabel = (language) => { diff --git a/platform/ui/src/components/Header/Header.jsx b/platform/ui/src/components/Header/Header.jsx index 34cc31213..e4bc16457 100644 --- a/platform/ui/src/components/Header/Header.jsx +++ b/platform/ui/src/components/Header/Header.jsx @@ -7,7 +7,7 @@ import { useHistory } from 'react-router-dom'; import { NavBar, Svg, Icon, IconButton, Dropdown } from '@ohif/ui'; function Header({ children, menuOptions, isReturnEnabled, isSticky, WhiteLabeling }) { - const { t } = useTranslation(); + const { t } = useTranslation('Header'); const history = useHistory(); // TODO: this should be passed in as a prop instead and the react-router-dom @@ -39,7 +39,7 @@ function Header({ children, menuOptions, isReturnEnabled, isSticky, WhiteLabelin
{children}
- {t('Header:INVESTIGATIONAL USE ONLY')} + {t('INVESTIGATIONAL USE ONLY')} { + const { t } = useTranslation('UserPreferencesModal'); + const visibleHotkeys = Object.keys(hotkeyDefinitions) .filter(key => hotkeyDefinitions[key].isEditable) .reduce((obj, key) => { @@ -57,7 +61,7 @@ const HotkeysPreferences = ({ disabled, hotkeyDefinitions, errors: controlledErr variant='subtitle' className={classNames('pr-6 w-full text-right text-primary-light', !isFirst && 'hidden')} > - Function + {t('Function')} - Shortcut + {t('Shortcut')}
{ + const { t } = useTranslation("StudyList") + const onClickHandler = e => { if (!isSortable) { return; @@ -38,7 +41,7 @@ const InputLabelWrapper = ({ onKeyDown={onClickHandler} tabIndex="0" > - {label} + {t(label)} {isSortable && ( { + const { t } = useTranslation("MeasurementTable") + return (
- {title} + {t(title)} {amount}
@@ -31,7 +34,7 @@ const MeasurementTable = ({ data, title, amount, onClick, onEdit }) => {
- No tracked measurements + {t('No tracked measurements')}
diff --git a/platform/ui/src/components/SidePanel/SidePanel.jsx b/platform/ui/src/components/SidePanel/SidePanel.jsx index 5d6dd4626..e2d0966e1 100644 --- a/platform/ui/src/components/SidePanel/SidePanel.jsx +++ b/platform/ui/src/components/SidePanel/SidePanel.jsx @@ -1,6 +1,7 @@ import React, { useState } from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; +import { useTranslation } from 'react-i18next'; import { Button, Icon } from '../'; @@ -69,6 +70,8 @@ const SidePanel = ({ defaultComponentOpen, childComponents, }) => { + const { t } = useTranslation('SidePanel'); + const [componentOpen, setComponentOpen] = useState(defaultComponentOpen); const openStatus = componentOpen ? 'open' : 'closed'; @@ -101,7 +104,7 @@ const SidePanel = ({ className="text-primary-active" /> - {childComponent.iconLabel} + {t(childComponent.iconLabel)} ); @@ -139,7 +142,7 @@ const SidePanel = ({ style={{ ...position[side] }} /> - {childComponent.label} + {t(childComponent.label)}
diff --git a/platform/ui/src/components/SplitButton/SplitButton.jsx b/platform/ui/src/components/SplitButton/SplitButton.jsx index c8f8f54ad..9b823d298 100644 --- a/platform/ui/src/components/SplitButton/SplitButton.jsx +++ b/platform/ui/src/components/SplitButton/SplitButton.jsx @@ -2,6 +2,7 @@ import React, { useState } from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import OutsideClickHandler from 'react-outside-click-handler'; +import { useTranslation } from 'react-i18next'; import { Icon, Tooltip, ListMenu } from '@ohif/ui'; @@ -83,6 +84,8 @@ const SplitButton = ({ renderer, onInteraction, }) => { + const { t } = useTranslation('Buttons'); + const { primaryToolId, toggles } = bState; /* Bubbles up individual item clicks */ const getSplitButtonItems = items => @@ -221,14 +224,14 @@ const SplitButton = ({ className={classes.Content({ ...state })} data-cy={`${groupId}-list-menu`} > - + renderer({ ...args, t })} />
); }; -const DefaultListItemRenderer = ({ icon, label, isActive }) => ( +const DefaultListItemRenderer = ({ icon, label, isActive, t }) => (
( - {label} + {t(label)}
); diff --git a/platform/ui/src/components/StudyBrowser/StudyBrowser.jsx b/platform/ui/src/components/StudyBrowser/StudyBrowser.jsx index fe931bb1a..cb366e99f 100644 --- a/platform/ui/src/components/StudyBrowser/StudyBrowser.jsx +++ b/platform/ui/src/components/StudyBrowser/StudyBrowser.jsx @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; +import { useTranslation } from 'react-i18next'; import { ButtonGroup, Button, StudyItem, ThumbnailList } from '../'; @@ -29,6 +30,8 @@ const StudyBrowser = ({ onClickUntrack, activeDisplaySetInstanceUID, }) => { + const { t } = useTranslation("StudyBrowser") + const getTabContent = () => { const tabData = tabs.find(tab => tab.name === activeTabName); @@ -96,7 +99,7 @@ const StudyBrowser = ({ }} disabled={isDisabled} > - {label} + {t(label)} ); })} diff --git a/platform/ui/src/components/StudyListExpandedRow/StudyListExpandedRow.js b/platform/ui/src/components/StudyListExpandedRow/StudyListExpandedRow.js index a7f3e7b80..6f2f88bce 100644 --- a/platform/ui/src/components/StudyListExpandedRow/StudyListExpandedRow.js +++ b/platform/ui/src/components/StudyListExpandedRow/StudyListExpandedRow.js @@ -1,5 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; +import { useTranslation } from 'react-i18next'; import { Table, TableHead, TableBody, TableRow, TableCell } from '../'; @@ -8,6 +9,9 @@ const StudyListExpandedRow = ({ seriesTableDataSource, children, }) => { + const { t } = useTranslation('StudyList'); + + return (
{children}
@@ -18,7 +22,7 @@ const StudyListExpandedRow = ({ {Object.keys(seriesTableColumns).map(columnKey => { return ( - {seriesTableColumns[columnKey]} + {t(seriesTableColumns[columnKey])} ); })} diff --git a/platform/ui/src/components/StudyListFilter/StudyListFilter.jsx b/platform/ui/src/components/StudyListFilter/StudyListFilter.jsx index 0567e4336..97c99058b 100644 --- a/platform/ui/src/components/StudyListFilter/StudyListFilter.jsx +++ b/platform/ui/src/components/StudyListFilter/StudyListFilter.jsx @@ -1,5 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; +import { useTranslation } from 'react-i18next'; import { Button, Icon, Typography, InputGroup } from '../../components'; @@ -11,6 +12,7 @@ const StudyListFilter = ({ isFiltering, numOfStudies, }) => { + const { t } = useTranslation("StudyList") const { sortBy, sortDirection } = filterValues; const filterSorting = { sortBy, sortDirection }; const setFilterSorting = sortingValues => { @@ -29,7 +31,7 @@ const StudyListFilter = ({
- Study list + {t('Study list')}
@@ -42,7 +44,7 @@ const StudyListFilter = ({ startIcon={} onClick={clearFilters} > - Clear filters + {t('Clear filters')} )} @@ -52,7 +54,7 @@ const StudyListFilter = ({ variant="h6" className="self-end pb-1 text-common-light" > - Studies + {t('Studies')}
@@ -77,7 +79,7 @@ const StudyListFilter = ({

- Filter list to 100 studies or less to enable sorting + {t('Filter list to 100 studies or less to enable sorting')}

diff --git a/platform/ui/src/components/StudyListPagination/StudyListPagination.js b/platform/ui/src/components/StudyListPagination/StudyListPagination.js index c57e53fdc..6a430cd5a 100644 --- a/platform/ui/src/components/StudyListPagination/StudyListPagination.js +++ b/platform/ui/src/components/StudyListPagination/StudyListPagination.js @@ -1,6 +1,7 @@ import React, { useState } from 'react'; import PropTypes from 'prop-types'; import { Button, ButtonGroup, Typography, Select } from '../'; +import { useTranslation } from 'react-i18next'; const StudyListPagination = ({ onChangePage, @@ -8,6 +9,8 @@ const StudyListPagination = ({ perPage, onChangePerPage, }) => { + const { t } = useTranslation("StudyList") + const navigateToPage = page => { const toPage = page < 1 ? 1 : page; onChangePage(toPage); @@ -42,7 +45,7 @@ const StudyListPagination = ({ onChange={onSelectedRange} /> - Results per page + {t('Results per page')}
@@ -64,14 +67,14 @@ const StudyListPagination = ({ className="border-primary-main py-2 px-2 text-base" color="white" onClick={() => navigateToPage(currentPage - 1)} - >{`< Previous`} + >{t(`< Previous`)}
diff --git a/platform/ui/src/components/Tooltip/Tooltip.jsx b/platform/ui/src/components/Tooltip/Tooltip.jsx index 8f8378052..c7cc6f839 100644 --- a/platform/ui/src/components/Tooltip/Tooltip.jsx +++ b/platform/ui/src/components/Tooltip/Tooltip.jsx @@ -1,6 +1,7 @@ import React, { useState } from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; +import { useTranslation } from 'react-i18next'; import './tooltip.css'; @@ -33,6 +34,7 @@ const Tooltip = ({ isDisabled, }) => { const [isActive, setIsActive] = useState(false); + const { t } = useTranslation('Buttons'); const handleMouseOver = () => { if (!isActive) { @@ -72,7 +74,7 @@ const Tooltip = ({ } )} > - {content} + {typeof content === 'string' ? t(content) : content} -
+
- Language + {t('Language')}