- Number of Slicewise correlations
+ {t('Number of Slicewise correlations',
+ {ns: 'imaging_browser'})}
|
{this.props.HeaderInfo.SlicewiseRejected}
@@ -272,8 +301,11 @@ class ImagePanelHeadersTable extends Component {
}
ImagePanelHeadersTable.propTypes = {
HeaderInfo: PropTypes.object,
+ t: PropTypes.func,
};
+const TranslatedImagePanelHeadersTable = withTranslation(
+ ['imaging_browser'])(ImagePanelHeadersTable);
/**
* Image quality control dropdown component
@@ -344,8 +376,11 @@ ImageQCDropdown.propTypes = {
FileID: PropTypes.string,
FormName: PropTypes.string,
defaultValue: PropTypes.string,
+ t: PropTypes.func,
};
+const TranslatedImageQCDropdown = withTranslation(
+ ['imaging_browser'])(ImageQCDropdown);
/**
* Image quality control static component
@@ -382,8 +417,11 @@ class ImageQCStatic extends Component {
ImageQCStatic.propTypes = {
defaultValue: PropTypes.string,
Label: PropTypes.string,
+ t: PropTypes.func,
};
+const TranslatedImageQCStatic = withTranslation(
+ ['imaging_browser'])(ImageQCStatic);
/**
* Image panel quality control
@@ -404,26 +442,28 @@ class ImagePanelQCStatusSelector extends Component {
* @return {JSX} - React markup for the component
*/
render() {
+ const {t} = this.props;
let qcStatusLabel;
if (this.props.HasQCPerm && this.props.FileNew) {
qcStatusLabel =
- QC Status
+ {t('QC Status', {ns: 'imaging_browser'})}
(
- New )
+ {t('New', {ns: 'imaging_browser'})} )
;
} else {
- qcStatusLabel = 'QC Status';
+ qcStatusLabel = t('QC Status', {ns: 'imaging_browser'});
}
return (
-
);
}
@@ -433,8 +473,11 @@ ImagePanelQCStatusSelector.propTypes = {
HasQCPerm: PropTypes.bool,
QCStatus: PropTypes.string,
FileID: PropTypes.string,
+ t: PropTypes.func,
};
+const TranslatedImagePanelQCStatusSelector = withTranslation(
+ ['imaging_browser'])(ImagePanelQCStatusSelector);
/**
* Image panel quality control
@@ -455,13 +498,15 @@ class ImagePanelQCSelectedSelector extends Component {
* @return {JSX} - React markup for the component
*/
render() {
+ const {t} = this.props;
return (
-
);
@@ -471,8 +516,11 @@ ImagePanelQCSelectedSelector.propTypes = {
FileID: PropTypes.string,
HasQCPerm: PropTypes.bool,
Selected: PropTypes.string,
+ t: PropTypes.func,
};
+const TranslatedImagePanelQCSelectedSelector = withTranslation(
+ ['imaging_browser'])(ImagePanelQCSelectedSelector);
/**
* Image panel quality control
@@ -493,6 +541,7 @@ class ImagePanelQCCaveatSelector extends Component {
* @return {JSX} - React markup for the component
*/
render() {
+ const {t} = this.props;
// Link caveat to MRI Violations if set true
let mriViolationsLink = null;
if (this.props.FullName && this.props.Caveat === '1') {
@@ -502,16 +551,16 @@ class ImagePanelQCCaveatSelector extends Component {
}
return (
-
-
-
-
-
@@ -626,8 +682,11 @@ ImagePanelQCPanel.propTypes = {
SNR: PropTypes.string,
EditableCaveat: PropTypes.bool,
FullName: PropTypes.string,
+ t: PropTypes.func,
};
+const TranslatedImagePanelQCPanel = withTranslation(
+ ['imaging_browser'])(ImagePanelQCPanel);
/**
* Download button component
@@ -647,6 +706,7 @@ class DownloadButton extends Component {
* @return {JSX} - React markup for the component
*/
render() {
+ const {t} = this.props;
const empty = (prop) => {
return !prop || prop == '';
};
@@ -663,7 +723,8 @@ class DownloadButton extends Component {
- {this.props.Label}
+ {t('Download Image',
+ {ns: 'imaging_browser'})}
);
}
@@ -673,8 +734,11 @@ DownloadButton.propTypes = {
BaseURL: PropTypes.string,
Label: PropTypes.string,
URL: PropTypes.string,
+ t: PropTypes.func,
};
+const TranslatedDownloadButton = withTranslation(
+ ['imaging_browser'])(DownloadButton);
/**
* Image quality control comments button component
@@ -712,6 +776,7 @@ class ImageQCCommentsButton extends Component {
* @return {JSX} - React markup for the component
*/
render() {
+ const {t} = this.props;
if (!this.props.FileID || this.props.FileID === '') {
return ;
}
@@ -722,7 +787,8 @@ class ImageQCCommentsButton extends Component {
>
- QC Comments
+ {t('QC Comments',
+ {ns: 'imaging_browser'})}
);
@@ -731,8 +797,11 @@ class ImageQCCommentsButton extends Component {
ImageQCCommentsButton.propTypes = {
FileID: PropTypes.string,
BaseURL: PropTypes.string,
+ t: PropTypes.func,
};
+const TranslatedImageQCCommentsButton = withTranslation(
+ ['imaging_browser'])(ImageQCCommentsButton);
/**
* Longitudinal view button component
@@ -768,6 +837,7 @@ class LongitudinalViewButton extends Component {
* @return {JSX} - React markup for the component
*/
render() {
+ const {t} = this.props;
if (!this.props.FileID || this.props.FileID === '') {
return ;
}
@@ -778,7 +848,8 @@ class LongitudinalViewButton extends Component {
>
- Longitudinal View
+ {t('Longitudinal View',
+ {ns: 'imaging_browser'})}
);
@@ -788,8 +859,11 @@ LongitudinalViewButton.propTypes = {
FileID: PropTypes.string,
BaseURL: PropTypes.string,
OtherTimepoints: PropTypes.string,
+ t: PropTypes.func,
};
+const TranslatedLongitudinalViewButton = withTranslation(
+ ['imaging_browser'])(LongitudinalViewButton);
/**
* Image download buttons component
@@ -809,52 +883,54 @@ class ImageDownloadButtons extends Component {
* @return {JSX} - React markup for the component
*/
render() {
+ const {t} = this.props;
return (
-
-
-
-
-
{ this.props.NiiFile ?
- :
null
}
{this.props.BvalFile ?
- :
null
}
{this.props.BvecFile ?
- :
null
}
{this.props.JsonFile ?
- :
null
}
-
@@ -875,8 +951,11 @@ ImageDownloadButtons.propTypes = {
BvecFile: PropTypes.string,
JsonFile: PropTypes.string,
OtherTimepoints: PropTypes.string,
+ t: PropTypes.func,
};
+const TranslatedImageDownloadButtons = withTranslation(
+ ['imaging_browser'])(ImageDownloadButtons);
/**
* Image panel body component
@@ -919,7 +998,7 @@ class ImagePanelBody extends Component {
-
-
- {this.props.HeadersExpanded ? : ''}
);
@@ -975,8 +1054,11 @@ ImagePanelBody.propTypes = {
HeadersExpanded: PropTypes.bool,
HeaderInfo: PropTypes.object,
EditableCaveat: PropTypes.bool,
+ t: PropTypes.func,
};
+const TranslatedImagePanelBody = withTranslation(
+ ['imaging_browser'])(ImagePanelBody);
/**
* Image panel component
@@ -1027,7 +1109,7 @@ class ImagePanel extends Component {
return (
-
{this.state.BodyCollapsed ? '' :
- {cell} | ;
+ const {t} = this.props;
switch (column) {
- case 'New Data':
+ case t('New Data', {ns: 'imaging_browser'}):
if (cell === 'new') {
result = (
- NEW |
+ {t('NEW', {ns: 'imaging_browser'})} |
);
}
break;
- case 'Links':
+ case t('Links', {ns: 'imaging_browser'}):
let cellTypes = cell.split(',');
let cellLinks = [];
for (let i = 0; i < cellTypes.length; i += 1) {
@@ -87,7 +91,7 @@ class ImagingBrowserIndex extends Component {
'/imaging_browser/viewSession/?sessionID=' +
row.SessionID +
'&selectedOnly=1&backURL=/imaging_browser/'}>
- selected
+ {t('selected', {ns: 'imaging_browser'})}
);
cellLinks.push(' | ');
@@ -95,7 +99,7 @@ class ImagingBrowserIndex extends Component {
'/imaging_browser/viewSession/?sessionID=' +
row.SessionID +
'&backURL=/imaging_browser/'}>
- all types
+ {t('all types', {ns: 'imaging_browser'})}
);
result = ({cellLinks} | );
break;
@@ -110,10 +114,12 @@ class ImagingBrowserIndex extends Component {
* @return {JSX} - React markup for the component
*/
render() {
+ const {t} = this.props;
// If error occurs, return a message.
// XXX: Replace this with a UI component for 500 errors.
if (this.state.error) {
- return An error occured while loading the page.
;
+ return {t('An error occured while loading the page.',
+ {ns: 'imaging_browser'})}
;
}
// Waiting for async data to load
@@ -128,61 +134,66 @@ class ImagingBrowserIndex extends Component {
const options = this.state.data.fieldOptions;
const configLabels = options.configLabels;
const fields = [
- {label: 'Site', show: true, filter: {
+ {label: t('Site', {ns: 'loris'}), show: true, filter: {
name: 'site',
type: 'select',
options: options.sites,
}},
- {label: 'PSCID', show: true, filter: {
+ {label: t('PSCID', {ns: 'loris'}), show: true, filter: {
name: 'PSCID',
type: 'text',
}},
- {label: 'DCCID', show: true, filter: {
+ {label: t('DCCID', {ns: 'loris'}), show: true, filter: {
name: 'DCCID',
type: 'text',
}},
- {label: 'Project', show: true, filter: {
+ {label: t('Project', {ns: 'loris'}), show: true, filter: {
name: 'project',
type: 'select',
options: options.projects,
}},
- {label: 'Visit Label', show: true, filter: {
+ {label: t('Visit Label', {ns: 'loris'}), show: true, filter: {
name: 'visitLabel',
type: 'text',
}},
- {label: 'Visit QC Status', show: true, filter: {
- name: 'visitQCStatus',
- type: 'select',
- options: options.visitQCStatus,
- }},
- {label: 'First Acquisition', show: true},
- {label: 'First Insertion', show: true},
- {label: 'Last QC', show: true},
- {label: 'New Data', show: true},
- {label: 'Links', show: true},
- {label: 'SessionID', show: false},
- {label: 'Sequence Type', show: false, filter: {
- name: 'sequenceType',
- type: 'multiselect',
- options: options.sequenceTypes,
- }},
- {label: 'Pending New', show: false, filter: {
- name: 'pendingNew',
- type: 'multiselect',
- options: options.pendingNew,
- }},
- {label: 'Entity Type', show: false, filter: {
- name: 'entityType',
- type: 'multiselect',
- options: options.entityType,
- }},
+ {label: t('Visit QC Status', {ns: 'imaging_browser'}),
+ show: true, filter: {
+ name: 'visitQCStatus',
+ type: 'select',
+ options: options.visitQCStatus,
+ }},
+ {label: t('First Acquisition', {ns: 'imaging_browser'}), show: true},
+ {label: t('First Insertion', {ns: 'imaging_browser'}), show: true},
+ {label: t('Last QC', {ns: 'imaging_browser'}), show: true},
+ {label: t('New Data', {ns: 'imaging_browser'}), show: true},
+ {label: t('Links', {ns: 'imaging_browser'}), show: true},
+ {label: t('SessionID', {ns: 'imaging_browser'}), show: false},
+ {label: t('Sequence Type', {ns: 'imaging_browser'}),
+ show: false, filter: {
+ name: 'sequenceType',
+ type: 'multiselect',
+ options: options.sequenceTypes,
+ }},
+ {label: t('Pending New', {ns: 'imaging_browser'}),
+ show: false, filter: {
+ name: 'pendingNew',
+ type: 'multiselect',
+ options: options.pendingNew,
+ }},
+ {label: t('Entity Type', {ns: 'imaging_browser'}),
+ show: false, filter: {
+ name: 'entityType',
+ type: 'multiselect',
+ options: options.entityType,
+ }},
];
/**
* Adding columns based on the Imaging Browser Tabulated Scan Types
* configured and stored in database
*/
Object.values(configLabels).forEach((label)=> {
- fields.push({label: label + ' QC Status', show: true}
+ fields.push({label: t(label + ' QC Status', {ns: 'imaging_browser'}),
+ show: true}
);
});
@@ -200,10 +211,12 @@ class ImagingBrowserIndex extends Component {
ImagingBrowserIndex.propTypes = {
dataURL: PropTypes.string.isRequired,
+ t: PropTypes.func,
};
window.addEventListener('load', () => {
i18n.addResourceBundle('ja', 'imaging_browser', {});
+ i18n.addResourceBundle('hi', 'imaging_browser', hiStrings);
const Index = withTranslation(
['imaging_browser', 'loris']
)(ImagingBrowserIndex);
diff --git a/modules/imaging_browser/locale/hi/LC_MESSAGES/imaging_browser.po b/modules/imaging_browser/locale/hi/LC_MESSAGES/imaging_browser.po
new file mode 100644
index 00000000000..cf4e51ec71f
--- /dev/null
+++ b/modules/imaging_browser/locale/hi/LC_MESSAGES/imaging_browser.po
@@ -0,0 +1,115 @@
+# Default LORIS strings to be translated (English).
+# Copy this to a language specific file and add translations to the
+# new file.
+# Copyright (C) 2025
+# This file is distributed under the same license as the LORIS package.
+# Dave MacFarlane , 2025.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: LORIS 27\n"
+"Report-Msgid-Bugs-To: https://github.com/aces/Loris/issues\n"
+"POT-Creation-Date: 2025-04-08 14:37-0400\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: LANGUAGE \n"
+"Language: hi\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid "Imaging Browser"
+msgstr "इमेजिंग ब्राउज़र"
+
+msgid "View Session"
+msgstr "सत्र देखें"
+
+msgid "New and pending imaging session"
+msgstr "नई और लंबित इमेजिंग सत्र"
+
+msgid "New and pending imaging sessions"
+msgstr "नई और लंबित इमेजिंग सत्रों"
+
+msgid "Visit QC Status"
+msgstr "विजिट QC स्थिति"
+
+msgid "First Acquisition"
+msgstr "पहला अधिग्रहण"
+
+msgid "First Insertion"
+msgstr "पहला सम्मिलन"
+
+msgid "Last QC"
+msgstr "अंतिम QC"
+
+msgid "New Data"
+msgstr "नया डेटा"
+
+msgid "Links"
+msgstr "लिंक"
+
+msgid "SessionID"
+msgstr "सेशन आईडी"
+
+msgid "Sequence Type"
+msgstr "सीक्वेंस प्रकार"
+
+msgid "Pending New"
+msgstr "लंबित नया"
+
+msgid "Entity Type"
+msgstr "इकाई प्रकार"
+
+msgid "QC Status"
+msgstr "QC स्थिति"
+
+msgid "selected"
+msgstr "चयनित"
+
+msgid "all types"
+msgstr "सभी प्रकार"
+
+msgid "NEW"
+msgstr "नया"
+
+msgid "Pass"
+msgstr "पास"
+
+msgid "Fail"
+msgstr "फेल"
+
+msgid "Header Info"
+msgstr "हेडर जानकारी"
+
+msgid "Selected"
+msgstr "चयनित"
+
+msgid "Download Image"
+msgstr "इमेज डाउनलोड करें"
+
+msgid "Longitudinal View"
+msgstr "लंबवत दृश्य"
+
+msgid "QC Comments"
+msgstr "QC टिप्पणियाँ"
+
+msgid "Series Instance UID"
+msgstr "सीरीज इंस्टेंस UID"
+
+msgid "Number of Scans"
+msgstr "स्कैन की संख्या"
+
+msgid "Red bar denotes number of failed QC scans."
+msgstr "लाल बार असफल QC स्कैन की संख्या दर्शाता है।"
+
+msgid "Green bar denotes number of passed QC scans."
+msgstr "हरा बार पास किए गए QC स्कैन की संख्या दर्शाता है।"
+
+msgid "Grey bar denotes other QC statuses."
+msgstr "ग्रे बार अन्य QC स्थितियाँ दर्शाता है।"
+
+msgid "Different shades represent different modalities. Only native modalities are displayed in results."
+msgstr "विभिन्न शेड्स विभिन्न मोडैलिटी का प्रतिनिधित्व करते हैं। केवल मूल मोडैलिटी परिणामों में दिखाई जाती हैं।"
+
+msgid "Hover over any visit to see detailed modality breakdown for visit, click to go to imaging browser."
+msgstr "किसी भी विजिट पर होवर करें ताकि विजिट के लिए विस्तृत मोडैलिटी ब्रेकडाउन देखें, क्लिक करें और इमेजिंग ब्राउज़र पर जाएं।"
diff --git a/modules/imaging_browser/locale/imaging_browser.pot b/modules/imaging_browser/locale/imaging_browser.pot
index 85c635b9e04..6352643c682 100644
--- a/modules/imaging_browser/locale/imaging_browser.pot
+++ b/modules/imaging_browser/locale/imaging_browser.pot
@@ -29,3 +29,87 @@ msgstr ""
msgid "New and pending imaging sessions"
msgstr ""
+
+msgid "Visit QC Status"
+msgstr ""
+
+msgid "First Acquisition"
+msgstr ""
+
+msgid "First Insertion"
+msgstr ""
+
+msgid "Last QC"
+msgstr ""
+
+msgid "New Data"
+msgstr ""
+
+msgid "Links"
+msgstr ""
+
+msgid "SessionID"
+msgstr ""
+
+msgid "Sequence Type"
+msgstr ""
+
+msgid "Pending New"
+msgstr ""
+
+msgid "Entity Type"
+msgstr ""
+
+msgid "QC Status"
+msgstr ""
+
+msgid "selected"
+msgstr ""
+
+msgid "all types"
+msgstr ""
+
+msgid "NEW"
+msgstr ""
+
+msgid "Pass"
+msgstr ""
+
+msgid "Fail"
+msgstr ""
+
+msgid "Header Info"
+msgstr ""
+
+msgid "Selected"
+msgstr ""
+
+msgid "Download Image"
+msgstr ""
+
+msgid "Longitudinal View"
+msgstr ""
+
+msgid "QC Comments"
+msgstr ""
+
+msgid "Series Instance UID"
+msgstr ""
+
+msgid "Number of Scans"
+msgstr ""
+
+msgid "Red bar denotes number of failed QC scans."
+msgstr ""
+
+msgid "Green bar denotes number of passed QC scans."
+msgstr ""
+
+msgid "Grey bar denotes other QC statuses."
+msgstr ""
+
+msgid "Different shades represent different modalities. Only native modalities are displayed in results."
+msgstr ""
+
+msgid "Hover over any visit to see detailed modality breakdown for visit, click to go to imaging browser."
+msgstr ""