diff --git a/Makefile b/Makefile index 8a4ffdb136b..b81d0becdf8 100755 --- a/Makefile +++ b/Makefile @@ -86,6 +86,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/fr/LC_MESSAGES/candidate_list.mo modules/candidate_list/locale/fr/LC_MESSAGES/candidate_list.po @@ -218,7 +220,11 @@ 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 my_preferences: modules/my_preferences/locale/ja/LC_MESSAGES/my_preferences.mo modules/my_preferences/locale/hi/LC_MESSAGES/my_preferences.mo npx i18next-conv -l ja -s modules/my_preferences/locale/ja/LC_MESSAGES/my_preferences.po -t modules/my_preferences/locale/ja/LC_MESSAGES/my_preferences.json --compatibilityJSON v4 npx i18next-conv -l hi -s modules/my_preferences/locale/hi/LC_MESSAGES/my_preferences.po -t modules/my_preferences/locale/hi/LC_MESSAGES/my_preferences.json --compatibilityJSON v4 - target=my_preferences npm run compile + target=my_preferences 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 52f26109475..0e6fa2aa970 100644 --- a/locale/hi/LC_MESSAGES/loris.po +++ b/locale/hi/LC_MESSAGES/loris.po @@ -396,8 +396,10 @@ msgstr "प्रगति पर" msgid "Complete" msgstr "पूर्ण" -msgid "Instruments" -msgstr "उपकरण" +msgid "Instrument" +msgid_plural "Instruments" +msgstr[0] "उपकरण" +msgstr[1] "उपकरण" msgid "Partial" 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..a07018eaec0 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,80 @@ 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'}); + const labelInstrument = t('Instrument', {ns: 'loris', count: 1}); + const labelTestName = t('Test Name', {ns: 'behavioural_qc'}); + const labelVisit = t('Visit', {ns: 'loris'}); + + // PSCID column (match English or translated) + if (column === 'PSCID' || column === labelPSCID) { + return ( - - {rowData['PSCID']} + + {rowData[labelPSCID]} ); - break; - case 'DCCID': - reactElement = ( + } + + // DCCID column + if (column === 'DCCID' || column === labelDCCID) { + return ( - - {rowData['DCCID']} + + {rowData[labelDCCID]} ); - 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']) { + if (rowData[labelInstrument]) { 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']; - } else if (rowData['Visit']) { + '/instruments/' + + rowData[labelTestName] + + '/?candID=' + rowData[labelDCCID] + + '&sessionID=' + rowData['sessionID'] + + '&commentID=' + rowData['commentID'] + + '&showFeedback=true'; + bvlLevel = labelInstrument + ' : ' + + rowData[labelInstrument]; + } else if (rowData[labelVisit]) { 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[labelDCCID] + + '&sessionID=' + rowData['sessionID'] + + '&showFeedback=true'; + bvlLevel = labelVisit + ' : ' + + rowData[labelVisit]; } else { - bvlLink = this.props.baseURL + - '/' + rowData['DCCID']; - // Open feedback panel - bvlLink += '/?showFeedback=true'; - bvlLevel ='Profile : ' + rowData['PSCID']; + bvlLink = this.props.baseURL + '/' + rowData[labelDCCID] + + '/?showFeedback=true'; + bvlLevel = t('Profile', {ns: 'behavioural_qc'}) + ' : ' + + rowData[labelPSCID]; } - 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 +165,7 @@ class BehaviouralFeedback extends Component { // The fields configured for display/hide. let fields = [ { - label: 'Instrument', + label: t('Instrument', {ns: 'loris', count: 1}), show: false, filter: { name: 'Instrument', @@ -179,7 +177,7 @@ class BehaviouralFeedback extends Component { }, }, { - label: 'DCCID', + label: t('DCCID', {ns: 'loris'}), show: true, filter: { name: 'DCCID', @@ -187,7 +185,7 @@ class BehaviouralFeedback extends Component { }, }, { - label: 'PSCID', + label: t('PSCID', {ns: 'loris'}), show: true, filter: { name: 'PSCID', @@ -195,7 +193,7 @@ class BehaviouralFeedback extends Component { }, }, { - label: 'Visit', + label: t('Visit', {ns: 'loris'}), show: false, filter: { name: 'Visit', @@ -204,7 +202,7 @@ class BehaviouralFeedback extends Component { }, }, { - label: 'Project', + label: t('Project', {ns: 'loris', count: 1}), show: false, filter: { name: 'Project', @@ -213,7 +211,7 @@ class BehaviouralFeedback extends Component { }, }, { - label: 'Cohort', + label: t('Cohort', {ns: 'loris', count: 1}), show: false, filter: { name: 'Cohort', @@ -222,7 +220,7 @@ class BehaviouralFeedback extends Component { }, }, { - label: 'Site', + label: t('Site', {ns: 'loris', count: 1}), show: false, filter: { name: 'Site', @@ -243,19 +241,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 +278,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..6d086dcb1a3 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', count: 1}), 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', count: 1}), show: true, filter: { name: 'Visit', @@ -198,7 +200,7 @@ class DataConflicts extends Component { }, }, { - label: 'Project', + label: t('Project', {ns: 'loris', count: 1}), show: false, filter: { name: 'Project', @@ -207,7 +209,7 @@ class DataConflicts extends Component { }, }, { - label: 'Cohort', + label: t('Cohort', {ns: 'loris', count: 1}), show: false, filter: { name: 'Cohort', @@ -216,7 +218,7 @@ class DataConflicts extends Component { }, }, { - label: 'Site', + label: t('Site', {ns: 'loris', count: 1}), 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..bac4d4b82c6 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', count: 1}), 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', count: 1}), show: true, filter: { name: 'Visit', @@ -210,7 +212,7 @@ class IncompleteForms extends Component { }, }, { - label: 'Project', + label: t('Project', {ns: 'loris', count: 1}), show: false, filter: { name: 'Project', @@ -219,7 +221,7 @@ class IncompleteForms extends Component { }, }, { - label: 'Cohort', + label: t('Cohort', {ns: 'loris', count: 1}), show: false, filter: { name: 'Cohort', @@ -228,7 +230,7 @@ class IncompleteForms extends Component { }, }, { - label: 'Site', + label: t('Site', {ns: 'loris', count: 1}), 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..32d6ae2b16c 100644 --- a/modules/behavioural_qc/locale/behavioural_qc.pot +++ b/modules/behavioural_qc/locale/behavioural_qc.pot @@ -21,6 +21,37 @@ msgstr "" msgid "Behavioural Quality Control" msgstr "" -msgid "Behavioural Session" +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..fe0097baa68 --- /dev/null +++ b/modules/behavioural_qc/locale/hi/LC_MESSAGES/behavioural_qc.po @@ -0,0 +1,62 @@ +# 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 "Behavioural Session" +msgid_plural "Behavioural Sessions" +msgstr[0] "व्यवहारिक सत्र" +msgstr[1] "व्यवहारिक सत्र" + +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 "प्रतिक्रिया स्थिति" + +msgid "Profile" +msgstr "प्रोफाइल" + + diff --git a/modules/behavioural_qc/php/behavioural_qc.class.inc b/modules/behavioural_qc/php/behavioural_qc.class.inc index c371e45c39f..03229443c56 100644 --- a/modules/behavioural_qc/php/behavioural_qc.class.inc +++ b/modules/behavioural_qc/php/behavioural_qc.class.inc @@ -69,7 +69,7 @@ class Behavioural_QC extends \NDB_Form { return new \LORIS\BreadcrumbTrail( new \LORIS\Breadcrumb( - 'Behavioural Quality Control', + dgettext("behavioural_qc", "Behavioural Quality Control"), '/behavioural_qc' ) );