diff --git a/Makefile b/Makefile index 762b4ea5c29..233c1df56b7 100755 --- a/Makefile +++ b/Makefile @@ -79,6 +79,8 @@ locales: msgfmt -o modules/api_docs/locale/ja/LC_MESSAGES/api_docs.mo modules/api_docs/locale/ja/LC_MESSAGES/api_docs.po msgfmt -o modules/battery_manager/locale/ja/LC_MESSAGES/battery_manager.mo modules/battery_manager/locale/ja/LC_MESSAGES/battery_manager.po msgfmt -o modules/behavioural_qc/locale/ja/LC_MESSAGES/behavioural_qc.mo modules/behavioural_qc/locale/ja/LC_MESSAGES/behavioural_qc.po + msgfmt -o modules/behavioural_qc/locale/hi/LC_MESSAGES/behavioural_qc.mo modules/behavioural_qc/locale/hi/LC_MESSAGES/behavioural_qc.po + npx i18next-conv -l hi -s modules/behavioural_qc/locale/hi/LC_MESSAGES/behavioural_qc.po -t modules/behavioural_qc/locale/hi/LC_MESSAGES/behavioural_qc.json msgfmt -o modules/brainbrowser/locale/ja/LC_MESSAGES/brainbrowser.mo modules/brainbrowser/locale/ja/LC_MESSAGES/brainbrowser.po msgfmt -o modules/bvl_feedback/locale/ja/LC_MESSAGES/bvl_feedback.mo modules/bvl_feedback/locale/ja/LC_MESSAGES/bvl_feedback.po msgfmt -o modules/candidate_list/locale/ja/LC_MESSAGES/candidate_list.mo modules/candidate_list/locale/ja/LC_MESSAGES/candidate_list.po @@ -192,3 +194,8 @@ server_processes_manager: modules/server_processes_manager/locale/ja/LC_MESSAGES conflict_resolver: target=conflict_resolver npm run compile + +behavioural_qc: + msgfmt -o modules/behavioural_qc/locale/hi/LC_MESSAGES/behavioural_qc.mo modules/behavioural_qc/locale/hi/LC_MESSAGES/behavioural_qc.po + npx i18next-conv -l hi -s modules/behavioural_qc/locale/hi/LC_MESSAGES/behavioural_qc.po -t modules/behavioural_qc/locale/hi/LC_MESSAGES/behavioural_qc.json + target=behavioural_qc npm run compile \ No newline at end of file diff --git a/locale/hi/LC_MESSAGES/loris.po b/locale/hi/LC_MESSAGES/loris.po index 337fc38afde..4709e9f217a 100644 --- a/locale/hi/LC_MESSAGES/loris.po +++ b/locale/hi/LC_MESSAGES/loris.po @@ -130,6 +130,12 @@ msgstr "रद्द करें" msgid "Success!" msgstr "सफलता!" +msgid "Selection Filter" +msgstr "चयन फ़िल्टर" + +msgid "Clear Filters" +msgstr "फ़िल्टर साफ़ करें" + # Common candidate terms msgid "PSCID" msgstr "पीएससीआईडी" @@ -146,6 +152,9 @@ msgstr "साइट" msgid "Module" msgstr "मॉड्यूल" +msgid "Instrument" +msgstr "उपकरण" + msgid "Project" msgstr "परियोजना" diff --git a/locale/loris.pot b/locale/loris.pot index a1456967b2c..ca463f31ed6 100644 --- a/locale/loris.pot +++ b/locale/loris.pot @@ -132,6 +132,12 @@ msgstr "" msgid "Success!" msgstr "" +msgid "Selection Filters" +msgstr "" + +msgid "Clear Filters" +msgstr "" + # Common candidate terms msgid "PSCID" msgstr "" @@ -148,6 +154,9 @@ msgstr "" msgid "Module" msgstr "" +msgid "Instrument" +msgstr "" + msgid "Project" msgstr "" diff --git a/modules/behavioural_qc/jsx/behaviouralQCIndex.js b/modules/behavioural_qc/jsx/behaviouralQCIndex.js index c62bd7f2ef9..33c01860af2 100644 --- a/modules/behavioural_qc/jsx/behaviouralQCIndex.js +++ b/modules/behavioural_qc/jsx/behaviouralQCIndex.js @@ -10,6 +10,7 @@ import IncompleteForms from './tabs_content/incompleteForms'; import DataConflicts from './tabs_content/dataConflicts'; import BehaviouralFeedback from './tabs_content/behaviouralFeedback'; +import hiStrings from '../locale/hi/LC_MESSAGES/behavioural_qc.json'; /** * Behavioural Quality Control. * @@ -20,10 +21,14 @@ import BehaviouralFeedback from './tabs_content/behaviouralFeedback'; * @version 1.0.0 */ const BehaviouralQC = (props) => { + const {t} = props; const tabList = [ - {id: 'tabIncompleteForms', label: 'Incomplete Forms'}, - {id: 'tabDataConflicts', label: 'Data Conflicts'}, - {id: 'tabBehaviouralFeedback', label: 'Behavioural Feedback'}, + {id: 'tabIncompleteForms', label: t('Incomplete Forms', + {ns: 'behavioural_qc'})}, + {id: 'tabDataConflicts', label: t('Data Conflicts', + {ns: 'behavioural_qc'})}, + {id: 'tabBehaviouralFeedback', label: t('Behavioural Feedback', + {ns: 'behavioural_qc'})}, ]; /** @@ -49,6 +54,7 @@ const BehaviouralQC = (props) => { }; BehaviouralQC.propTypes = { baseURL: PropTypes.string.isRequired, + t: PropTypes.func, // ADD THIS }; /** @@ -56,6 +62,7 @@ BehaviouralQC.propTypes = { */ window.addEventListener('load', () => { i18n.addResourceBundle('ja', 'behavioural_qc', {}); + i18n.addResourceBundle('hi', 'behavioural_qc', hiStrings); const Index = withTranslation( ['behavioural_qc', 'loris'] )(BehaviouralQC); diff --git a/modules/behavioural_qc/jsx/tabs_content/behaviouralFeedback.js b/modules/behavioural_qc/jsx/tabs_content/behaviouralFeedback.js index 3d7fba2661a..05afc1b9c76 100644 --- a/modules/behavioural_qc/jsx/tabs_content/behaviouralFeedback.js +++ b/modules/behavioural_qc/jsx/tabs_content/behaviouralFeedback.js @@ -2,6 +2,7 @@ import React, {Component} from 'react'; import PropTypes from 'prop-types'; import Loader from 'jsx/Loader'; import FilterableDataTable from 'jsx/FilterableDataTable'; +import {withTranslation} from 'react-i18next'; /** * Behavioural Feedback Component. @@ -80,83 +81,75 @@ class BehaviouralFeedback extends Component { * @return {*} a formatted table cell for a given column */ formatColumn(column, cell, rowData, rowHeaders) { - let reactElement; - switch (column) { - case 'PSCID': - reactElement = ( + const {t} = this.props; + const labelPSCID = t('PSCID', {ns: 'loris'}); + const labelDCCID = t('DCCID', {ns: 'loris'}); + const labelBVL = t('Feedback Level', {ns: 'behavioural_qc'}); + + // PSCID column (match English or translated) + if (column === 'PSCID' || column === labelPSCID) { + return ( - + {rowData['PSCID']} ); - break; - case 'DCCID': - reactElement = ( + } + + // DCCID column + if (column === 'DCCID' || column === labelDCCID) { + return ( - + {rowData['DCCID']} ); - break; - case 'Feedback Level': + } + + // Feedback Level column — build link depending on row data + if (column === 'Feedback Level' || column === labelBVL) { let bvlLink = ''; let bvlLevel = ''; if (rowData['Instrument']) { bvlLink = this.props.baseURL + - '/instruments/' + - rowData['Test Name'] + - '/?candID=' + - rowData['DCCID'] + - '&sessionID=' + - rowData['sessionID'] + - '&commentID=' + - rowData['commentID']; - // Open feedback panel - bvlLink += '&showFeedback=true'; - bvlLevel ='Instrument : ' + rowData['Instrument']; + '/instruments/' + + rowData['Test Name'] + + '/?candID=' + rowData['DCCID'] + + '&sessionID=' + rowData['sessionID'] + + '&commentID=' + rowData['commentID'] + + '&showFeedback=true'; + bvlLevel = t('Instrument', {ns: 'behavioural_qc'}) + ' : ' + + rowData['Instrument']; } else if (rowData['Visit']) { bvlLink = this.props.baseURL + - '/instrument_list/' + - '?candID=' + - rowData['DCCID'] + - '&sessionID=' + - rowData['sessionID']; - // Open feedback panel - bvlLink += '&showFeedback=true'; - bvlLevel ='Visit : ' + rowData['Visit']; + '/instrument_list/?candID=' + rowData['DCCID'] + + '&sessionID=' + rowData['sessionID'] + + '&showFeedback=true'; + bvlLevel = t('Visit', {ns: 'behavioural_qc'}) + ' : ' + + rowData['Visit']; } else { - bvlLink = this.props.baseURL + - '/' + rowData['DCCID']; - // Open feedback panel - bvlLink += '/?showFeedback=true'; - bvlLevel ='Profile : ' + rowData['PSCID']; + bvlLink = this.props.baseURL + '/' + rowData['DCCID'] + + '/?showFeedback=true'; + bvlLevel = t('Profile', {ns: 'behavioural_qc'}) + ' : ' + + rowData['PSCID']; } - reactElement = ( + return ( {bvlLevel} ); - break; - default: - reactElement = ( - {cell} - ); } - return reactElement; + + return {cell}; } /** * @return {JSX} the feedback form to render. */ render() { + const {t} = this.props; // Waiting for async data to load. if (!this.state.isLoaded) { return ; @@ -167,7 +160,7 @@ class BehaviouralFeedback extends Component { // The fields configured for display/hide. let fields = [ { - label: 'Instrument', + label: t('Instrument', {ns: 'loris'}), show: false, filter: { name: 'Instrument', @@ -179,7 +172,7 @@ class BehaviouralFeedback extends Component { }, }, { - label: 'DCCID', + label: t('DCCID', {ns: 'loris'}), show: true, filter: { name: 'DCCID', @@ -187,7 +180,7 @@ class BehaviouralFeedback extends Component { }, }, { - label: 'PSCID', + label: t('PSCID', {ns: 'loris'}), show: true, filter: { name: 'PSCID', @@ -195,7 +188,7 @@ class BehaviouralFeedback extends Component { }, }, { - label: 'Visit', + label: t('Visit', {ns: 'loris'}), show: false, filter: { name: 'Visit', @@ -204,7 +197,7 @@ class BehaviouralFeedback extends Component { }, }, { - label: 'Project', + label: t('Project', {ns: 'loris'}), show: false, filter: { name: 'Project', @@ -213,7 +206,7 @@ class BehaviouralFeedback extends Component { }, }, { - label: 'Cohort', + label: t('Cohort', {ns: 'loris'}), show: false, filter: { name: 'Cohort', @@ -222,7 +215,7 @@ class BehaviouralFeedback extends Component { }, }, { - label: 'Site', + label: t('Site', {ns: 'loris'}), show: false, filter: { name: 'Site', @@ -243,19 +236,19 @@ class BehaviouralFeedback extends Component { show: false, }, { - label: 'Feedback Level', + label: t('Feedback Level', {ns: 'behavioural_qc'}), show: true, }, { - label: 'Test Name', + label: t('Test Name', {ns: 'behavioural_qc'}), show: false, }, { - label: 'Field Name', + label: t('Field Name', {ns: 'behavioural_qc'}), show: false, }, { - label: 'Feedback Status', + label: t('Feedback Status', {ns: 'behavioural_qc'}), show: true, }, ]; @@ -280,6 +273,8 @@ BehaviouralFeedback.propTypes = { display: PropTypes.bool, data: PropTypes.object, baseURL: PropTypes.string.isRequired, + t: PropTypes.func, }; -export default BehaviouralFeedback; +export default withTranslation( + ['behavioural_qc', 'loris'])(BehaviouralFeedback); diff --git a/modules/behavioural_qc/jsx/tabs_content/dataConflicts.js b/modules/behavioural_qc/jsx/tabs_content/dataConflicts.js index c2b4d061185..71a6e7f6d69 100644 --- a/modules/behavioural_qc/jsx/tabs_content/dataConflicts.js +++ b/modules/behavioural_qc/jsx/tabs_content/dataConflicts.js @@ -2,6 +2,7 @@ import React, {Component} from 'react'; import PropTypes from 'prop-types'; import Loader from 'jsx/Loader'; import FilterableDataTable from 'jsx/FilterableDataTable'; +import {withTranslation} from 'react-i18next'; /** * Data Conflicts Component. @@ -150,6 +151,7 @@ class DataConflicts extends Component { * @return {JSX} the data conflicts form to render. */ render() { + const {t} = this.props; // Waiting for async data to load. if (!this.state.isLoaded) { return ; @@ -161,7 +163,7 @@ class DataConflicts extends Component { // The fields configured for display/hide. let fields = [ { - label: 'Instrument', + label: t('Instrument', {ns: 'loris'}), show: true, filter: { name: 'Instrument', @@ -173,7 +175,7 @@ class DataConflicts extends Component { }, }, { - label: 'DCCID', + label: t('DCCID', {ns: 'loris'}), show: true, filter: { name: 'DCCID', @@ -181,7 +183,7 @@ class DataConflicts extends Component { }, }, { - label: 'PSCID', + label: t('PSCID', {ns: 'loris'}), show: true, filter: { name: 'PSCID', @@ -189,7 +191,7 @@ class DataConflicts extends Component { }, }, { - label: 'Visit', + label: t('Visit', {ns: 'loris'}), show: true, filter: { name: 'Visit', @@ -198,7 +200,7 @@ class DataConflicts extends Component { }, }, { - label: 'Project', + label: t('Project', {ns: 'loris'}), show: false, filter: { name: 'Project', @@ -207,7 +209,7 @@ class DataConflicts extends Component { }, }, { - label: 'Cohort', + label: t('Cohort', {ns: 'loris'}), show: false, filter: { name: 'Cohort', @@ -216,7 +218,7 @@ class DataConflicts extends Component { }, }, { - label: 'Site', + label: t('Site', {ns: 'loris'}), show: false, filter: { name: 'Site', @@ -225,7 +227,7 @@ class DataConflicts extends Component { }, }, { - label: 'Field Name', + label: t('Field Name', {ns: 'behavioural_qc'}), show: true, }, { @@ -266,6 +268,7 @@ DataConflicts.propTypes = { display: PropTypes.bool, data: PropTypes.object, baseURL: PropTypes.string.isRequired, + t: PropTypes.func, }; -export default DataConflicts; +export default withTranslation(['behavioural_qc', 'loris'])(DataConflicts); diff --git a/modules/behavioural_qc/jsx/tabs_content/incompleteForms.js b/modules/behavioural_qc/jsx/tabs_content/incompleteForms.js index 0fdcbd7b7b0..02ace97f698 100644 --- a/modules/behavioural_qc/jsx/tabs_content/incompleteForms.js +++ b/modules/behavioural_qc/jsx/tabs_content/incompleteForms.js @@ -2,6 +2,7 @@ import React, {Component} from 'react'; import PropTypes from 'prop-types'; import Loader from 'jsx/Loader'; import FilterableDataTable from 'jsx/FilterableDataTable'; +import {withTranslation} from 'react-i18next'; /** * Incomplete Forms Component. @@ -150,6 +151,7 @@ class IncompleteForms extends Component { * @return {JSX} the incomplete form to render. */ render() { + const {t} = this.props; // Waiting for async data to load. if (!this.state.isLoaded) { return ; @@ -161,7 +163,7 @@ class IncompleteForms extends Component { // The fields configured for display/hide. let fields = [ { - label: 'Instrument', + label: t('Instrument', {ns: 'loris'}), show: true, filter: { name: 'Instrument', @@ -173,19 +175,19 @@ class IncompleteForms extends Component { }, }, { - label: 'Data Entry Type', + label: t('Data Entry Type', {ns: 'behavioural_qc'}), show: true, filter: { name: 'Data Entry Type', type: 'select', options: { - 'IDE': 'Initial Data Entry (IDE)', - 'DDE': 'Double Data Entry (DDE)', + 'IDE': t('Initial Data Entry (IDE)', {ns: 'behavioural_qc'}), + 'DDE': t('Double Data Entry (DDE)', {ns: 'behavioural_qc'}), }, }, }, { - label: 'DCCID', + label: t('DCCID', {ns: 'loris'}), show: true, filter: { name: 'DCCID', @@ -193,7 +195,7 @@ class IncompleteForms extends Component { }, }, { - label: 'PSCID', + label: t('PSCID', {ns: 'loris'}), show: true, filter: { name: 'PSCID', @@ -201,7 +203,7 @@ class IncompleteForms extends Component { }, }, { - label: 'Visit', + label: t('Visit', {ns: 'loris'}), show: true, filter: { name: 'Visit', @@ -210,7 +212,7 @@ class IncompleteForms extends Component { }, }, { - label: 'Project', + label: t('Project', {ns: 'loris'}), show: false, filter: { name: 'Project', @@ -219,7 +221,7 @@ class IncompleteForms extends Component { }, }, { - label: 'Cohort', + label: t('Cohort', {ns: 'loris'}), show: false, filter: { name: 'Cohort', @@ -228,7 +230,7 @@ class IncompleteForms extends Component { }, }, { - label: 'Site', + label: t('Site', {ns: 'loris'}), show: false, filter: { name: 'Site', @@ -277,6 +279,7 @@ IncompleteForms.propTypes = { display: PropTypes.bool, data: PropTypes.object, baseURL: PropTypes.string.isRequired, + t: PropTypes.func, }; -export default IncompleteForms; +export default withTranslation(['behavioural_qc', 'loris'])(IncompleteForms); diff --git a/modules/behavioural_qc/locale/behavioural_qc.pot b/modules/behavioural_qc/locale/behavioural_qc.pot index 411b5fff841..cc8ebbe4716 100644 --- a/modules/behavioural_qc/locale/behavioural_qc.pot +++ b/modules/behavioural_qc/locale/behavioural_qc.pot @@ -21,6 +21,33 @@ msgstr "" msgid "Behavioural Quality Control" msgstr "" -msgid "Behavioural Session" -msgid_plural "Behavioural Sessions" -msgstr[0] "" +msgid "Incomplete Forms" +msgstr "" + +msgid "Data Conflicts" +msgstr "" + +msgid "Behavioural Feedback" +msgstr "" + +msgid "Data Entry Type" +msgstr "" + +msgid "Initial Data Entry (IDE)" +msgstr "" + +msgid "Double Data Entry (DDE)" +msgstr "" + +msgid "Field Name" +msgstr "" + +msgid "Feedback Level" +msgstr "" + +msgid "Test Name" +msgstr "" + +msgid "Feedback Status" +msgstr "" + diff --git a/modules/behavioural_qc/locale/hi/LC_MESSAGES/behavioural_qc.json b/modules/behavioural_qc/locale/hi/LC_MESSAGES/behavioural_qc.json new file mode 100644 index 00000000000..ee19250d212 --- /dev/null +++ b/modules/behavioural_qc/locale/hi/LC_MESSAGES/behavioural_qc.json @@ -0,0 +1,13 @@ +{ + "Behavioural Quality Control": "व्यवहारिक गुणवत्ता नियंत्रण", + "Incomplete Forms": "अधूरी प्रपत्र", + "Data Conflicts": "डेटा संघर्ष", + "Behavioural Feedback": "व्यवहारिक प्रतिक्रिया", + "Data Entry Type": "डेटा प्रविष्टि प्रकार", + "Initial Data Entry (IDE)": "प्रारंभिक डेटा प्रविष्टि (IDE)", + "Double Data Entry (DDE)": "द्वि-डेटा प्रविष्टि (DDE)", + "Field Name": "फ़ील्ड नाम", + "Feedback Level": "प्रतिक्रिया स्तर", + "Test Name": "परीक्षण नाम", + "Feedback Status": "प्रतिक्रिया स्थिति" +} \ No newline at end of file diff --git a/modules/behavioural_qc/locale/hi/LC_MESSAGES/behavioural_qc.po b/modules/behavioural_qc/locale/hi/LC_MESSAGES/behavioural_qc.po new file mode 100644 index 00000000000..a7e7a1321db --- /dev/null +++ b/modules/behavioural_qc/locale/hi/LC_MESSAGES/behavioural_qc.po @@ -0,0 +1,54 @@ +# 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 "Behavioural Quality Control" +msgstr "व्यवहारिक गुणवत्ता नियंत्रण" + +msgid "Incomplete Forms" +msgstr "अधूरी प्रपत्र" + +msgid "Data Conflicts" +msgstr "डेटा संघर्ष" + +msgid "Behavioural Feedback" +msgstr "व्यवहारिक प्रतिक्रिया" + +msgid "Data Entry Type" +msgstr "डेटा प्रविष्टि प्रकार" + +msgid "Initial Data Entry (IDE)" +msgstr "प्रारंभिक डेटा प्रविष्टि (IDE)" + +msgid "Double Data Entry (DDE)" +msgstr "द्वि-डेटा प्रविष्टि (DDE)" + +msgid "Field Name" +msgstr "फ़ील्ड नाम" + +msgid "Feedback Level" +msgstr "प्रतिक्रिया स्तर" + +msgid "Test Name" +msgstr "परीक्षण नाम" + +msgid "Feedback Status" +msgstr "प्रतिक्रिया स्थिति" + +