From 6bcc436eaae31ca5e0f1b25030832aa42cf94e54 Mon Sep 17 00:00:00 2001 From: Saket Hatwar Date: Tue, 29 Jul 2025 16:16:19 -0400 Subject: [PATCH 01/17] Add Translation --- Makefile | 3 +- .../user_accounts/jsx/userAccountsIndex.js | 57 +++++++++--------- .../locale/hi/LC_MESSAGES/user_accounts.po | 58 +++++++++++++++++++ .../user_accounts/locale/user_accounts.pot | 34 ++++++++++- 4 files changed, 123 insertions(+), 29 deletions(-) create mode 100644 modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po diff --git a/Makefile b/Makefile index c614da9d7bb..418259aa97c 100755 --- a/Makefile +++ b/Makefile @@ -117,7 +117,8 @@ locales: msgfmt -o modules/survey_accounts/locale/ja/LC_MESSAGES/survey_accounts.mo modules/survey_accounts/locale/ja/LC_MESSAGES/survey_accounts.po msgfmt -o modules/timepoint_list/locale/ja/LC_MESSAGES/timepoint_list.mo modules/timepoint_list/locale/ja/LC_MESSAGES/timepoint_list.po msgfmt -o modules/user_accounts/locale/ja/LC_MESSAGES/user_accounts.mo modules/user_accounts/locale/ja/LC_MESSAGES/user_accounts.po - + msgfmt -o modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.mo modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po + npx i18next-conv -l hi -s modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po -t modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.json acknowledgements: target=acknowledgements npm run compile diff --git a/modules/user_accounts/jsx/userAccountsIndex.js b/modules/user_accounts/jsx/userAccountsIndex.js index 56d491d69ea..e8a42e4b23a 100644 --- a/modules/user_accounts/jsx/userAccountsIndex.js +++ b/modules/user_accounts/jsx/userAccountsIndex.js @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import i18n from 'I18nSetup'; import {withTranslation} from 'react-i18next'; +import hiStrings from '../locale/hi/LC_MESSAGES/user_accounts.json'; import Loader from 'Loader'; import FilterableDataTable from 'FilterableDataTable'; @@ -21,8 +22,8 @@ class UserAccountsIndex extends Component { /** * {@inheritdoc} */ - constructor() { - super(); + constructor(props) { + super(props); this.state = { data: {}, @@ -69,11 +70,11 @@ class UserAccountsIndex extends Component { * @return {*} a formated table cell for a given column */ formatColumn(column, cell, row) { + const { t } = this.props; let url; let result = {cell}; switch (column) { - case 'Site': - // If user has multiple sites, join array of sites into string + case t('Site', {ns: 'user_accounts'}): result = ( {cell .map((centerId) => this.state.data.fieldOptions.sites[centerId]) @@ -82,12 +83,11 @@ class UserAccountsIndex extends Component { ); if (cell.length === 0) { result = ( - This user has no site affiliations + {t('This user has no site affiliations', {ns: 'user_accounts'})} ); } break; - case 'Project': - // If user has multiple projects, join array of sites into string + case t('Project', {ns: 'user_accounts'}): result = ( {cell.map( (projectId) => this.state.data.fieldOptions.projects[projectId] @@ -96,26 +96,26 @@ class UserAccountsIndex extends Component { ); if (cell.length === 0) { result = ( - This user has no project affiliations + {t('This user has no project affiliations', {ns: 'user_accounts'})} ); } break; - case 'Username': + case t('Username', {ns: 'user_accounts'}): url = loris.BaseURL + '/user_accounts/edit_user/' + row.Username; result = {cell}; break; - case 'Active': + case t('Active', {ns: 'user_accounts'}): if (row.Active === 'Y') { - result = Yes; + result = {t('Yes', {ns: 'user_accounts'})}; } else if (row.Active === 'N') { - result = No; + result = {t('No', {ns: 'user_accounts'})}; } break; - case 'Pending Approval': + case t('Pending Approval', {ns: 'user_accounts'}): if (row['Pending Approval'] === 'Y') { - result = Yes; + result = {t('Yes', {ns: 'user_accounts'})}; } else if (row['Pending Approval'] === 'N') { - result = No; + result = {t('No', {ns: 'user_accounts'})}; } break; } @@ -135,10 +135,11 @@ class UserAccountsIndex extends Component { * @return {object} */ 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: 'user_accounts'})}

; } // Waiting for async data to load @@ -152,52 +153,52 @@ class UserAccountsIndex extends Component { */ const options = this.state.data.fieldOptions; const fields = [ - {label: 'Site', show: true, filter: { + {label: t('Site', {ns: 'user_accounts'}), show: true, filter: { name: 'site', type: 'multiselect', options: options.sites, }}, - {label: 'Project', show: true, filter: { + {label: t('Project', {ns: 'user_accounts'}), show: true, filter: { name: 'project', type: 'select', options: options.projects, }}, - {label: 'Username', show: true, filter: { + {label: t('Username', {ns: 'user_accounts'}), show: true, filter: { name: 'username', type: 'text', }}, - {label: 'Full Name', show: true, filter: { + {label: t('Full Name', {ns: 'user_accounts'}), show: true, filter: { name: 'fullName', type: 'text', }}, - {label: 'Email', show: true, filter: { + {label: t('Email', {ns: 'user_accounts'}), show: true, filter: { name: 'email', type: 'text', }}, - {label: 'Active', show: true, filter: { + {label: t('Active', {ns: 'user_accounts'}), show: true, filter: { name: 'active', type: 'select', options: options.actives, }}, - {label: 'Pending Approval', show: true, filter: { + {label: t('Pending Approval', {ns: 'user_accounts'}), show: true, filter: { name: 'pendingApproval', type: 'select', options: options.pendingApprovals, }}, - {label: 'Account Request Date', show: true, filter: { + {label: t('Account Request Date', {ns: 'user_accounts'}), show: true, filter: { name: 'accountRequestDate', type: 'date', hide: true, }}, ]; const actions = [ - {label: 'Add User', action: this.addUser}, + {label: t('Add User', {ns: 'user_accounts'}), action: this.addUser}, ]; return ( { i18n.addResourceBundle('ja', 'user_accounts', {}); + i18n.addResourceBundle('hi', 'user_accounts', hiStrings); const Index = withTranslation( ['user_accounts', 'loris'] )(UserAccountsIndex); @@ -226,3 +229,5 @@ window.addEventListener('load', () => { /> ); }); + +export default withTranslation(['user_accounts', 'loris'])(UserAccountsIndex); diff --git a/modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po b/modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po new file mode 100644 index 00000000000..5ce87a2062a --- /dev/null +++ b/modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po @@ -0,0 +1,58 @@ +# 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 "User Accounts" +msgstr "उपयोगकर्ता खाते" + +msgid "Edit User" +msgstr "उपयोगकर्ता संपादित करें" + +# --- Strings not in loris.pot, add below --- + +msgid "This user has no site affiliations" +msgstr "इस उपयोगकर्ता की कोई साइट संबद्धता नहीं है" + +msgid "This user has no project affiliations" +msgstr "इस उपयोगकर्ता की कोई परियोजना संबद्धता नहीं है" + +msgid "Username" +msgstr "उपयोगकर्ता नाम" + +msgid "Full Name" +msgstr "पूरा नाम" + +msgid "Email" +msgstr "ईमेल" + +msgid "Active" +msgstr "सक्रिय" + +msgid "Pending Approval" +msgstr "स्वीकृति लंबित" + +msgid "Account Request Date" +msgstr "खाता अनुरोध तिथि" + +msgid "Add User" +msgstr "उपयोगकर्ता जोड़ें" + +msgid "An error occured while loading the page." +msgstr "पृष्ठ लोड करते समय एक त्रुटि हुई।" + diff --git a/modules/user_accounts/locale/user_accounts.pot b/modules/user_accounts/locale/user_accounts.pot index da7b43163f9..16133caac0b 100644 --- a/modules/user_accounts/locale/user_accounts.pot +++ b/modules/user_accounts/locale/user_accounts.pot @@ -24,8 +24,38 @@ msgstr "" msgid "Edit User" msgstr "" -msgid "Pending account approval" +# --- Strings not in loris.pot, add below --- + +msgid "This user has no site affiliations" +msgstr "" + +msgid "This user has no project affiliations" +msgstr "" + +msgid "Username" +msgstr "" + +msgid "Full Name" +msgstr "" + +msgid "Email" +msgstr "" + +msgid "Active" msgstr "" -msgid "Pending account approvals" +msgid "Pending Approval" msgstr "" + +msgid "Account Request Date" +msgstr "" + +msgid "Add User" +msgstr "" + +msgid "User Accounts" +msgstr "" + +msgid "An error occured while loading the page." +msgstr "" + From be4cb27efd0b54661de95df8583621ee154793ca Mon Sep 17 00:00:00 2001 From: Saket Hatwar Date: Wed, 30 Jul 2025 12:25:53 -0400 Subject: [PATCH 02/17] Fix lint issues --- .../user_accounts/jsx/userAccountsIndex.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/modules/user_accounts/jsx/userAccountsIndex.js b/modules/user_accounts/jsx/userAccountsIndex.js index e8a42e4b23a..1dee8a5ff82 100644 --- a/modules/user_accounts/jsx/userAccountsIndex.js +++ b/modules/user_accounts/jsx/userAccountsIndex.js @@ -70,7 +70,7 @@ class UserAccountsIndex extends Component { * @return {*} a formated table cell for a given column */ formatColumn(column, cell, row) { - const { t } = this.props; + const {t} = this.props; let url; let result = {cell}; switch (column) { @@ -83,7 +83,8 @@ class UserAccountsIndex extends Component { ); if (cell.length === 0) { result = ( - {t('This user has no site affiliations', {ns: 'user_accounts'})} + {t('This user has no site affiliations', + {ns: 'user_accounts'})} ); } break; @@ -96,7 +97,8 @@ class UserAccountsIndex extends Component { ); if (cell.length === 0) { result = ( - {t('This user has no project affiliations', {ns: 'user_accounts'})} + {t('This user has no project affiliations', + {ns: 'user_accounts'})} ); } break; @@ -135,11 +137,12 @@ class UserAccountsIndex extends Component { * @return {object} */ render() { - const { t } = this.props; + 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

{t('An error occured while loading the page.', {ns: 'user_accounts'})}

; + return

{t('An error occured while loading the page.', + {ns: 'user_accounts'})}

; } // Waiting for async data to load @@ -180,12 +183,14 @@ class UserAccountsIndex extends Component { type: 'select', options: options.actives, }}, - {label: t('Pending Approval', {ns: 'user_accounts'}), show: true, filter: { + {label: t('Pending Approval', {ns: 'user_accounts'}), + show: true, filter: { name: 'pendingApproval', type: 'select', options: options.pendingApprovals, }}, - {label: t('Account Request Date', {ns: 'user_accounts'}), show: true, filter: { + {label: t('Account Request Date', {ns: 'user_accounts'}), + show: true, filter: { name: 'accountRequestDate', type: 'date', hide: true, From be2935024d309545e605a470eed5ec6fc37eca0f Mon Sep 17 00:00:00 2001 From: Saket Hatwar Date: Wed, 30 Jul 2025 12:46:18 -0400 Subject: [PATCH 03/17] lint --- .../user_accounts/jsx/userAccountsIndex.js | 212 +++++++++++------- 1 file changed, 127 insertions(+), 85 deletions(-) diff --git a/modules/user_accounts/jsx/userAccountsIndex.js b/modules/user_accounts/jsx/userAccountsIndex.js index 1dee8a5ff82..98a3542e2c2 100644 --- a/modules/user_accounts/jsx/userAccountsIndex.js +++ b/modules/user_accounts/jsx/userAccountsIndex.js @@ -17,6 +17,8 @@ import FilterableDataTable from 'FilterableDataTable'; * * When clicking on the Add User button or a Username, this component redirects * the user to a form that allows them to add or edit a user. + * + * @param {object} props - React component properties */ class UserAccountsIndex extends Component { /** @@ -74,52 +76,56 @@ class UserAccountsIndex extends Component { let url; let result = {cell}; switch (column) { - case t('Site', {ns: 'user_accounts'}): - result = ( - {cell - .map((centerId) => this.state.data.fieldOptions.sites[centerId]) - .join(', ')} - - ); - if (cell.length === 0) { + case t('Site', {ns: 'user_accounts'}): result = ( - {t('This user has no site affiliations', - {ns: 'user_accounts'})} + + {cell + .map((centerId) => this.state.data.fieldOptions.sites[centerId]) + .join(', ')} + ); - } - break; - case t('Project', {ns: 'user_accounts'}): - result = ( - {cell.map( - (projectId) => this.state.data.fieldOptions.projects[projectId] - ).join(', ')} - - ); - if (cell.length === 0) { + if (cell.length === 0) { + result = ( + + {t('This user has no site affiliations', {ns: 'user_accounts'})} + + ); + } + break; + case t('Project', {ns: 'user_accounts'}): result = ( - {t('This user has no project affiliations', - {ns: 'user_accounts'})} + + {cell.map( + (projectId) => this.state.data.fieldOptions.projects[projectId] + ).join(', ')} + ); - } - break; - case t('Username', {ns: 'user_accounts'}): - url = loris.BaseURL + '/user_accounts/edit_user/' + row.Username; - result = {cell}; - break; - case t('Active', {ns: 'user_accounts'}): - if (row.Active === 'Y') { - result = {t('Yes', {ns: 'user_accounts'})}; - } else if (row.Active === 'N') { - result = {t('No', {ns: 'user_accounts'})}; - } - break; - case t('Pending Approval', {ns: 'user_accounts'}): - if (row['Pending Approval'] === 'Y') { - result = {t('Yes', {ns: 'user_accounts'})}; - } else if (row['Pending Approval'] === 'N') { - result = {t('No', {ns: 'user_accounts'})}; - } - break; + if (cell.length === 0) { + result = ( + + {t('This user has no project affiliations', {ns: 'user_accounts'})} + + ); + } + break; + case t('Username', {ns: 'user_accounts'}): + url = loris.BaseURL + '/user_accounts/edit_user/' + row.Username; + result = {cell}; + break; + case t('Active', {ns: 'user_accounts'}): + if (row.Active === 'Y') { + result = {t('Yes', {ns: 'user_accounts'})}; + } else if (row.Active === 'N') { + result = {t('No', {ns: 'user_accounts'})}; + } + break; + case t('Pending Approval', {ns: 'user_accounts'}): + if (row['Pending Approval'] === 'Y') { + result = {t('Yes', {ns: 'user_accounts'})}; + } else if (row['Pending Approval'] === 'N') { + result = {t('No', {ns: 'user_accounts'})}; + } + break; } return result; } @@ -128,7 +134,7 @@ class UserAccountsIndex extends Component { * Changes url to be able to add or edit a User. */ addUser() { - location.href='/user_accounts/edit_user/'; + location.href = '/user_accounts/edit_user/'; } /** @@ -141,8 +147,11 @@ class UserAccountsIndex extends Component { // If error occurs, return a message. // XXX: Replace this with a UI component for 500 errors. if (this.state.error) { - return

{t('An error occured while loading the page.', - {ns: 'user_accounts'})}

; + return ( +

+ {t('An error occured while loading the page.', {ns: 'user_accounts'})} +

+ ); } // Waiting for async data to load @@ -156,48 +165,81 @@ class UserAccountsIndex extends Component { */ const options = this.state.data.fieldOptions; const fields = [ - {label: t('Site', {ns: 'user_accounts'}), show: true, filter: { - name: 'site', - type: 'multiselect', - options: options.sites, - }}, - {label: t('Project', {ns: 'user_accounts'}), show: true, filter: { - name: 'project', - type: 'select', - options: options.projects, - }}, - {label: t('Username', {ns: 'user_accounts'}), show: true, filter: { - name: 'username', - type: 'text', - }}, - {label: t('Full Name', {ns: 'user_accounts'}), show: true, filter: { - name: 'fullName', - type: 'text', - }}, - {label: t('Email', {ns: 'user_accounts'}), show: true, filter: { - name: 'email', - type: 'text', - }}, - {label: t('Active', {ns: 'user_accounts'}), show: true, filter: { - name: 'active', - type: 'select', - options: options.actives, - }}, - {label: t('Pending Approval', {ns: 'user_accounts'}), - show: true, filter: { - name: 'pendingApproval', - type: 'select', - options: options.pendingApprovals, - }}, - {label: t('Account Request Date', {ns: 'user_accounts'}), - show: true, filter: { - name: 'accountRequestDate', - type: 'date', - hide: true, - }}, + { + label: t('Site', {ns: 'user_accounts'}), + show: true, + filter: { + name: 'site', + type: 'multiselect', + options: options.sites, + }, + }, + { + label: t('Project', {ns: 'user_accounts'}), + show: true, + filter: { + name: 'project', + type: 'select', + options: options.projects, + }, + }, + { + label: t('Username', {ns: 'user_accounts'}), + show: true, + filter: { + name: 'username', + type: 'text', + }, + }, + { + label: t('Full Name', {ns: 'user_accounts'}), + show: true, + filter: { + name: 'fullName', + type: 'text', + }, + }, + { + label: t('Email', {ns: 'user_accounts'}), + show: true, + filter: { + name: 'email', + type: 'text', + }, + }, + { + label: t('Active', {ns: 'user_accounts'}), + show: true, + filter: { + name: 'active', + type: 'select', + options: options.actives, + }, + }, + { + label: t('Pending Approval', {ns: 'user_accounts'}), + show: true, + filter: { + name: 'pendingApproval', + type: 'select', + options: options.pendingApprovals, + }, + }, + { + label: t('Account Request Date', {ns: 'user_accounts'}), + show: true, + filter: { + name: 'accountRequestDate', + type: 'date', + hide: true, + }, + }, ]; const actions = [ - {label: t('Add User', {ns: 'user_accounts'}), action: this.addUser}, + { + label: t('Add User', {ns: 'user_accounts'}), + action: this.addUser, + }, ]; return ( From ac8de258787197f3958237c365407a9eda7a8f49 Mon Sep 17 00:00:00 2001 From: Saket Hatwar Date: Fri, 8 Aug 2025 10:14:25 -0400 Subject: [PATCH 04/17] Lint issues --- .../user_accounts/jsx/userAccountsIndex.js | 86 ++++++++++--------- 1 file changed, 44 insertions(+), 42 deletions(-) diff --git a/modules/user_accounts/jsx/userAccountsIndex.js b/modules/user_accounts/jsx/userAccountsIndex.js index 98a3542e2c2..c6ff5e54c76 100644 --- a/modules/user_accounts/jsx/userAccountsIndex.js +++ b/modules/user_accounts/jsx/userAccountsIndex.js @@ -23,6 +23,8 @@ import FilterableDataTable from 'FilterableDataTable'; class UserAccountsIndex extends Component { /** * {@inheritdoc} + * + * @param props */ constructor(props) { super(props); @@ -76,56 +78,56 @@ class UserAccountsIndex extends Component { let url; let result = {cell}; switch (column) { - case t('Site', {ns: 'user_accounts'}): + case t('Site', {ns: 'user_accounts'}): + result = ( + + {cell + .map((centerId) => this.state.data.fieldOptions.sites[centerId]) + .join(', ')} + + ); + if (cell.length === 0) { result = ( - {cell - .map((centerId) => this.state.data.fieldOptions.sites[centerId]) - .join(', ')} + {t('This user has no site affiliations', {ns: 'user_accounts'})} ); - if (cell.length === 0) { - result = ( - - {t('This user has no site affiliations', {ns: 'user_accounts'})} - - ); - } - break; - case t('Project', {ns: 'user_accounts'}): + } + break; + case t('Project', {ns: 'user_accounts'}): + result = ( + + {cell.map( + (projectId) => this.state.data.fieldOptions.projects[projectId] + ).join(', ')} + + ); + if (cell.length === 0) { result = ( - {cell.map( - (projectId) => this.state.data.fieldOptions.projects[projectId] - ).join(', ')} + {t('This user has no project affiliations', {ns: 'user_accounts'})} ); - if (cell.length === 0) { - result = ( - - {t('This user has no project affiliations', {ns: 'user_accounts'})} - - ); - } - break; - case t('Username', {ns: 'user_accounts'}): - url = loris.BaseURL + '/user_accounts/edit_user/' + row.Username; - result = {cell}; - break; - case t('Active', {ns: 'user_accounts'}): - if (row.Active === 'Y') { - result = {t('Yes', {ns: 'user_accounts'})}; - } else if (row.Active === 'N') { - result = {t('No', {ns: 'user_accounts'})}; - } - break; - case t('Pending Approval', {ns: 'user_accounts'}): - if (row['Pending Approval'] === 'Y') { - result = {t('Yes', {ns: 'user_accounts'})}; - } else if (row['Pending Approval'] === 'N') { - result = {t('No', {ns: 'user_accounts'})}; - } - break; + } + break; + case t('Username', {ns: 'user_accounts'}): + url = loris.BaseURL + '/user_accounts/edit_user/' + row.Username; + result = {cell}; + break; + case t('Active', {ns: 'user_accounts'}): + if (row.Active === 'Y') { + result = {t('Yes', {ns: 'user_accounts'})}; + } else if (row.Active === 'N') { + result = {t('No', {ns: 'user_accounts'})}; + } + break; + case t('Pending Approval', {ns: 'user_accounts'}): + if (row['Pending Approval'] === 'Y') { + result = {t('Yes', {ns: 'user_accounts'})}; + } else if (row['Pending Approval'] === 'N') { + result = {t('No', {ns: 'user_accounts'})}; + } + break; } return result; } From d7bc8fcb8ff721465bee232795978b6ee0d7cbdf Mon Sep 17 00:00:00 2001 From: Saket Hatwar Date: Mon, 18 Aug 2025 14:27:07 -0400 Subject: [PATCH 05/17] change workspace --- modules/user_accounts/jsx/userAccountsIndex.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/user_accounts/jsx/userAccountsIndex.js b/modules/user_accounts/jsx/userAccountsIndex.js index c6ff5e54c76..1010cb04f35 100644 --- a/modules/user_accounts/jsx/userAccountsIndex.js +++ b/modules/user_accounts/jsx/userAccountsIndex.js @@ -78,7 +78,7 @@ class UserAccountsIndex extends Component { let url; let result = {cell}; switch (column) { - case t('Site', {ns: 'user_accounts'}): + case t('Site', {ns: 'loris'}): result = ( {cell @@ -94,7 +94,7 @@ class UserAccountsIndex extends Component { ); } break; - case t('Project', {ns: 'user_accounts'}): + case t('Project', {ns: 'loris'}): result = ( {cell.map( @@ -151,7 +151,7 @@ class UserAccountsIndex extends Component { if (this.state.error) { return (

- {t('An error occured while loading the page.', {ns: 'user_accounts'})} + {t('An error occured while loading the page.', {ns: 'loris'})}

); } @@ -168,7 +168,7 @@ class UserAccountsIndex extends Component { const options = this.state.data.fieldOptions; const fields = [ { - label: t('Site', {ns: 'user_accounts'}), + label: t('Site', {ns: 'loris'}), show: true, filter: { name: 'site', @@ -177,7 +177,7 @@ class UserAccountsIndex extends Component { }, }, { - label: t('Project', {ns: 'user_accounts'}), + label: t('Project', {ns: 'loris'}), show: true, filter: { name: 'project', From 537ccc6721a409fb4eded0c550d934881a27957a Mon Sep 17 00:00:00 2001 From: Saket Hatwar Date: Tue, 26 Aug 2025 07:00:28 -0400 Subject: [PATCH 06/17] workspace changes --- modules/user_accounts/jsx/userAccountsIndex.js | 8 ++++---- .../user_accounts/locale/hi/LC_MESSAGES/user_accounts.po | 2 -- modules/user_accounts/locale/user_accounts.pot | 5 ----- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/modules/user_accounts/jsx/userAccountsIndex.js b/modules/user_accounts/jsx/userAccountsIndex.js index 1010cb04f35..d8e270394a1 100644 --- a/modules/user_accounts/jsx/userAccountsIndex.js +++ b/modules/user_accounts/jsx/userAccountsIndex.js @@ -116,16 +116,16 @@ class UserAccountsIndex extends Component { break; case t('Active', {ns: 'user_accounts'}): if (row.Active === 'Y') { - result = {t('Yes', {ns: 'user_accounts'})}; + result = {t('Yes', {ns: 'loris'})}; } else if (row.Active === 'N') { - result = {t('No', {ns: 'user_accounts'})}; + result = {t('No', {ns: 'loris'})}; } break; case t('Pending Approval', {ns: 'user_accounts'}): if (row['Pending Approval'] === 'Y') { - result = {t('Yes', {ns: 'user_accounts'})}; + result = {t('Yes', {ns: 'loris'})}; } else if (row['Pending Approval'] === 'N') { - result = {t('No', {ns: 'user_accounts'})}; + result = {t('No', {ns: 'loris'})}; } break; } diff --git a/modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po b/modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po index 5ce87a2062a..b9ed9aade7d 100644 --- a/modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po +++ b/modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po @@ -53,6 +53,4 @@ msgstr "खाता अनुरोध तिथि" msgid "Add User" msgstr "उपयोगकर्ता जोड़ें" -msgid "An error occured while loading the page." -msgstr "पृष्ठ लोड करते समय एक त्रुटि हुई।" diff --git a/modules/user_accounts/locale/user_accounts.pot b/modules/user_accounts/locale/user_accounts.pot index 16133caac0b..1649633bdf4 100644 --- a/modules/user_accounts/locale/user_accounts.pot +++ b/modules/user_accounts/locale/user_accounts.pot @@ -53,9 +53,4 @@ msgstr "" msgid "Add User" msgstr "" -msgid "User Accounts" -msgstr "" - -msgid "An error occured while loading the page." -msgstr "" From b163e0b9e6c8fad72631ecc6b1d324db3e3625ad Mon Sep 17 00:00:00 2001 From: Saket Hatwar Date: Fri, 29 Aug 2025 16:56:10 -0400 Subject: [PATCH 07/17] Add remaining Translation --- .../locale/hi/LC_MESSAGES/user_accounts.po | 45 +++++++++++++++++++ .../user_accounts/locale/user_accounts.pot | 45 +++++++++++++++++++ .../templates/form_edit_user.tpl | 30 ++++++------- 3 files changed, 105 insertions(+), 15 deletions(-) diff --git a/modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po b/modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po index b9ed9aade7d..5bab004e051 100644 --- a/modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po +++ b/modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po @@ -53,4 +53,49 @@ msgstr "खाता अनुरोध तिथि" msgid "Add User" msgstr "उपयोगकर्ता जोड़ें" +msgid "The form you submitted contains data entry errors" +msgstr "आपके द्वारा प्रस्तुत फॉर्म में डेटा प्रविष्टि त्रुटियां हैं" + +msgid "Password Rules" +msgstr "पासवर्ड नियम" + +msgid "The password must be at least 8 characters long." +msgstr "पासवर्ड कम से कम 8 अक्षर लंबा होना चाहिए।" + +msgid "The password cannot be your username or email address." +msgstr "पासवर्ड आपका उपयोगकर्ता नाम या ईमेल पता नहीं हो सकता।" + +msgid "No special characters are required but your password must be sufficiently complex to be accepted." +msgstr "कोई विशेष वर्ण आवश्यक नहीं हैं लेकिन आपका पासवर्ड स्वीकार किए जाने के लिए पर्याप्त रूप से जटिल होना चाहिए।" + +msgid "Please choose a unique password." +msgstr "कृपया एक अनूठा पासवर्ड चुनें।" + +msgid "We suggest using a password manager to generate one for you." +msgstr "हम आपके लिए एक उत्पन्न करने के लिए पासवर्ड प्रबंधक का उपयोग करने का सुझाव देते हैं।" + +msgid "Notes" +msgstr "नोट्स" + +msgid "It is recommended to use an email address as the username, for clarity and uniqueness." +msgstr "स्पष्टता और अद्वितीयता के लिए उपयोगकर्ता नाम के रूप में ईमेल पते का उपयोग करने की अनुशंसा की जाती है।" + +msgid "When generating a new password, please notify the user by checking 'Send email to user' box below!" +msgstr "नया पासवर्ड बनाते समय, कृपया नीचे 'उपयोगकर्ता को ईमेल भेजें' बॉक्स को चेक करके उपयोगकर्ता को सूचित करें!" + +msgid "Add/Edit User" +msgstr "उपयोगकर्ता जोड़ें/संपादित करें" + +msgid "Save" +msgstr "सहेजें" + +msgid "Reset" +msgstr "रीसेट करें" + +msgid "Back" +msgstr "वापस" + +msgid "Reject User" +msgstr "उपयोगकर्ता को अस्वीकार करें" + diff --git a/modules/user_accounts/locale/user_accounts.pot b/modules/user_accounts/locale/user_accounts.pot index 1649633bdf4..35eee09e8ae 100644 --- a/modules/user_accounts/locale/user_accounts.pot +++ b/modules/user_accounts/locale/user_accounts.pot @@ -53,4 +53,49 @@ msgstr "" msgid "Add User" msgstr "" +msgid "The form you submitted contains data entry errors" +msgstr "" + +msgid "Password Rules" +msgstr "" + +msgid "The password must be at least 8 characters long." +msgstr "" + +msgid "The password cannot be your username or email address." +msgstr "" + +msgid "No special characters are required but your password must be sufficiently complex to be accepted." +msgstr "" + +msgid "Please choose a unique password." +msgstr "" + +msgid "We suggest using a password manager to generate one for you." +msgstr "" + +msgid "Notes" +msgstr "" + +msgid "It is recommended to use an email address as the username, for clarity and uniqueness." +msgstr "" + +msgid "When generating a new password, please notify the user by checking 'Send email to user' box below!" +msgstr "" + +msgid "Add/Edit User" +msgstr "" + +msgid "Save" +msgstr "" + +msgid "Reset" +msgstr "" + +msgid "Back" +msgstr "" + +msgid "Reject User" +msgstr "" + diff --git a/modules/user_accounts/templates/form_edit_user.tpl b/modules/user_accounts/templates/form_edit_user.tpl index 74f97a53ff3..14464cbcd05 100644 --- a/modules/user_accounts/templates/form_edit_user.tpl +++ b/modules/user_accounts/templates/form_edit_user.tpl @@ -2,28 +2,28 @@
{if $form.errors} {/if}
-

Password Rules

+

{dgettext("user_accounts", "Password Rules")}

    -
  • The password must be at least 8 characters long.
  • -
  • The password cannot be your username or email address.
  • -
  • No special characters are required but your password must be sufficiently complex to be accepted.
  • +
  • {dgettext("user_accounts", "The password must be at least 8 characters long.")}
  • +
  • {dgettext("user_accounts", "The password cannot be your username or email address.")}
  • +
  • {dgettext("user_accounts", "No special characters are required but your password must be sufficiently complex to be accepted.")}
-

Please choose a unique password.

-

We suggest using a password manager to generate one for you.

-

Notes

+

{dgettext("user_accounts", "Please choose a unique password.")}

+

{dgettext("user_accounts", "We suggest using a password manager to generate one for you.")}

+

{dgettext("user_accounts", "Notes")}

    -
  • It is recommended to use an email address as the username, for clarity and uniqueness.
  • -
  • When generating a new password, please notify the user by checking 'Send email to user' box below!
  • +
  • {dgettext("user_accounts", "It is recommended to use an email address as the username, for clarity and uniqueness.")}
  • +
  • {dgettext("user_accounts", "When generating a new password, please notify the user by checking 'Send email to user' box below!")}
-

Add/Edit User

+

{dgettext("user_accounts", "Add/Edit User")}

{if $form.errors.UserID_Group|default}
{else} @@ -496,19 +496,19 @@
- +
- +
- +
{if $can_reject}
- +
{/if}
From aaebee6b2be04c86860cd8d979462ee389488e65 Mon Sep 17 00:00:00 2001 From: Saket Hatwar Date: Thu, 25 Sep 2025 08:26:11 -0400 Subject: [PATCH 08/17] Translate .inc files --- locale/hi/LC_MESSAGES/loris.po | 9 + locale/loris.pot | 9 + .../locale/hi/LC_MESSAGES/user_accounts.po | 131 +++++++++- .../user_accounts/locale/user_accounts.pot | 132 +++++++++- modules/user_accounts/php/edit_user.class.inc | 229 ++++++++++-------- .../user_accounts/php/user_accounts.class.inc | 20 +- .../templates/form_edit_user.tpl | 2 +- 7 files changed, 416 insertions(+), 116 deletions(-) diff --git a/locale/hi/LC_MESSAGES/loris.po b/locale/hi/LC_MESSAGES/loris.po index 353699aabc6..875c48e9af8 100644 --- a/locale/hi/LC_MESSAGES/loris.po +++ b/locale/hi/LC_MESSAGES/loris.po @@ -130,9 +130,15 @@ msgstr "दौरे का लेबल" msgid "Site" msgstr "साइट" +msgid "Sites" +msgstr "साइट्स" + msgid "Project" msgstr "परियोजना" +msgid "Projects" +msgstr "प्रोजेक्ट्स" + msgid "Cohort" msgstr "समूह" @@ -160,6 +166,9 @@ msgstr "जन्म तिथि" msgid "An error occured while loading the page." msgstr "पृष्ठ लोड करते समय एक त्रुटि हुई।" +msgid "Active" +msgstr "सक्रिय" + # Data table strings msgid "{{pageCount}} rows displayed of {{totalCount}}." msgstr "{{totalCount}} में से {{pageCount}} पंक्तियाँ प्रदर्शित" diff --git a/locale/loris.pot b/locale/loris.pot index 9aefccc63d1..106cf50f148 100644 --- a/locale/loris.pot +++ b/locale/loris.pot @@ -129,9 +129,15 @@ msgstr "" msgid "Site" msgstr "" +msgid "Sites" +msgstr "" + msgid "Project" msgstr "" +msgid "Projects" +msgstr "" + msgid "Cohort" msgstr "" @@ -159,6 +165,9 @@ msgstr "" msgid "An error occured while loading the page." msgstr "" +msgid "Active" +msgstr "" + # Data table strings msgid "{{pageCount}} rows displayed of {{totalCount}}." msgstr "" diff --git a/modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po b/modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po index 5bab004e051..efcfb249723 100644 --- a/modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po +++ b/modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po @@ -41,9 +41,6 @@ msgstr "पूरा नाम" msgid "Email" msgstr "ईमेल" -msgid "Active" -msgstr "सक्रिय" - msgid "Pending Approval" msgstr "स्वीकृति लंबित" @@ -98,4 +95,132 @@ msgstr "वापस" msgid "Reject User" msgstr "उपयोगकर्ता को अस्वीकार करें" +msgid "User name" +msgstr "उपयोगकर्ता नाम" + +msgid "Make user name match email address" +msgstr "उपयोगकर्ता नाम को ईमेल पता से मिलाएँ" + +msgid "Password" +msgstr "पासवर्ड" + +msgid "Generate new password" +msgstr "नया पासवर्ड बनाएं" + +msgid "Confirm Password" +msgstr "पासवर्ड की पुष्टि करें" + +msgid "First name" +msgstr "पहला नाम" + +msgid "Last name" +msgstr "अंतिम नाम" + +msgid "Degree" +msgstr "डिग्री" + +msgid "Academic Position" +msgstr "शैक्षणिक पद" + +msgid "Institution" +msgstr "संस्थान" + +msgid "Department" +msgstr "विभाग" + +msgid "Street Address" +msgstr "सड़क का पता" + +msgid "City" +msgstr "शहर" + +msgid "State/Province" +msgstr "राज्य/प्रांत" + +msgid "Zip/Postal Code" +msgstr "पिन/डाक कोड" + +msgid "Country" +msgstr "देश" + +msgid "FAX" +msgstr "फैक्स" + +msgid "Email address" +msgstr "ईमेल पता" + +msgid "Send email to user" +msgstr "उपयोगकर्ता को ईमेल भेजें" + +msgid "Confirm Email" +msgstr "ईमेल की पुष्टि करें" + +msgid "Examiner At:" +msgstr "परीक्षक स्थल:" + +msgid "Examiner Status" +msgstr "परीक्षक की स्थिति" + +msgid "Pending approval" +msgstr "अनुमोदन प्रतीक्षारत" + +msgid "Active from" +msgstr "सक्रिय शुरू" + +msgid "Active to" +msgstr "सक्रिय समाप्त" + +msgid "Permissions" +msgstr "अनुमतियाँ" + +msgid "Supervisors" +msgstr "पर्यवेक्षक" + +msgid "You cannot enter a user name if you want it to match the email address" +msgstr "यदि आप उपयोगकर्ता नाम को ईमेल से मेल करना चाहते हैं, तो आप इसे अलग से दर्ज नहीं कर सकते" + +msgid "You must enter a user name or choose to make it match the email address" +msgstr "आपको उपयोगकर्ता नाम दर्ज करना होगा या इसे ईमेल से मेल करने का विकल्प चुनना होगा" + +msgid "The user name already exists" +msgstr "उपयोगकर्ता नाम पहले से मौजूद है" + +msgid "The user name must not exceed 255 characters" +msgstr "उपयोगकर्ता नाम 255 अक्षरों से अधिक नहीं होना चाहिए" + +msgid "You cannot have the user name match an email address that contains a whitespace character" +msgstr "आप उपयोगकर्ता नाम को ऐसे ईमेल से मेल नहीं कर सकते जिसमें रिक्त स्थान हो" + +msgid "Whitespace characters are not allowed in user names" +msgstr "उपयोगकर्ता नाम में रिक्त स्थान की अनुमति नहीं है" + +msgid "Please specify password or click Generate new password" +msgstr "कृपया पासवर्ड निर्दिष्ट करें या 'नया पासवर्ड बनाएं' पर क्लिक करें" + +msgid "Password is required" +msgstr "पासवर्ड आवश्यक है" + +msgid "You must enter an email address" +msgstr "आपको ईमेल पता दर्ज करना होगा" + +msgid "Email and confirmed email do not match" +msgstr "ईमेल और पुष्टि की गई ईमेल मेल नहीं खाते" + +msgid "You must select at least one site/affiliation" +msgstr "आपको कम से कम एक साइट/संलग्नता चुननी होगी" + +msgid "You must select at least one project/affiliation" +msgstr "आपको कम से कम एक प्रोजेक्ट/संलग्नता चुननी होगी" + +msgid "Please specify if examiner is a radiologist" +msgstr "कृपया निर्दिष्ट करें कि परीक्षक रेडियोलॉजिस्ट है या नहीं" + +msgid "Please set pending approval Yes or No" +msgstr "कृपया 'अनुमोदन प्रतीक्षारत' को हाँ या नहीं सेट करें" + +msgid "Please select at least one examiner site or clear the 'Examiner status' fields below (i.e. 'Radiologist' and 'Pending Approval')." +msgstr "कृपया कम से कम एक परीक्षक स्थल चुनें या नीचे के 'परीक्षक स्थिति' फ़ील्ड्स (जैसे 'रेडियोलॉजिस्ट' और 'अनुमोदन प्रतीक्षारत') को साफ़ करें।" + +msgid "Please notice that the \"Active from\" date should be lesser or equal to the \"Active to\" date." +msgstr "कृपया ध्यान दें कि 'सक्रिय शुरू' तिथि, 'सक्रिय समाप्त' तिथि के बराबर या उससे पहले होनी चाहिए।" diff --git a/modules/user_accounts/locale/user_accounts.pot b/modules/user_accounts/locale/user_accounts.pot index 35eee09e8ae..660d0f1e756 100644 --- a/modules/user_accounts/locale/user_accounts.pot +++ b/modules/user_accounts/locale/user_accounts.pot @@ -41,9 +41,6 @@ msgstr "" msgid "Email" msgstr "" -msgid "Active" -msgstr "" - msgid "Pending Approval" msgstr "" @@ -98,4 +95,133 @@ msgstr "" msgid "Reject User" msgstr "" +msgid "User name" +msgstr "" + +msgid "Make user name match email address" +msgstr "" + +msgid "Password" +msgstr "" + +msgid "Generate new password" +msgstr "" + +msgid "Confirm Password" +msgstr "" + +msgid "First name" +msgstr "" + +msgid "Last name" +msgstr "" + +msgid "Degree" +msgstr "" + +msgid "Academic Position" +msgstr "" + +msgid "Institution" +msgstr "" + +msgid "Department" +msgstr "" + +msgid "Street Address" +msgstr "" + +msgid "City" +msgstr "" + +msgid "State/Province" +msgstr "" + +msgid "Zip/Postal Code" +msgstr "" + +msgid "Country" +msgstr "" + +msgid "FAX" +msgstr "" + +msgid "Email address" +msgstr "" + +msgid "Send email to user" +msgstr "" + +msgid "Confirm Email" +msgstr "" + +msgid "Examiner At:" +msgstr "" + +msgid "Examiner Status" +msgstr "" + +msgid "Pending approval" +msgstr "" + +msgid "Active from" +msgstr "" + +msgid "Active to" +msgstr "" + +msgid "Permissions" +msgstr "" + +msgid "Supervisors" +msgstr "" + +msgid "You cannot enter a user name if you want it to match the email address" +msgstr "" + +msgid "You must enter a user name or choose to make it match the email address" +msgstr "" + +msgid "The user name already exists" +msgstr "" + +msgid "The user name must not exceed 255 characters" +msgstr "" + +msgid "You cannot have the user name match an email address that contains a whitespace character" +msgstr "" + +msgid "Whitespace characters are not allowed in user names" +msgstr "" + +msgid "Please specify password or click Generate new password" +msgstr "" + +msgid "Password is required" +msgstr "" + +msgid "You must enter an email address" +msgstr "" + +msgid "Email and confirmed email do not match" +msgstr "" + +msgid "You must select at least one site/affiliation" +msgstr "" + +msgid "You must select at least one project/affiliation" +msgstr "" + +msgid "Please specify if examiner is a radiologist" +msgstr "" + +msgid "Please set pending approval Yes or No" +msgstr "" + +msgid "Please select at least one examiner site or clear the 'Examiner status' fields below (i.e. 'Radiologist' and 'Pending Approval')." +msgstr "" + +msgid "Please notice that the \"Active from\" date should be lesser or equal to the \"Active to\" date." +msgstr "" + diff --git a/modules/user_accounts/php/edit_user.class.inc b/modules/user_accounts/php/edit_user.class.inc index eb0da4b79f6..226be793baa 100644 --- a/modules/user_accounts/php/edit_user.class.inc +++ b/modules/user_accounts/php/edit_user.class.inc @@ -1,4 +1,6 @@ -hasPermission('user_accounts_multisite')) { return true; @@ -127,22 +131,22 @@ class Edit_User extends \NDB_Form } $defaults['examiner'] = $defaults['examiner'] ?? []; - foreach ($defaults['examiner'] as $cid=>$vals) { + foreach ($defaults['examiner'] as $cid => $vals) { //sets pending approval info - if ($cid=='pending') { + if ($cid == 'pending') { $defaults['examiner_pending'] = $vals; continue; } //gets radiologist Y/N from any of the active sites - if ($vals[0]=='Y') { - if ($vals[1]==='1') { + if ($vals[0] == 'Y') { + if ($vals[1] === '1') { $defaults['examiner_radiologist'] = 'Y'; } else { $defaults['examiner_radiologist'] = 'N'; } } - if ($vals[0]=='Y') { - $defaults['ex_'.$cid] ='on'; + if ($vals[0] == 'Y') { + $defaults['ex_' . $cid] = 'on'; } } @@ -152,13 +156,13 @@ class Edit_User extends \NDB_Form $curr_sub = \NDB_Notifier::getUserNotificationModuleServices( $user_id ); - foreach ($curr_sub as $module=>$operations) { + foreach ($curr_sub as $module => $operations) { foreach ($operations as $operation => $services) { unset($services['desc']); foreach ($services as $service => $subscribed) { - $var_name = "notif_".$module."_".$operation."_".$service; + $var_name = "notif_" . $module . "_" . $operation . "_" . $service; - if ($subscribed==='Y') { + if ($subscribed === 'Y') { $defaults[$var_name] = 'on'; } } @@ -243,7 +247,8 @@ class Edit_User extends \NDB_Form // Keep old permissions if the editor is not allowed to edit them, // unless editor is superuser foreach ($current_permissionids as $perm) { - if (!in_array($perm, $newPermissions) + if ( + !in_array($perm, $newPermissions) && !in_array($perm, $editorPermissions) && !$editor->hasPermission('superuser') ) { @@ -423,7 +428,8 @@ class Edit_User extends \NDB_Form ); // START EXAMINER UPDATE - if (!empty($ex_radiologist) + if ( + !empty($ex_radiologist) && !empty($ex_pending) && !empty($ex_curr_sites) && count($examinerID) === 0 @@ -445,7 +451,8 @@ class Edit_User extends \NDB_Form WHERE userID=:uid", ['uid' => $uid] ); - } elseif (count($examinerID) > 0 + } elseif ( + count($examinerID) > 0 && ((!empty($ex_radiologist) && !empty($ex_pending) && !empty($ex_curr_sites)) @@ -484,7 +491,6 @@ class Edit_User extends \NDB_Form } if (!empty($ex_curr_sites)) { foreach ($ex_curr_sites as $v) { - //Check if examiner already in db for site $result = $DB->pselectRow( "SELECT epr.centerID @@ -545,7 +551,6 @@ class Edit_User extends \NDB_Form // Now set the password. Note that this field is named incorrectly // and represents a plaintext password, not a hash. if (isset($values['Password_hash'])) { - $user->updatePassword( new \Password( htmlspecialchars_decode($values['Password_hash']) @@ -654,7 +659,7 @@ class Edit_User extends \NDB_Form * * @return ResponseInterface The outgoing PSR15 response */ - public function handle(ServerRequestInterface $request) : ResponseInterface + public function handle(ServerRequestInterface $request): ResponseInterface { $matches = []; preg_match('#.*/edit_user/(.*)#', $request->getUri()->getPath(), $matches); @@ -693,20 +698,19 @@ class Edit_User extends \NDB_Form // it is a new user if ($this->identifier == '') { // user name - $this->addBasicText('UserID', 'User name', ['required' => true]); + $this->addBasicText('UserID', dgettext("user_accounts", "User name"), ['required' => true]); $this->addCheckbox( 'NA_UserID', - 'Make user name match email address', + dgettext("user_accounts", "Make user name match email address"), [] ); - } else { // It is an existing user: // display user name and account request date - $this->addScoreColumn('UserID', 'User name'); + $this->addScoreColumn('UserID', dgettext("user_accounts", "User name")); } // Account Request Date - always displayed - $this->addScoreColumn('account_request_date', 'Account Request Date'); + $this->addScoreColumn('account_request_date', dgettext("user_accounts", "Account Request Date")); // password if ($this->isCreatingNewUser()) { @@ -715,9 +719,9 @@ class Edit_User extends \NDB_Form $pwd_attribs = []; } - $this->addPassword('Password_hash', 'Password', $pwd_attribs); - $this->addCheckbox('NA_Password', 'Generate new password', []); - $this->addPassword('__Confirm', 'Confirm Password', $pwd_attribs); + $this->addPassword('Password_hash', dgettext("user_accounts", "Password"), $pwd_attribs); + $this->addCheckbox('NA_Password', dgettext("user_accounts", "Generate new password"), []); + $this->addPassword('__Confirm', dgettext("user_accounts", "Confirm Password"), $pwd_attribs); // The supplied pattern is: // - must have at least one non-whitespace characters @@ -728,7 +732,7 @@ class Edit_User extends \NDB_Form . "should not exceed 120 characters')"; $this->addBasicText( 'First_name', - 'First name', + dgettext("user_accounts", "First name"), [], [ 'oninvalid' => $onInvalidMsg, @@ -746,7 +750,7 @@ class Edit_User extends \NDB_Form . "should not exceed 120 characters')"; $this->addBasicText( 'Last_name', - 'Last name', + dgettext("user_accounts", "Last name"), [], [ 'oninvalid' => $onInvalidMsg, @@ -761,28 +765,28 @@ class Edit_User extends \NDB_Form // if the option is not set or if it's and it's true then display it if ($additional_user_info) { - $this->addBasicText('Degree', 'Degree'); - $this->addBasicText('Position_title', 'Academic Position'); - $this->addBasicText('Institution', 'Institution'); - $this->addBasicText('Department', 'Department'); - $this->addBasicText('Address', 'Street Address'); - $this->addBasicText('City', 'City'); - $this->addBasicText('State', 'State/Province'); - $this->addBasicText('Zip_code', 'Zip/Postal Code'); - $this->addBasicText('Country', 'Country'); - $this->addBasicText('Fax', 'FAX'); + $this->addBasicText('Degree', dgettext("user_accounts", "Degree")); + $this->addBasicText('Position_title', dgettext("user_accounts", "Academic Position")); + $this->addBasicText('Institution', dgettext("user_accounts", "Institution")); + $this->addBasicText('Department', dgettext("user_accounts", "Department")); + $this->addBasicText('Address', dgettext("user_accounts", "Street Address")); + $this->addBasicText('City', dgettext("user_accounts", "City")); + $this->addBasicText('State', dgettext("user_accounts", "State/Province")); + $this->addBasicText('Zip_code', dgettext("user_accounts", "Zip/Postal Code")); + $this->addBasicText('Country', dgettext("user_accounts", "Country")); + $this->addBasicText('Fax', dgettext("user_accounts", "FAX")); } // email address - $this->addBasicText('Email', 'Email address', ['required' => true]); - $this->addCheckbox('SendEmail', 'Send email to user', []); + $this->addBasicText('Email', dgettext("user_accounts", "Email address"), ['required' => true]); + $this->addCheckbox('SendEmail', dgettext("user_accounts", "Send email to user"), []); // Add a confirm email text field only if creating a new user // (to make sure that account creation email goes through) if ($this->isCreatingNewUser()) { $this->addBasicText( '__ConfirmEmail', - 'Confirm Email', + dgettext("user_accounts", "Confirm Email"), [], ['required' => true] ); @@ -811,7 +815,7 @@ class Edit_User extends \NDB_Form $this->addSelect( 'CenterIDs', - 'Sites', + dgettext("loris", "Sites"), $siteOptions, [ 'class' => 'form-control input-sm resizable', @@ -831,7 +835,7 @@ class Edit_User extends \NDB_Form $this->addSelect( 'ProjectIDs', - 'Projects', + dgettext("loris", "Projects"), $projectOptions, [ 'class' => 'form-control input-sm resizable', @@ -852,7 +856,7 @@ class Edit_User extends \NDB_Form foreach ($aliases as $row) { $groupA[] = $this->createCheckbox( - 'ex_'.$row['CenterID'], + 'ex_' . $row['CenterID'], $row['Alias'], [] ); @@ -885,13 +889,13 @@ class Edit_User extends \NDB_Form $this->addGroup( $groupA, 'examiner_sites', - 'Examiner At:', + dgettext("user_accounts", "Examiner At:"), $this->_GUIDelimiter ); $this->addGroup( $groupB, "examiner_group", - "Examiner Status", + dgettext("user_accounts", "Examiner Status"), $this->_GUIDelimiter ); unset($groupA); @@ -904,19 +908,19 @@ class Edit_User extends \NDB_Form if (!$this->_isEditingOwnAccount()) { $this->addSelect( "Pending_approval", - "Pending approval", + dgettext("user_accounts", "Pending approval"), [ - 'Y' => 'Yes', - 'N' => 'No', + 'Y' => dgettext("loris", "Yes"), + 'N' => dgettext("loris", "No"), ] ); $this->addSelect( 'Active', - 'Active', + dgettext("loris", "Active"), [ - 'Y' => 'Yes', - 'N' => 'No' + 'Y' => dgettext("loris", "Yes"), + 'N' => dgettext("loris", "No") ] ); @@ -930,14 +934,14 @@ class Edit_User extends \NDB_Form $this->addBasicDate( 'active_from', - 'Active from', + dgettext("user_accounts", "Active from"), $dateOptions, $dateAttributes ); $this->addBasicDate( 'active_to', - 'Active to', + dgettext("user_accounts", "Active to"), $dateOptions, $dateAttributes ); @@ -969,7 +973,7 @@ class Edit_User extends \NDB_Form . "

" - .ucwords($row['type']) + . ucwords($row['type']) . '

' . "
" ); @@ -983,7 +987,7 @@ class Edit_User extends \NDB_Form $attribs['disabled'] = true; } $group[] = $this->createCheckbox( - 'permID['.$row['permID'].']', + 'permID[' . $row['permID'] . ']', htmlspecialchars( $row['label'], ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML5, @@ -994,7 +998,7 @@ class Edit_User extends \NDB_Form $attribs ); } - $this->addGroup($group, 'PermID_Group', 'Permissions', ""); + $this->addGroup($group, 'PermID_Group', dgettext("user_accounts", "Permissions"), ""); unset($group); //getting users name and emails to create checkboxes @@ -1022,7 +1026,7 @@ class Edit_User extends \NDB_Form $attribs = $this->_isEditingOwnAccount() ? ['disabled' => true] : null; foreach ($results as $row) { $group[] = $this->createCheckbox( - 'supervisorEmail[' . $row['email'] .']', + 'supervisorEmail[' . $row['email'] . ']', htmlspecialchars( $row['Real_Name'], ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML5, @@ -1034,7 +1038,7 @@ class Edit_User extends \NDB_Form ); } - $this->addGroup($group, 'Supervisors_Group', 'Supervisors', ""); + $this->addGroup($group, 'Supervisors_Group', dgettext("user_accounts", "Supervisors"), ""); unset($group); if (!$this->isCreatingNewUser()) { @@ -1099,14 +1103,19 @@ class Edit_User extends \NDB_Form // Clicked on "UID == email" and specified a UID if (!empty($values['UserID']) && $values['NA_UserID'] == 'on') { $errors['UserID_Group'] - = 'You cannot enter a user name ' - . 'if you want it to match the email address'; + = dgettext( + "user_accounts", + "You cannot enter a user name if you want it to match the email address" + ); } elseif (empty($values['UserID']) && $values['NA_UserID'] != 'on') { // Not clicked on "UID == email" and not specified a UID $errors['UserID_Group'] - = 'You must enter a user name ' - . 'or choose to make it match the email address'; - } elseif (!empty($values['UserID']) + = dgettext( + "user_accounts", + "You must enter a user name or choose to make it match the email address" + ); + } elseif ( + !empty($values['UserID']) || ($values['NA_UserID'] == 'on' && $values['Email']) ) { // Either specified a UID or clicked on "UID = email" @@ -1123,12 +1132,12 @@ class Edit_User extends \NDB_Form ); if ($result > 0) { - $errors['UserID_Group'] = 'The user name already exists'; + $errors['UserID_Group'] = dgettext("user_accounts", "The user name already exists"); } if (strlen($effectiveUID) > 255) { $errors['UserID_Group'] - = 'The user name must not exceed 255 characters'; + = dgettext("user_accounts", "The user name must not exceed 255 characters"); } // Check that user name does not contain a whitespace character if (preg_match('/\s/', $effectiveUID)) { @@ -1136,11 +1145,17 @@ class Edit_User extends \NDB_Form // can contain spaces if ($values['NA_UserID'] == 'on') { $errors['UserID_Group'] - = 'You cannot have the user name match an email address' - . ' that contains a whitespace character'; + = dgettext( + "user_accounts", + "You cannot have the user name match an email address" + . " that contains a whitespace character" + ); } else { $errors['UserID_Group'] - = 'Whitespace characters are not allowed in user names'; + = dgettext( + "user_accounts", + "Whitespace characters are not allowed in user names" + ); } } } @@ -1154,7 +1169,8 @@ class Edit_User extends \NDB_Form // Do not show this error if the password is an empty string: in this // case, that means the email is empty also. It's more appropriate to // display only the error 'You must enter an email'. - if ($values['Email'] === $values['Password_hash'] + if ( + $values['Email'] === $values['Password_hash'] && $values['Password_hash'] !== '' ) { $errors['Password'] = self::PASSWORD_ERROR_IS_EMAIL; @@ -1165,7 +1181,8 @@ class Edit_User extends \NDB_Form // case 2 - New user and Make user name match email address checked // already handled in email/password check // case 3 - Edit user - if ((isset($values['UserID']) && !isset($values['NA_UserID']) + if ( + (isset($values['UserID']) && !isset($values['NA_UserID']) && $values['UserID'] === $values['Password_hash']) || (!empty($this->identifier) && $this->identifier === $values['Password_hash']) @@ -1183,12 +1200,13 @@ class Edit_User extends \NDB_Form // case of new user the password column will be null // so either password should be set or // password should be generated - if (is_null($pass) + if ( + is_null($pass) && empty($values['Password_hash']) && $values['NA_Password'] != 'on' ) { $errors['Password'] - = 'Please specify password or click Generate new password'; + = dgettext("user_accounts", "Please specify password or click Generate new password"); } } // Ensure that the password and confirm password fields match. @@ -1198,7 +1216,8 @@ class Edit_User extends \NDB_Form } // if password is user-defined, and user wants to change password - if (empty($values['NA_Password']) + if ( + empty($values['NA_Password']) && (!empty($values['Password_hash']) || !empty($values['__Confirm'])) ) { try { @@ -1218,7 +1237,8 @@ class Edit_User extends \NDB_Form } // if password is generated then the email user button should be clicked - if (isset($values['NA_Password']) + if ( + isset($values['NA_Password']) && $values['NA_Password'] == "on" && $values['SendEmail'] != "on" ) { @@ -1227,7 +1247,8 @@ class Edit_User extends \NDB_Form . 'please notify the user by checking Send email to user box'; } - if (isset($values['NA_Password']) + if ( + isset($values['NA_Password']) && $values['NA_Password'] == 'on' && $plaintext != '' ) { @@ -1235,11 +1256,12 @@ class Edit_User extends \NDB_Form . 'if you want the system to generate one for you'; } - if (is_null($this->identifier) + if ( + is_null($this->identifier) && (!isset($values['NA_Password']) || $values['NA_Password'] != 'on') && empty($plaintext) ) { - $errors['Password'] = 'Password is required'; + $errors['Password'] = dgettext("user_accounts", "Password is required"); } //====================================== @@ -1253,13 +1275,12 @@ class Edit_User extends \NDB_Form $errors['Email'] = $emailError; } elseif ($this->isCreatingNewUser()) { if ($values['Email'] != $values['__ConfirmEmail']) { - $errors['__ConfirmEmail'] = 'Email and confirmed email ' - . ' do not match'; + $errors['__ConfirmEmail'] = dgettext("user_accounts", "Email and confirmed email do not match"); } } } else { // No email entered: error - $errors['Email'] = 'You must enter an email address'; + $errors['Email'] = dgettext("user_accounts", "You must enter an email address"); } //====================================== @@ -1267,8 +1288,7 @@ class Edit_User extends \NDB_Form //====================================== // Ensure that at least one site is selected if (empty($values['CenterIDs'])) { - $errors['sites_group'] = "You must select at least one " . - "site/affiliation"; + $errors['sites_group'] = dgettext("user_accounts", "You must select at least one site/affiliation"); } //====================================== @@ -1276,8 +1296,7 @@ class Edit_User extends \NDB_Form //====================================== // Ensure that at least one site is selected if (empty($values['ProjectIDs'])) { - $errors['projects_group'] = "You must select at least one " . - "project/affiliation"; + $errors['projects_group'] = dgettext("user_accounts", "You must select at least one project/affiliation"); } //====================================== @@ -1289,25 +1308,32 @@ class Edit_User extends \NDB_Form if (preg_match("/^ex_[0-9]+$/", $k)) { $matched = true; if ($values['examiner_radiologist'] == '') { - $errors['examiner_group'] = "Please specify if examiner " . - "is a radiologist"; - + $errors['examiner_group'] = dgettext( + "user_accounts", + "Please specify if examiner is a radiologist" + ); } - if ($values['examiner_radiologist'] !== '' + if ( + $values['examiner_radiologist'] !== '' && $values['examiner_pending'] == '' ) { - $errors['examiner_group'] = "Please set pending " . - "approval Yes or No"; + $errors['examiner_group'] = dgettext( + "user_accounts", + "Please set pending approval Yes or No" + ); } } } - if (!$matched + if ( + !$matched && ($values['examiner_radiologist'] !== '' || $values['examiner_pending'] ?? '' !== '') ) { - $errors['examiner_sites'] = "Please select at least one examiner - site or clear the 'Examiner status' fields below (i.e. - 'Radiologist' and 'Pending Approval')."; + $errors['examiner_sites'] = dgettext( + "user_accounts", + "Please select at least one examiner site or clear the " + . "'Examiner status' fields below (i.e. 'Radiologist' and 'Pending Approval')." + ); } } @@ -1319,12 +1345,15 @@ class Edit_User extends \NDB_Form // should be less or equal to the time to it will be active. //====================================== - if (($values['active_to'] != null) + if ( + ($values['active_to'] != null) && ($values['active_from'] > $values['active_to']) ) { $errors['active_timeWindows'] - = 'Please notice that the "Active from" - date should be lesser or equal to the "Active to" date.'; + = dgettext( + "user_accounts", + "Please notice that the \"Active from\" date should be lesser or equal to the \"Active to\" date." + ); } return $errors; } @@ -1344,7 +1373,7 @@ class Edit_User extends \NDB_Form // Although some of these characters are legal in emails, due to the // current HTML escaping method, it is better to reject email // addresses containing them - return 'Email address can not contain any the following '. + return 'Email address can not contain any the following ' . 'characters: <, >, & and "'; } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) { // If email not syntactically valid diff --git a/modules/user_accounts/php/user_accounts.class.inc b/modules/user_accounts/php/user_accounts.class.inc index da1402dec4f..9d5221233da 100644 --- a/modules/user_accounts/php/user_accounts.class.inc +++ b/modules/user_accounts/php/user_accounts.class.inc @@ -1,4 +1,6 @@ -hasAnyPermission(self::PERMISSIONS); } @@ -51,7 +54,7 @@ class User_Accounts extends \DataFrameworkMenu * * @return ?array of permissions or null */ - public function allSitePermissionNames() : ?array + public function allSitePermissionNames(): ?array { return ['user_accounts_multisite']; } @@ -62,7 +65,7 @@ class User_Accounts extends \DataFrameworkMenu * * @return bool true */ - public function useProjectFilter() : bool + public function useProjectFilter(): bool { return true; } @@ -72,11 +75,11 @@ class User_Accounts extends \DataFrameworkMenu * * @return array */ - protected function getFieldOptions() : array + protected function getFieldOptions(): array { $yesNoOptions = [ - 'Y' => 'Yes', - 'N' => 'No', + 'Y' => dgettext("loris", "Yes"), + 'N' => dgettext("loris", "No"), ]; return [ @@ -92,7 +95,7 @@ class User_Accounts extends \DataFrameworkMenu * * @return \Loris\Data\Provisioner */ - public function getBaseDataProvisioner() : \LORIS\Data\Provisioner + public function getBaseDataProvisioner(): \LORIS\Data\Provisioner { return new UserAccountRowProvisioner($this->loris); } @@ -113,4 +116,3 @@ class User_Accounts extends \DataFrameworkMenu ); } } - diff --git a/modules/user_accounts/templates/form_edit_user.tpl b/modules/user_accounts/templates/form_edit_user.tpl index 14464cbcd05..ef239ce963b 100644 --- a/modules/user_accounts/templates/form_edit_user.tpl +++ b/modules/user_accounts/templates/form_edit_user.tpl @@ -505,7 +505,7 @@
{if $can_reject} - +Confirm
From 550a11ee48308056eebe16e71feda87bc2661ba8 Mon Sep 17 00:00:00 2001 From: Saket Hatwar Date: Tue, 30 Sep 2025 12:35:23 -0400 Subject: [PATCH 09/17] lint --- modules/user_accounts/php/edit_user.class.inc | 4 +--- modules/user_accounts/php/user_accounts.class.inc | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/modules/user_accounts/php/edit_user.class.inc b/modules/user_accounts/php/edit_user.class.inc index 226be793baa..906100e0588 100644 --- a/modules/user_accounts/php/edit_user.class.inc +++ b/modules/user_accounts/php/edit_user.class.inc @@ -1,6 +1,4 @@ - Date: Tue, 30 Sep 2025 12:57:32 -0400 Subject: [PATCH 10/17] lint2 --- modules/user_accounts/php/edit_user.class.inc | 42 +++++++------------ .../templates/form_edit_user.tpl | 1 - 2 files changed, 14 insertions(+), 29 deletions(-) diff --git a/modules/user_accounts/php/edit_user.class.inc b/modules/user_accounts/php/edit_user.class.inc index 906100e0588..cbd66263465 100644 --- a/modules/user_accounts/php/edit_user.class.inc +++ b/modules/user_accounts/php/edit_user.class.inc @@ -245,8 +245,7 @@ class Edit_User extends \NDB_Form // Keep old permissions if the editor is not allowed to edit them, // unless editor is superuser foreach ($current_permissionids as $perm) { - if ( - !in_array($perm, $newPermissions) + if (!in_array($perm, $newPermissions) && !in_array($perm, $editorPermissions) && !$editor->hasPermission('superuser') ) { @@ -426,8 +425,7 @@ class Edit_User extends \NDB_Form ); // START EXAMINER UPDATE - if ( - !empty($ex_radiologist) + if (!empty($ex_radiologist) && !empty($ex_pending) && !empty($ex_curr_sites) && count($examinerID) === 0 @@ -449,8 +447,7 @@ class Edit_User extends \NDB_Form WHERE userID=:uid", ['uid' => $uid] ); - } elseif ( - count($examinerID) > 0 + } elseif (count($examinerID) > 0 && ((!empty($ex_radiologist) && !empty($ex_pending) && !empty($ex_curr_sites)) @@ -1112,8 +1109,7 @@ class Edit_User extends \NDB_Form "user_accounts", "You must enter a user name or choose to make it match the email address" ); - } elseif ( - !empty($values['UserID']) + } elseif (!empty($values['UserID']) || ($values['NA_UserID'] == 'on' && $values['Email']) ) { // Either specified a UID or clicked on "UID = email" @@ -1167,8 +1163,7 @@ class Edit_User extends \NDB_Form // Do not show this error if the password is an empty string: in this // case, that means the email is empty also. It's more appropriate to // display only the error 'You must enter an email'. - if ( - $values['Email'] === $values['Password_hash'] + if ($values['Email'] === $values['Password_hash'] && $values['Password_hash'] !== '' ) { $errors['Password'] = self::PASSWORD_ERROR_IS_EMAIL; @@ -1179,8 +1174,7 @@ class Edit_User extends \NDB_Form // case 2 - New user and Make user name match email address checked // already handled in email/password check // case 3 - Edit user - if ( - (isset($values['UserID']) && !isset($values['NA_UserID']) + if ((isset($values['UserID']) && !isset($values['NA_UserID']) && $values['UserID'] === $values['Password_hash']) || (!empty($this->identifier) && $this->identifier === $values['Password_hash']) @@ -1198,8 +1192,7 @@ class Edit_User extends \NDB_Form // case of new user the password column will be null // so either password should be set or // password should be generated - if ( - is_null($pass) + if (is_null($pass) && empty($values['Password_hash']) && $values['NA_Password'] != 'on' ) { @@ -1214,8 +1207,7 @@ class Edit_User extends \NDB_Form } // if password is user-defined, and user wants to change password - if ( - empty($values['NA_Password']) + if (empty($values['NA_Password']) && (!empty($values['Password_hash']) || !empty($values['__Confirm'])) ) { try { @@ -1235,8 +1227,7 @@ class Edit_User extends \NDB_Form } // if password is generated then the email user button should be clicked - if ( - isset($values['NA_Password']) + if (isset($values['NA_Password']) && $values['NA_Password'] == "on" && $values['SendEmail'] != "on" ) { @@ -1245,8 +1236,7 @@ class Edit_User extends \NDB_Form . 'please notify the user by checking Send email to user box'; } - if ( - isset($values['NA_Password']) + if (isset($values['NA_Password']) && $values['NA_Password'] == 'on' && $plaintext != '' ) { @@ -1254,8 +1244,7 @@ class Edit_User extends \NDB_Form . 'if you want the system to generate one for you'; } - if ( - is_null($this->identifier) + if (is_null($this->identifier) && (!isset($values['NA_Password']) || $values['NA_Password'] != 'on') && empty($plaintext) ) { @@ -1311,8 +1300,7 @@ class Edit_User extends \NDB_Form "Please specify if examiner is a radiologist" ); } - if ( - $values['examiner_radiologist'] !== '' + if ($values['examiner_radiologist'] !== '' && $values['examiner_pending'] == '' ) { $errors['examiner_group'] = dgettext( @@ -1322,8 +1310,7 @@ class Edit_User extends \NDB_Form } } } - if ( - !$matched + if (!$matched && ($values['examiner_radiologist'] !== '' || $values['examiner_pending'] ?? '' !== '') ) { @@ -1343,8 +1330,7 @@ class Edit_User extends \NDB_Form // should be less or equal to the time to it will be active. //====================================== - if ( - ($values['active_to'] != null) + if (($values['active_to'] != null) && ($values['active_from'] > $values['active_to']) ) { $errors['active_timeWindows'] diff --git a/modules/user_accounts/templates/form_edit_user.tpl b/modules/user_accounts/templates/form_edit_user.tpl index ef239ce963b..d0abbc36179 100644 --- a/modules/user_accounts/templates/form_edit_user.tpl +++ b/modules/user_accounts/templates/form_edit_user.tpl @@ -505,7 +505,6 @@
{if $can_reject} -Confirm
From c278dc5335ba030294b2397b8f57e55f66bf65c0 Mon Sep 17 00:00:00 2001 From: Saket Hatwar Date: Mon, 6 Oct 2025 05:33:24 -0400 Subject: [PATCH 11/17] change --- locale/hi/LC_MESSAGES/loris.po | 29 ++- locale/loris.pot | 27 ++- .../user_accounts/jsx/userAccountsIndex.js | 4 +- .../locale/hi/LC_MESSAGES/user_accounts.po | 12 +- .../user_accounts/locale/user_accounts.pot | 12 +- modules/user_accounts/php/edit_user.class.inc | 206 +++++++++++++----- .../templates/form_edit_user.tpl | 7 +- php/libraries/Password.class.inc | 19 +- 8 files changed, 225 insertions(+), 91 deletions(-) diff --git a/locale/hi/LC_MESSAGES/loris.po b/locale/hi/LC_MESSAGES/loris.po index 875c48e9af8..7b329926cea 100644 --- a/locale/hi/LC_MESSAGES/loris.po +++ b/locale/hi/LC_MESSAGES/loris.po @@ -117,6 +117,18 @@ msgstr "हाँ" msgid "No" msgstr "नहीं" +msgid "Save" +msgstr "सहेजें" + +msgid "Reset" +msgstr "रीसेट करें" + +msgid "Back" +msgstr "वापस" + +msgid "None" +msgstr "कोई नहीं" + # Common candidate terms msgid "PSCID" msgstr "पीएससीआईडी" @@ -140,7 +152,8 @@ msgid "Projects" msgstr "प्रोजेक्ट्स" msgid "Cohort" -msgstr "समूह" +msgid_plural "Cohorts" +msgstr[0] "समूह" msgid "Date of registration" msgstr "पंजीकरण की तिथि" @@ -176,5 +189,15 @@ msgstr "{{totalCount}} में से {{pageCount}} पंक्तिया msgid "Maximum rows per page:" msgstr "प्रति पृष्ठ अधिकतम पंक्तियाँ:" -msgid "Download Table as CSV" -msgstr "तालिका को CSV के रूप में डाउनलोड करें" +msgid "Download Data as CSV" +msgstr "डेटा को CSV के रूप में डाउनलोड करें" + +#: php/libraries/Password.class.inc +msgid "The password is too short" +msgstr "पासवर्ड बहुत छोटा है" + +msgid "The password is not complex enough." +msgstr "पासवर्ड पर्याप्त जटिल नहीं है।" + +msgid "This password is known to be exposed in online data breaches." +msgstr "यह पासवर्ड ऑनलाइन डेटा उल्लंघनों में उजागर होने के लिए जाना जाता है।" diff --git a/locale/loris.pot b/locale/loris.pot index 106cf50f148..cbfe71696a7 100644 --- a/locale/loris.pot +++ b/locale/loris.pot @@ -116,6 +116,18 @@ msgstr "" msgid "No" msgstr "" +msgid "Save" +msgstr "" + +msgid "Reset" +msgstr "" + +msgid "Back" +msgstr "" + +msgid "None" +msgstr "" + # Common candidate terms msgid "PSCID" msgstr "" @@ -139,7 +151,8 @@ msgid "Projects" msgstr "" msgid "Cohort" -msgstr "" +msgid_plural "Cohorts" +msgstr[0] "" msgid "Date of registration" msgstr "" @@ -175,5 +188,15 @@ msgstr "" msgid "Maximum rows per page:" msgstr "" -msgid "Download Table as CSV" +msgid "Download Data as CSV" +msgstr "" + +#: php/libraries/Password.class.inc +msgid "The password is too short" +msgstr "" + +msgid "The password is not complex enough." +msgstr "" + +msgid "This password is known to be exposed in online data breaches." msgstr "" diff --git a/modules/user_accounts/jsx/userAccountsIndex.js b/modules/user_accounts/jsx/userAccountsIndex.js index d8e270394a1..cbc0d3730ec 100644 --- a/modules/user_accounts/jsx/userAccountsIndex.js +++ b/modules/user_accounts/jsx/userAccountsIndex.js @@ -114,7 +114,7 @@ class UserAccountsIndex extends Component { url = loris.BaseURL + '/user_accounts/edit_user/' + row.Username; result = {cell}; break; - case t('Active', {ns: 'user_accounts'}): + case t('Active', {ns: 'loris'}): if (row.Active === 'Y') { result = {t('Yes', {ns: 'loris'})}; } else if (row.Active === 'N') { @@ -210,7 +210,7 @@ class UserAccountsIndex extends Component { }, }, { - label: t('Active', {ns: 'user_accounts'}), + label: t('Active', {ns: 'loris'}), show: true, filter: { name: 'active', diff --git a/modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po b/modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po index efcfb249723..560d8584c31 100644 --- a/modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po +++ b/modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po @@ -44,6 +44,9 @@ msgstr "ईमेल" msgid "Pending Approval" msgstr "स्वीकृति लंबित" +msgid "Radiologist" +msgstr "रेडियोलॉजिस्ट" + msgid "Account Request Date" msgstr "खाता अनुरोध तिथि" @@ -83,15 +86,6 @@ msgstr "नया पासवर्ड बनाते समय, कृपय msgid "Add/Edit User" msgstr "उपयोगकर्ता जोड़ें/संपादित करें" -msgid "Save" -msgstr "सहेजें" - -msgid "Reset" -msgstr "रीसेट करें" - -msgid "Back" -msgstr "वापस" - msgid "Reject User" msgstr "उपयोगकर्ता को अस्वीकार करें" diff --git a/modules/user_accounts/locale/user_accounts.pot b/modules/user_accounts/locale/user_accounts.pot index 660d0f1e756..f5dde6227b2 100644 --- a/modules/user_accounts/locale/user_accounts.pot +++ b/modules/user_accounts/locale/user_accounts.pot @@ -44,6 +44,9 @@ msgstr "" msgid "Pending Approval" msgstr "" +msgid "Radiologist" +msgstr "" + msgid "Account Request Date" msgstr "" @@ -83,15 +86,6 @@ msgstr "" msgid "Add/Edit User" msgstr "" -msgid "Save" -msgstr "" - -msgid "Reset" -msgstr "" - -msgid "Back" -msgstr "" - msgid "Reject User" msgstr "" diff --git a/modules/user_accounts/php/edit_user.class.inc b/modules/user_accounts/php/edit_user.class.inc index cbd66263465..4f64b4ba601 100644 --- a/modules/user_accounts/php/edit_user.class.inc +++ b/modules/user_accounts/php/edit_user.class.inc @@ -13,7 +13,6 @@ */ namespace LORIS\user_accounts; - use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface; @@ -158,7 +157,7 @@ class Edit_User extends \NDB_Form foreach ($operations as $operation => $services) { unset($services['desc']); foreach ($services as $service => $subscribed) { - $var_name = "notif_" . $module . "_" . $operation . "_" . $service; + $var_name = "notif_".$module."_".$operation."_".$service; if ($subscribed === 'Y') { $defaults[$var_name] = 'on'; @@ -693,7 +692,14 @@ class Edit_User extends \NDB_Form // it is a new user if ($this->identifier == '') { // user name - $this->addBasicText('UserID', dgettext("user_accounts", "User name"), ['required' => true]); + $this->addBasicText( + 'UserID', + dgettext( + "user_accounts", + "User name" + ), + ['required' => true] + ); $this->addCheckbox( 'NA_UserID', dgettext("user_accounts", "Make user name match email address"), @@ -704,8 +710,10 @@ class Edit_User extends \NDB_Form // display user name and account request date $this->addScoreColumn('UserID', dgettext("user_accounts", "User name")); } - // Account Request Date - always displayed - $this->addScoreColumn('account_request_date', dgettext("user_accounts", "Account Request Date")); + $this->addScoreColumn( + 'account_request_date', + dgettext("user_accounts", "Account Request Date") + ); // password if ($this->isCreatingNewUser()) { @@ -714,9 +722,21 @@ class Edit_User extends \NDB_Form $pwd_attribs = []; } - $this->addPassword('Password_hash', dgettext("user_accounts", "Password"), $pwd_attribs); - $this->addCheckbox('NA_Password', dgettext("user_accounts", "Generate new password"), []); - $this->addPassword('__Confirm', dgettext("user_accounts", "Confirm Password"), $pwd_attribs); + $this->addPassword( + 'Password_hash', + dgettext("user_accounts", "Password"), + $pwd_attribs + ); + $this->addCheckbox( + 'NA_Password', + dgettext("user_accounts", "Generate new password"), + [] + ); + $this->addPassword( + '__Confirm', + dgettext("user_accounts", "Confirm Password"), + $pwd_attribs + ); // The supplied pattern is: // - must have at least one non-whitespace characters @@ -760,21 +780,59 @@ class Edit_User extends \NDB_Form // if the option is not set or if it's and it's true then display it if ($additional_user_info) { - $this->addBasicText('Degree', dgettext("user_accounts", "Degree")); - $this->addBasicText('Position_title', dgettext("user_accounts", "Academic Position")); - $this->addBasicText('Institution', dgettext("user_accounts", "Institution")); - $this->addBasicText('Department', dgettext("user_accounts", "Department")); - $this->addBasicText('Address', dgettext("user_accounts", "Street Address")); - $this->addBasicText('City', dgettext("user_accounts", "City")); - $this->addBasicText('State', dgettext("user_accounts", "State/Province")); - $this->addBasicText('Zip_code', dgettext("user_accounts", "Zip/Postal Code")); - $this->addBasicText('Country', dgettext("user_accounts", "Country")); - $this->addBasicText('Fax', dgettext("user_accounts", "FAX")); + $this->addBasicText( + 'Degree', + dgettext("user_accounts", "Degree") + ); + $this->addBasicText( + 'Position_title', + dgettext("user_accounts", "Academic Position") + ); + $this->addBasicText( + 'Institution', + dgettext("user_accounts", "Institution") + ); + $this->addBasicText( + 'Department', + dgettext("user_accounts", "Department") + ); + $this->addBasicText( + 'Address', + dgettext("user_accounts", "Street Address") + ); + $this->addBasicText( + 'City', + dgettext("user_accounts", "City") + ); + $this->addBasicText( + 'State', + dgettext("user_accounts", "State/Province") + ); + $this->addBasicText( + 'Zip_code', + dgettext("user_accounts", "Zip/Postal Code") + ); + $this->addBasicText( + 'Country', + dgettext("user_accounts", "Country") + ); + $this->addBasicText( + 'Fax', + dgettext("user_accounts", "FAX") + ); } // email address - $this->addBasicText('Email', dgettext("user_accounts", "Email address"), ['required' => true]); - $this->addCheckbox('SendEmail', dgettext("user_accounts", "Send email to user"), []); + $this->addBasicText( + 'Email', + dgettext("user_accounts", "Email address"), + ['required' => true] + ); + $this->addCheckbox( + 'SendEmail', + dgettext("user_accounts", "Send email to user"), + [] + ); // Add a confirm email text field only if creating a new user // (to make sure that account creation email goes through) @@ -857,28 +915,28 @@ class Edit_User extends \NDB_Form ); } $groupB[] = $this->createLabel( - "Radiologist: " + dgettext("user_accounts", "Radiologist") . ": " ); $groupB[] = $this->createSelect( "examiner_radiologist", - "Radiologist: ", + dgettext("user_accounts", "Radiologist") . ": ", [ '' => "", - 'Y' => 'Yes', - 'N' => 'No', + 'Y' => dgettext("loris", "Yes"), + 'N' => dgettext("loris", "No"), ] ); $groupB[] = $this->createLabel( - "Pending Approval:" + dgettext("user_accounts", "Pending Approval") . ":" ); $groupB[] = $this->createSelect( "examiner_pending", - "Pending Approval: ", + dgettext("user_accounts", "Pending Approval") . ": ", [ - '' => "", - 'Y' => 'Yes', - 'N' => 'No', + '' => dgettext("loris", "None"), + 'Y' => dgettext("loris", "Yes"), + 'N' => dgettext("loris", "No"), ] ); $this->addGroup( @@ -993,7 +1051,12 @@ class Edit_User extends \NDB_Form $attribs ); } - $this->addGroup($group, 'PermID_Group', dgettext("user_accounts", "Permissions"), ""); + $this->addGroup( + $group, + 'PermID_Group', + dgettext("user_accounts", "Permissions"), + "" + ); unset($group); //getting users name and emails to create checkboxes @@ -1033,7 +1096,12 @@ class Edit_User extends \NDB_Form ); } - $this->addGroup($group, 'Supervisors_Group', dgettext("user_accounts", "Supervisors"), ""); + $this->addGroup( + $group, + 'Supervisors_Group', + dgettext("user_accounts", "Supervisors"), + "" + ); unset($group); if (!$this->isCreatingNewUser()) { @@ -1100,14 +1168,16 @@ class Edit_User extends \NDB_Form $errors['UserID_Group'] = dgettext( "user_accounts", - "You cannot enter a user name if you want it to match the email address" + 'You cannot enter a user name ' + . 'if you want it to match the email address' ); } elseif (empty($values['UserID']) && $values['NA_UserID'] != 'on') { // Not clicked on "UID == email" and not specified a UID $errors['UserID_Group'] = dgettext( "user_accounts", - "You must enter a user name or choose to make it match the email address" + 'You must enter a user name ' + . 'or choose to make it match the email address' ); } elseif (!empty($values['UserID']) || ($values['NA_UserID'] == 'on' && $values['Email']) @@ -1126,30 +1196,33 @@ class Edit_User extends \NDB_Form ); if ($result > 0) { - $errors['UserID_Group'] = dgettext("user_accounts", "The user name already exists"); + $errors['UserID_Group'] = dgettext( + "user_accounts", + "The user name already exists" + ); } if (strlen($effectiveUID) > 255) { - $errors['UserID_Group'] - = dgettext("user_accounts", "The user name must not exceed 255 characters"); + $errors['UserID_Group'] = dgettext( + "user_accounts", + "The user name must not exceed 255 characters" + ); } // Check that user name does not contain a whitespace character if (preg_match('/\s/', $effectiveUID)) { // Note: email addresses can contain comments which themselves // can contain spaces if ($values['NA_UserID'] == 'on') { - $errors['UserID_Group'] - = dgettext( - "user_accounts", - "You cannot have the user name match an email address" - . " that contains a whitespace character" - ); + $errors['UserID_Group'] = dgettext( + "user_accounts", + "You cannot have the user name match an email address" + . " that contains a whitespace character" + ); } else { - $errors['UserID_Group'] - = dgettext( - "user_accounts", - "Whitespace characters are not allowed in user names" - ); + $errors['UserID_Group'] = dgettext( + "user_accounts", + "Whitespace characters are not allowed in user names" + ); } } } @@ -1196,8 +1269,10 @@ class Edit_User extends \NDB_Form && empty($values['Password_hash']) && $values['NA_Password'] != 'on' ) { - $errors['Password'] - = dgettext("user_accounts", "Please specify password or click Generate new password"); + $errors['Password'] = dgettext( + "user_accounts", + "Please specify password or click Generate new password" + ); } } // Ensure that the password and confirm password fields match. @@ -1262,12 +1337,18 @@ class Edit_User extends \NDB_Form $errors['Email'] = $emailError; } elseif ($this->isCreatingNewUser()) { if ($values['Email'] != $values['__ConfirmEmail']) { - $errors['__ConfirmEmail'] = dgettext("user_accounts", "Email and confirmed email do not match"); + $errors['__ConfirmEmail'] = dgettext( + "user_accounts", + "Email and confirmed email do not match" + ); } } } else { // No email entered: error - $errors['Email'] = dgettext("user_accounts", "You must enter an email address"); + $errors['Email'] = dgettext( + "user_accounts", + "You must enter an email address" + ); } //====================================== @@ -1275,7 +1356,10 @@ class Edit_User extends \NDB_Form //====================================== // Ensure that at least one site is selected if (empty($values['CenterIDs'])) { - $errors['sites_group'] = dgettext("user_accounts", "You must select at least one site/affiliation"); + $errors['sites_group'] = dgettext( + "user_accounts", + "You must select at least one site/affiliation" + ); } //====================================== @@ -1283,7 +1367,10 @@ class Edit_User extends \NDB_Form //====================================== // Ensure that at least one site is selected if (empty($values['ProjectIDs'])) { - $errors['projects_group'] = dgettext("user_accounts", "You must select at least one project/affiliation"); + $errors['projects_group'] = dgettext( + "user_accounts", + "You must select at least one project/affiliation" + ); } //====================================== @@ -1317,7 +1404,8 @@ class Edit_User extends \NDB_Form $errors['examiner_sites'] = dgettext( "user_accounts", "Please select at least one examiner site or clear the " - . "'Examiner status' fields below (i.e. 'Radiologist' and 'Pending Approval')." + . "'Examiner status' fields below " + . "(i.e. 'Radiologist' and 'Pending Approval')." ); } } @@ -1333,11 +1421,11 @@ class Edit_User extends \NDB_Form if (($values['active_to'] != null) && ($values['active_from'] > $values['active_to']) ) { - $errors['active_timeWindows'] - = dgettext( - "user_accounts", - "Please notice that the \"Active from\" date should be lesser or equal to the \"Active to\" date." - ); + $errors['active_timeWindows'] = dgettext( + "user_accounts", + "Please notice that the \"Active from\" date should be" + . " lesser or equal to the \"Active to\" date." + ); } return $errors; } diff --git a/modules/user_accounts/templates/form_edit_user.tpl b/modules/user_accounts/templates/form_edit_user.tpl index d0abbc36179..c5faa588f1a 100644 --- a/modules/user_accounts/templates/form_edit_user.tpl +++ b/modules/user_accounts/templates/form_edit_user.tpl @@ -496,15 +496,16 @@
- +
- +
- +
{if $can_reject} +
diff --git a/php/libraries/Password.class.inc b/php/libraries/Password.class.inc index 31f4997234a..755df264d58 100644 --- a/php/libraries/Password.class.inc +++ b/php/libraries/Password.class.inc @@ -105,11 +105,19 @@ class Password // Check length and complexity separately in order to return a precise // error message upon failure. if (!$this->_hasSufficientLength($value)) { - throw new \InvalidArgumentException('The password is too short'); + throw new \InvalidArgumentException( + dgettext( + 'loris', + 'The password is too short' + ) + ); } if (!$this->_hasSufficientComplexity($value)) { throw new \InvalidArgumentException( - 'The password is not complex enough.' + dgettext( + 'loris', + 'The password is not complex enough.' + ) ); } if (\NDB_Factory::singleton()->config()->settingEnabled( @@ -118,8 +126,11 @@ class Password ) { if ($this->_pwned($value)) { throw new \InvalidArgumentException( - 'This password is known to be exposed in online data ' - . 'breaches.' + dgettext( + 'loris', + 'This password is known to be exposed in online data' + . 'breaches.' + ) ); } } From 618200c9936f82ec0eb8e00c3323e4efa439e148 Mon Sep 17 00:00:00 2001 From: Saket Hatwar Date: Mon, 27 Oct 2025 08:17:33 -0400 Subject: [PATCH 12/17] fixes2 --- locale/hi/LC_MESSAGES/loris.po | 80 +++++++++++++++++++ locale/loris.pot | 80 +++++++++++++++++++ .../user_accounts/jsx/userAccountsIndex.js | 16 ++-- .../locale/hi/LC_MESSAGES/user_accounts.po | 45 ----------- .../user_accounts/locale/user_accounts.pot | 46 ----------- modules/user_accounts/php/edit_user.class.inc | 43 ++++++---- .../templates/form_edit_user.tpl | 14 ++-- php/libraries/Password.class.inc | 2 +- 8 files changed, 204 insertions(+), 122 deletions(-) diff --git a/locale/hi/LC_MESSAGES/loris.po b/locale/hi/LC_MESSAGES/loris.po index 7b329926cea..09097a11dd8 100644 --- a/locale/hi/LC_MESSAGES/loris.po +++ b/locale/hi/LC_MESSAGES/loris.po @@ -117,6 +117,9 @@ msgstr "हाँ" msgid "No" msgstr "नहीं" +msgid "N/A" +msgstr "लागू नहीं" + msgid "Save" msgstr "सहेजें" @@ -129,6 +132,12 @@ msgstr "वापस" msgid "None" msgstr "कोई नहीं" +msgid "Y" +msgstr "हाँ" + +msgid "N" +msgstr "नहीं" + # Common candidate terms msgid "PSCID" msgstr "पीएससीआईडी" @@ -139,6 +148,9 @@ msgstr "डीसीसीआईडी" msgid "Visit Label" msgstr "दौरे का लेबल" +msgid "Email" +msgstr "ईमेल" + msgid "Site" msgstr "साइट" @@ -201,3 +213,71 @@ msgstr "पासवर्ड पर्याप्त जटिल नहीं msgid "This password is known to be exposed in online data breaches." msgstr "यह पासवर्ड ऑनलाइन डेटा उल्लंघनों में उजागर होने के लिए जाना जाता है।" + +msgid "Data Supervisors to Email" +msgstr "ईमेल करने के लिए डेटा पर्यवेक्षक" + +msgid "Invalid email address" +msgstr "अमान्य ईमेल पता" + +# Common strings on widgets +msgid "NEW" +msgstr "नया" + +msgid "Updated" +msgstr "अद्यतन किया गया" + +msgid "Uploaded" +msgstr "अपलोड किया गया" + +# User Account related +msgid "Password Rules" +msgstr "पासवर्ड नियम" + +msgid "Username" +msgstr "उपयोगकर्ता नाम" + +msgid "First name" +msgstr "पहला नाम" + +msgid "First name is required and should not exceed 120 characters" +msgstr "पहला नाम आवश्यक है और 120 अक्षरों से अधिक नहीं होना चाहिए।" + +msgid "Last name" +msgstr "अंतिम नाम" + +msgid "Last name is required and should not exceed 120 characters" +msgstr "अंतिम नाम आवश्यक है और 120 अक्षरों से अधिक नहीं होना चाहिए।" + +msgid "Email address" +msgstr "ईमेल पता" + +msgid "New Password" +msgstr "नया पासवर्ड" + +msgid "Password" +msgstr "पासवर्ड" + +msgid "Confirm Password" +msgstr "पासवर्ड की पुष्टि करें" + +msgid "Email address is required" +msgstr "ईमेल पता आवश्यक है" + +msgid "Email address cannot contain any of the following characters: <, >, &, and \"" +msgstr "ईमेल पता निम्नलिखित किसी भी वर्ण को नहीं शामिल कर सकता: <, >, &, और \"" + +msgid "The password must be at least 8 characters long." +msgstr "पासवर्ड कम से कम 8 अक्षरों का होना चाहिए।" + +msgid "The password cannot be your username or email address." +msgstr "पासवर्ड आपका उपयोगकर्ता नाम या ईमेल पता नहीं हो सकता।" + +msgid "Please choose a unique password." +msgstr "कृपया एक अद्वितीय पासवर्ड चुनें।" + +msgid "No special characters are required but your password must be sufficiently complex to be accepted." +msgstr "कोई विशेष अक्षर आवश्यक नहीं हैं, लेकिन पासवर्ड पर्याप्त जटिल होना चाहिए ताकि उसे स्वीकार किया जा सके।" + +msgid "We suggest using a password manager to generate one for you." +msgstr "हम सुझाव देते हैं कि आपके लिए पासवर्ड बनाने हेतु पासवर्ड मैनेजर का उपयोग करें।" \ No newline at end of file diff --git a/locale/loris.pot b/locale/loris.pot index cbfe71696a7..ee90f88e056 100644 --- a/locale/loris.pot +++ b/locale/loris.pot @@ -116,6 +116,9 @@ msgstr "" msgid "No" msgstr "" +msgid "N/A" +msgstr "" + msgid "Save" msgstr "" @@ -128,6 +131,12 @@ msgstr "" msgid "None" msgstr "" +msgid "Y" +msgstr "" + +msgid "N" +msgstr "" + # Common candidate terms msgid "PSCID" msgstr "" @@ -138,6 +147,9 @@ msgstr "" msgid "Visit Label" msgstr "" +msgid "Email" +msgstr "" + msgid "Site" msgstr "" @@ -200,3 +212,71 @@ msgstr "" msgid "This password is known to be exposed in online data breaches." msgstr "" + +msgid "Data Supervisors to Email" +msgstr "" + +msgid "Invalid email address" +msgstr "" + +# Common strings on widgets +msgid "NEW" +msgstr "" + +msgid "Updated" +msgstr "" + +msgid "Uploaded" +msgstr "" + +# User Account related +msgid "Password Rules" +msgstr "" + +msgid "Username" +msgstr "" + +msgid "First name" +msgstr "" + +msgid "First name is required and should not exceed 120 characters" +msgstr "" + +msgid "Last name" +msgstr "" + +msgid "Last name is required and should not exceed 120 characters" +msgstr "" + +msgid "Email address" +msgstr "" + +msgid "New Password" +msgstr "" + +msgid "Password" +msgstr "" + +msgid "Confirm Password" +msgstr "" + +msgid "Email address is required" +msgstr "" + +msgid "Email address cannot contain any of the following characters: <, >, &, and \"" +msgstr "" + +msgid "The password must be at least 8 characters long." +msgstr "" + +msgid "The password cannot be your username or email address." +msgstr "" + +msgid "Please choose a unique password." +msgstr "" + +msgid "No special characters are required but your password must be sufficiently complex to be accepted." +msgstr "" + +msgid "We suggest using a password manager to generate one for you." +msgstr "" diff --git a/modules/user_accounts/jsx/userAccountsIndex.js b/modules/user_accounts/jsx/userAccountsIndex.js index cbc0d3730ec..58bfb9f8441 100644 --- a/modules/user_accounts/jsx/userAccountsIndex.js +++ b/modules/user_accounts/jsx/userAccountsIndex.js @@ -110,21 +110,23 @@ class UserAccountsIndex extends Component { ); } break; - case t('Username', {ns: 'user_accounts'}): + case t('Username', {ns: 'loris'}): url = loris.BaseURL + '/user_accounts/edit_user/' + row.Username; result = {cell}; break; case t('Active', {ns: 'loris'}): - if (row.Active === 'Y') { + const activeKey = t('Active', {ns: 'loris'}); + if (row[activeKey] === 'Y') { result = {t('Yes', {ns: 'loris'})}; - } else if (row.Active === 'N') { + } else if (row[activeKey] === 'N') { result = {t('No', {ns: 'loris'})}; } break; case t('Pending Approval', {ns: 'user_accounts'}): - if (row['Pending Approval'] === 'Y') { + const pendingKey = t('Pending Approval', { ns: 'user_accounts' }); + if (row[pendingKey] === 'Y') { result = {t('Yes', {ns: 'loris'})}; - } else if (row['Pending Approval'] === 'N') { + } else if (row[pendingKey] === 'N') { result = {t('No', {ns: 'loris'})}; } break; @@ -186,7 +188,7 @@ class UserAccountsIndex extends Component { }, }, { - label: t('Username', {ns: 'user_accounts'}), + label: t('Username', {ns: 'loris'}), show: true, filter: { name: 'username', @@ -202,7 +204,7 @@ class UserAccountsIndex extends Component { }, }, { - label: t('Email', {ns: 'user_accounts'}), + label: t('Email', {ns: 'loris'}), show: true, filter: { name: 'email', diff --git a/modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po b/modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po index 560d8584c31..350cadbb573 100644 --- a/modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po +++ b/modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po @@ -24,23 +24,15 @@ msgstr "उपयोगकर्ता खाते" msgid "Edit User" msgstr "उपयोगकर्ता संपादित करें" -# --- Strings not in loris.pot, add below --- - msgid "This user has no site affiliations" msgstr "इस उपयोगकर्ता की कोई साइट संबद्धता नहीं है" msgid "This user has no project affiliations" msgstr "इस उपयोगकर्ता की कोई परियोजना संबद्धता नहीं है" -msgid "Username" -msgstr "उपयोगकर्ता नाम" - msgid "Full Name" msgstr "पूरा नाम" -msgid "Email" -msgstr "ईमेल" - msgid "Pending Approval" msgstr "स्वीकृति लंबित" @@ -56,24 +48,6 @@ msgstr "उपयोगकर्ता जोड़ें" msgid "The form you submitted contains data entry errors" msgstr "आपके द्वारा प्रस्तुत फॉर्म में डेटा प्रविष्टि त्रुटियां हैं" -msgid "Password Rules" -msgstr "पासवर्ड नियम" - -msgid "The password must be at least 8 characters long." -msgstr "पासवर्ड कम से कम 8 अक्षर लंबा होना चाहिए।" - -msgid "The password cannot be your username or email address." -msgstr "पासवर्ड आपका उपयोगकर्ता नाम या ईमेल पता नहीं हो सकता।" - -msgid "No special characters are required but your password must be sufficiently complex to be accepted." -msgstr "कोई विशेष वर्ण आवश्यक नहीं हैं लेकिन आपका पासवर्ड स्वीकार किए जाने के लिए पर्याप्त रूप से जटिल होना चाहिए।" - -msgid "Please choose a unique password." -msgstr "कृपया एक अनूठा पासवर्ड चुनें।" - -msgid "We suggest using a password manager to generate one for you." -msgstr "हम आपके लिए एक उत्पन्न करने के लिए पासवर्ड प्रबंधक का उपयोग करने का सुझाव देते हैं।" - msgid "Notes" msgstr "नोट्स" @@ -89,27 +63,12 @@ msgstr "उपयोगकर्ता जोड़ें/संपादित msgid "Reject User" msgstr "उपयोगकर्ता को अस्वीकार करें" -msgid "User name" -msgstr "उपयोगकर्ता नाम" - msgid "Make user name match email address" msgstr "उपयोगकर्ता नाम को ईमेल पता से मिलाएँ" -msgid "Password" -msgstr "पासवर्ड" - msgid "Generate new password" msgstr "नया पासवर्ड बनाएं" -msgid "Confirm Password" -msgstr "पासवर्ड की पुष्टि करें" - -msgid "First name" -msgstr "पहला नाम" - -msgid "Last name" -msgstr "अंतिम नाम" - msgid "Degree" msgstr "डिग्री" @@ -140,9 +99,6 @@ msgstr "देश" msgid "FAX" msgstr "फैक्स" -msgid "Email address" -msgstr "ईमेल पता" - msgid "Send email to user" msgstr "उपयोगकर्ता को ईमेल भेजें" @@ -217,4 +173,3 @@ msgstr "कृपया कम से कम एक परीक्षक स् msgid "Please notice that the \"Active from\" date should be lesser or equal to the \"Active to\" date." msgstr "कृपया ध्यान दें कि 'सक्रिय शुरू' तिथि, 'सक्रिय समाप्त' तिथि के बराबर या उससे पहले होनी चाहिए।" - diff --git a/modules/user_accounts/locale/user_accounts.pot b/modules/user_accounts/locale/user_accounts.pot index f5dde6227b2..2d8f671deaa 100644 --- a/modules/user_accounts/locale/user_accounts.pot +++ b/modules/user_accounts/locale/user_accounts.pot @@ -24,23 +24,15 @@ msgstr "" msgid "Edit User" msgstr "" -# --- Strings not in loris.pot, add below --- - msgid "This user has no site affiliations" msgstr "" msgid "This user has no project affiliations" msgstr "" -msgid "Username" -msgstr "" - msgid "Full Name" msgstr "" -msgid "Email" -msgstr "" - msgid "Pending Approval" msgstr "" @@ -56,24 +48,6 @@ msgstr "" msgid "The form you submitted contains data entry errors" msgstr "" -msgid "Password Rules" -msgstr "" - -msgid "The password must be at least 8 characters long." -msgstr "" - -msgid "The password cannot be your username or email address." -msgstr "" - -msgid "No special characters are required but your password must be sufficiently complex to be accepted." -msgstr "" - -msgid "Please choose a unique password." -msgstr "" - -msgid "We suggest using a password manager to generate one for you." -msgstr "" - msgid "Notes" msgstr "" @@ -89,27 +63,12 @@ msgstr "" msgid "Reject User" msgstr "" -msgid "User name" -msgstr "" - msgid "Make user name match email address" msgstr "" -msgid "Password" -msgstr "" - msgid "Generate new password" msgstr "" -msgid "Confirm Password" -msgstr "" - -msgid "First name" -msgstr "" - -msgid "Last name" -msgstr "" - msgid "Degree" msgstr "" @@ -140,9 +99,6 @@ msgstr "" msgid "FAX" msgstr "" -msgid "Email address" -msgstr "" - msgid "Send email to user" msgstr "" @@ -217,5 +173,3 @@ msgstr "" msgid "Please notice that the \"Active from\" date should be lesser or equal to the \"Active to\" date." msgstr "" - - diff --git a/modules/user_accounts/php/edit_user.class.inc b/modules/user_accounts/php/edit_user.class.inc index 4f64b4ba601..3daabd326ab 100644 --- a/modules/user_accounts/php/edit_user.class.inc +++ b/modules/user_accounts/php/edit_user.class.inc @@ -695,8 +695,8 @@ class Edit_User extends \NDB_Form $this->addBasicText( 'UserID', dgettext( - "user_accounts", - "User name" + "loris", + "Username" ), ['required' => true] ); @@ -708,7 +708,7 @@ class Edit_User extends \NDB_Form } else { // It is an existing user: // display user name and account request date - $this->addScoreColumn('UserID', dgettext("user_accounts", "User name")); + $this->addScoreColumn('UserID', dgettext("loris", "Username")); } $this->addScoreColumn( 'account_request_date', @@ -724,7 +724,7 @@ class Edit_User extends \NDB_Form $this->addPassword( 'Password_hash', - dgettext("user_accounts", "Password"), + dgettext("loris", "Password"), $pwd_attribs ); $this->addCheckbox( @@ -734,7 +734,7 @@ class Edit_User extends \NDB_Form ); $this->addPassword( '__Confirm', - dgettext("user_accounts", "Confirm Password"), + dgettext("loris", "Confirm Password"), $pwd_attribs ); @@ -743,11 +743,15 @@ class Edit_User extends \NDB_Form // - once leading and trailing spaces are stripped, the field should // not exceed 120 chars $onInvalidMsg - = "this.setCustomValidity('First name is required and " - . "should not exceed 120 characters')"; + = "this.setCustomValidity('" + . dgettext( + "user_accounts", + "First name is required and should not exceed 120 characters" + ) + . "')"; $this->addBasicText( 'First_name', - dgettext("user_accounts", "First name"), + dgettext("loris", "First name"), [], [ 'oninvalid' => $onInvalidMsg, @@ -761,11 +765,15 @@ class Edit_User extends \NDB_Form // - once leading and trailing spaces are stripped, the field should // not exceed 120 chars $onInvalidMsg - = "this.setCustomValidity('Last name is required and " - . "should not exceed 120 characters')"; + = "this.setCustomValidity('" + . dgettext( + "user_accounts", + "Last name is required and should not exceed 120 characters" + ) + . "')"; $this->addBasicText( 'Last_name', - dgettext("user_accounts", "Last name"), + dgettext("loris", "Last name"), [], [ 'oninvalid' => $onInvalidMsg, @@ -825,7 +833,7 @@ class Edit_User extends \NDB_Form // email address $this->addBasicText( 'Email', - dgettext("user_accounts", "Email address"), + dgettext("loris", "Email address"), ['required' => true] ); $this->addCheckbox( @@ -1077,7 +1085,7 @@ class Edit_User extends \NDB_Form '
' . "

" - . "Data Supervisors to Email

" + . dgettext('loris', 'Data Supervisors to Email') . " " . "
" ); @@ -1445,11 +1453,14 @@ class Edit_User extends \NDB_Form // Although some of these characters are legal in emails, due to the // current HTML escaping method, it is better to reject email // addresses containing them - return 'Email address can not contain any the following ' . - 'characters: <, >, & and "'; + return dgettext( + 'loris', + 'Email address cannot contain any of the following characters: ' + . '<, >, &, and "' + ); } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) { // If email not syntactically valid - return "Invalid email address"; + return dgettext('loris', 'Invalid email address'); } // check email address' uniqueness diff --git a/modules/user_accounts/templates/form_edit_user.tpl b/modules/user_accounts/templates/form_edit_user.tpl index c5faa588f1a..1040474b460 100644 --- a/modules/user_accounts/templates/form_edit_user.tpl +++ b/modules/user_accounts/templates/form_edit_user.tpl @@ -8,14 +8,14 @@
-

{dgettext("user_accounts", "Password Rules")}

+

{dgettext("loris", "Password Rules")}

    -
  • {dgettext("user_accounts", "The password must be at least 8 characters long.")}
  • -
  • {dgettext("user_accounts", "The password cannot be your username or email address.")}
  • -
  • {dgettext("user_accounts", "No special characters are required but your password must be sufficiently complex to be accepted.")}
  • +
  • {dgettext("loris", "The password must be at least 8 characters long.")}
  • +
  • {dgettext("loris", "The password cannot be your username or email address.")}
  • +
  • {dgettext("loris", "No special characters are required but your password must be sufficiently complex to be accepted.")}
-

{dgettext("user_accounts", "Please choose a unique password.")}

-

{dgettext("user_accounts", "We suggest using a password manager to generate one for you.")}

+

{dgettext("loris", "Please choose a unique password.")}

+

{dgettext("loris", "We suggest using a password manager to generate one for you.")}

{dgettext("user_accounts", "Notes")}

  • {dgettext("user_accounts", "It is recommended to use an email address as the username, for clarity and uniqueness.")}
  • @@ -453,7 +453,7 @@ {$form.account_request_date.label}
    - {$form.account_request_date.html|default:'None'} + {$form.account_request_date.html|default:dgettext('loris', 'None')}
diff --git a/php/libraries/Password.class.inc b/php/libraries/Password.class.inc index 755df264d58..e3f676ab497 100644 --- a/php/libraries/Password.class.inc +++ b/php/libraries/Password.class.inc @@ -129,7 +129,7 @@ class Password dgettext( 'loris', 'This password is known to be exposed in online data' - . 'breaches.' + . ' breaches.' ) ); } From aa3ba317fde1dbf0ba9476c5123fc6e568397f15 Mon Sep 17 00:00:00 2001 From: Saket Hatwar Date: Mon, 3 Nov 2025 16:10:00 -0500 Subject: [PATCH 13/17] fixes --- .../locale/hi/LC_MESSAGES/user_accounts.po | 22 +++++++++- .../user_accounts/locale/user_accounts.pot | 20 +++++++++- modules/user_accounts/php/edit_user.class.inc | 40 ++++++++++++++----- 3 files changed, 69 insertions(+), 13 deletions(-) diff --git a/modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po b/modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po index 350cadbb573..d9f8aaaa6ac 100644 --- a/modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po +++ b/modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po @@ -54,8 +54,11 @@ msgstr "नोट्स" msgid "It is recommended to use an email address as the username, for clarity and uniqueness." msgstr "स्पष्टता और अद्वितीयता के लिए उपयोगकर्ता नाम के रूप में ईमेल पते का उपयोग करने की अनुशंसा की जाती है।" -msgid "When generating a new password, please notify the user by checking 'Send email to user' box below!" -msgstr "नया पासवर्ड बनाते समय, कृपया नीचे 'उपयोगकर्ता को ईमेल भेजें' बॉक्स को चेक करके उपयोगकर्ता को सूचित करें!" +msgid "When generating a new password, please notify the user by checking 'Send email to user' box" +msgstr "नया पासवर्ड बनाते समय, कृपया 'उपयोगकर्ता को ईमेल भेजें' बॉक्स को चुनकर उपयोगकर्ता को सूचित करें।" + +msgid "You must leave the password field empty if you want the system to generate one for you" +msgstr "यदि आप चाहते हैं कि सिस्टम आपके लिए पासवर्ड बनाए, तो पासवर्ड फ़ील्ड खाली छोड़ना आवश्यक है।" msgid "Add/Edit User" msgstr "उपयोगकर्ता जोड़ें/संपादित करें" @@ -173,3 +176,18 @@ msgstr "कृपया कम से कम एक परीक्षक स् msgid "Please notice that the \"Active from\" date should be lesser or equal to the \"Active to\" date." msgstr "कृपया ध्यान दें कि 'सक्रिय शुरू' तिथि, 'सक्रिय समाप्त' तिथि के बराबर या उससे पहले होनी चाहिए।" + +msgid "Your password cannot be your email." +msgstr "आपका पासवर्ड आपका ईमेल नहीं हो सकता।" + +msgid "Your password cannot be your user name." +msgstr "आपका पासवर्ड आपका उपयोगकर्ता नाम नहीं हो सकता।" + +msgid "The passwords do not match." +msgstr "पासवर्ड मेल नहीं खाते।" + +msgid "New and old passwords are identical" +msgstr "नया और पुराना पासवर्ड समान हैं।" + +msgid "This email address is already in use" +msgstr "यह ईमेल पता पहले से उपयोग में है।" diff --git a/modules/user_accounts/locale/user_accounts.pot b/modules/user_accounts/locale/user_accounts.pot index 2d8f671deaa..e999aa55091 100644 --- a/modules/user_accounts/locale/user_accounts.pot +++ b/modules/user_accounts/locale/user_accounts.pot @@ -54,7 +54,10 @@ msgstr "" msgid "It is recommended to use an email address as the username, for clarity and uniqueness." msgstr "" -msgid "When generating a new password, please notify the user by checking 'Send email to user' box below!" +msgid "When generating a new password, please notify the user by checking 'Send email to user' box" +msgstr "" + +msgid "You must leave the password field empty if you want the system to generate one for you" msgstr "" msgid "Add/Edit User" @@ -173,3 +176,18 @@ msgstr "" msgid "Please notice that the \"Active from\" date should be lesser or equal to the \"Active to\" date." msgstr "" + +msgid "Your password cannot be your email." +msgstr "" + +msgid "Your password cannot be your user name." +msgstr "" + +msgid "The passwords do not match." +msgstr "" + +msgid "New and old passwords are identical" +msgstr "" + +msgid "This email address is already in use" +msgstr "" diff --git a/modules/user_accounts/php/edit_user.class.inc b/modules/user_accounts/php/edit_user.class.inc index 3daabd326ab..4c94173d15d 100644 --- a/modules/user_accounts/php/edit_user.class.inc +++ b/modules/user_accounts/php/edit_user.class.inc @@ -1247,7 +1247,10 @@ class Edit_User extends \NDB_Form if ($values['Email'] === $values['Password_hash'] && $values['Password_hash'] !== '' ) { - $errors['Password'] = self::PASSWORD_ERROR_IS_EMAIL; + $errors['Password'] = dgettext( + "user_accounts", + "Your password cannot be your email." + ); } // Make sure the user is not using their username as their password. @@ -1260,7 +1263,10 @@ class Edit_User extends \NDB_Form || (!empty($this->identifier) && $this->identifier === $values['Password_hash']) ) { - $errors['Password'] = self::PASSWORD_ERROR_IS_USER; + $errors['Password'] = dgettext( + "user_accounts", + "Your password cannot be your user name." + ); } if (!is_null($this->identifier)) { @@ -1286,7 +1292,10 @@ class Edit_User extends \NDB_Form // Ensure that the password and confirm password fields match. // TODO This validation should be done on the front-end instead. if ($plaintext !== $values['__Confirm']) { - $errors['Password'] = self::PASSWORD_ERROR_NO_MATCH; + $errors['Password'] = dgettext( + "user_accounts", + "The passwords do not match." + ); } // if password is user-defined, and user wants to change password @@ -1302,7 +1311,10 @@ class Edit_User extends \NDB_Form $isPasswordDifferent = \User::factory($this->identifier) ->isPasswordDifferent($decoded); if (! $isPasswordDifferent) { - $errors['Password'] = self::PASSWORD_ERROR_NO_CHANGE; + $errors['Password'] = dgettext( + "user_accounts", + "New and old passwords are identical" + ); } } catch (\InvalidArgumentException $e) { $errors['Password'] = $e->getMessage(); @@ -1314,17 +1326,22 @@ class Edit_User extends \NDB_Form && $values['NA_Password'] == "on" && $values['SendEmail'] != "on" ) { - $errors['Email'] - = 'When generating a new password, ' - . 'please notify the user by checking Send email to user box'; + $errors['Email'] = dgettext( + "user_accounts", + "When generating a new password, please notify the user by checking" + + " 'Send email to user' box" + ); } if (isset($values['NA_Password']) && $values['NA_Password'] == 'on' && $plaintext != '' ) { - $errors['Password'] = 'You must leave the password field empty ' - . 'if you want the system to generate one for you'; + $errors['Password'] = dgettext( + "user_accounts", + "You must leave the password field empty if you want the system to" + + " generate one for you" + ); } if (is_null($this->identifier) @@ -1474,7 +1491,10 @@ class Edit_User extends \NDB_Form // Email already exists in database if ($result > 0) { - return self::EMAIL_NOT_UNIQUE; + return dgettext( + "user_accounts", + "This email address is already in use" + ); } return null; From 7aa8b3dccca33c0ae1a99a25d42a159f7bc65ab7 Mon Sep 17 00:00:00 2001 From: T Saket Hatwar <112693309+SKADE2303@users.noreply.github.com> Date: Tue, 4 Nov 2025 03:05:06 +0530 Subject: [PATCH 14/17] lint --- modules/user_accounts/php/edit_user.class.inc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/user_accounts/php/edit_user.class.inc b/modules/user_accounts/php/edit_user.class.inc index a05de28d35e..be5ab7a517a 100644 --- a/modules/user_accounts/php/edit_user.class.inc +++ b/modules/user_accounts/php/edit_user.class.inc @@ -1379,17 +1379,17 @@ class Edit_User extends \NDB_Form if ($values['examiner_sites'] ?? null) { if ($values['examiner_radiologist'] == '') { $errors['examiner_group'] = dgettext( - "user_accounts", - "Please specify if examiner is a radiologist" - ); + "user_accounts", + "Please specify if examiner is a radiologist" + ); } if ($values['examiner_radiologist'] !== '' && $values['examiner_pending'] == '' ) { $errors['examiner_group'] = dgettext( - "user_accounts", - "Please set pending approval Yes or No" - ); + "user_accounts", + "Please set pending approval Yes or No" + ); } } elseif ($values['examiner_radiologist'] !== '' || $values['examiner_pending'] ?? '' !== '' From cf9271a0a48e45169519c7a338fabcacfe758f5f Mon Sep 17 00:00:00 2001 From: T Saket Hatwar <112693309+SKADE2303@users.noreply.github.com> Date: Tue, 4 Nov 2025 03:34:44 +0530 Subject: [PATCH 15/17] Fix string --- modules/user_accounts/php/edit_user.class.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/user_accounts/php/edit_user.class.inc b/modules/user_accounts/php/edit_user.class.inc index be5ab7a517a..f3ae4d5d625 100644 --- a/modules/user_accounts/php/edit_user.class.inc +++ b/modules/user_accounts/php/edit_user.class.inc @@ -1303,7 +1303,7 @@ class Edit_User extends \NDB_Form $errors['Email'] = dgettext( "user_accounts", "When generating a new password, please notify the user by checking" - + " 'Send email to user' box" + . " 'Send email to user' box" ); } @@ -1314,7 +1314,7 @@ class Edit_User extends \NDB_Form $errors['Password'] = dgettext( "user_accounts", "You must leave the password field empty if you want the system to" - + " generate one for you" + . " generate one for you" ); } From 748c6a763f34abcc19caaafba1a6a7bb9a286388 Mon Sep 17 00:00:00 2001 From: T Saket Hatwar <112693309+SKADE2303@users.noreply.github.com> Date: Tue, 4 Nov 2025 04:14:56 +0530 Subject: [PATCH 16/17] lint --- modules/user_accounts/jsx/userAccountsIndex.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/user_accounts/jsx/userAccountsIndex.js b/modules/user_accounts/jsx/userAccountsIndex.js index 58bfb9f8441..b121c25ea8a 100644 --- a/modules/user_accounts/jsx/userAccountsIndex.js +++ b/modules/user_accounts/jsx/userAccountsIndex.js @@ -123,7 +123,7 @@ class UserAccountsIndex extends Component { } break; case t('Pending Approval', {ns: 'user_accounts'}): - const pendingKey = t('Pending Approval', { ns: 'user_accounts' }); + const pendingKey = t('Pending Approval', {ns: 'user_accounts'}); if (row[pendingKey] === 'Y') { result = {t('Yes', {ns: 'loris'})}; } else if (row[pendingKey] === 'N') { From f9a3d701ba0dd1b6ded565aa9710d85ab49330dd Mon Sep 17 00:00:00 2001 From: Dave MacFarlane Date: Mon, 10 Nov 2025 12:54:44 -0500 Subject: [PATCH 17/17] Fix issues found in testing - The "edit user" link did not go to the correct URL - "Sites" and "Projects" were encoded as separate strings rather than plural forms of "Site" and "Project" - Some error messages were in the wrong namespace - "When generating a new password, please notify the user by checking 'Send email to user' box below!" was untranslated because the template string did not match the code - Translation strings from widgets were incorrectly removed - Also added Japanese --- Makefile | 3 +- locale/hi/LC_MESSAGES/loris.po | 15 +- locale/ja/LC_MESSAGES/loris.po | 21 ++- locale/loris.pot | 36 ++-- .../user_accounts/jsx/userAccountsIndex.js | 14 +- .../locale/ja/LC_MESSAGES/user_accounts.po | 169 ++++++++++++++++++ .../user_accounts/locale/user_accounts.pot | 8 +- modules/user_accounts/php/edit_user.class.inc | 8 +- 8 files changed, 229 insertions(+), 45 deletions(-) diff --git a/Makefile b/Makefile index e7b046ec28a..dec005e9c6c 100755 --- a/Makefile +++ b/Makefile @@ -157,7 +157,8 @@ locales: msgfmt -o modules/timepoint_list/locale/es/LC_MESSAGES/timepoint_list.mo modules/timepoint_list/locale/es/LC_MESSAGES/timepoint_list.po msgfmt -o modules/user_accounts/locale/ja/LC_MESSAGES/user_accounts.mo modules/user_accounts/locale/ja/LC_MESSAGES/user_accounts.po msgfmt -o modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.mo modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po - npx i18next-conv -l hi -s modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po -t modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.json + npx i18next-conv -l hi -s modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.po -t modules/user_accounts/locale/hi/LC_MESSAGES/user_accounts.json --compatibilityJSON v4 + npx i18next-conv -l ja -s modules/user_accounts/locale/ja/LC_MESSAGES/user_accounts.po -t modules/user_accounts/locale/ja/LC_MESSAGES/user_accounts.json --compatibilityJSON v4 acknowledgements: modules/acknowledgements/locale/ja/LC_MESSAGES/acknowledgements.mo target=acknowledgements npm run compile diff --git a/locale/hi/LC_MESSAGES/loris.po b/locale/hi/LC_MESSAGES/loris.po index e79ea5fb478..52f26109475 100644 --- a/locale/hi/LC_MESSAGES/loris.po +++ b/locale/hi/LC_MESSAGES/loris.po @@ -17,6 +17,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" # Smarty template main.tpl strings msgid "LORIS" @@ -187,16 +188,14 @@ msgid "Email" msgstr "ईमेल" msgid "Site" -msgstr "साइट" - -msgid "Sites" -msgstr "साइट्स" +msgid_plural "Sites" +msgstr[0] "साइट" +msgstr[1] "साइट्स" msgid "Project" -msgstr "परियोजना" - -msgid "Projects" -msgstr "प्रोजेक्ट्स" +msgid_plural "Projects" +msgstr[0] "परियोजना" +msgstr[1] "प्रोजेक्ट्" msgid "Candidate Registration Project" msgstr "उम्मीदवार पंजीकरण परियोजना" diff --git a/locale/ja/LC_MESSAGES/loris.po b/locale/ja/LC_MESSAGES/loris.po index 6f13ef8dd8c..95544e70758 100644 --- a/locale/ja/LC_MESSAGES/loris.po +++ b/locale/ja/LC_MESSAGES/loris.po @@ -129,6 +129,9 @@ msgstr "作成する" msgid "N/A" msgstr "適用できない" +msgid "Back" +msgstr "戻る" + # Filters msgid "Selection Filter" msgstr "'選択フィルター" @@ -162,14 +165,19 @@ msgstr "候補者識別子" msgid "Visit Label" msgstr "ラベルを訪問" +msgid "Email" +msgstr "メール" + msgid "Site" -msgstr "サイト" +msgid_plural "Sites" +msgstr[0] "サイト" msgid "Module" msgstr "モジュール" msgid "Project" -msgstr "プロジェクト" +msgid_plural "Projects" +msgstr[0] "プロジェクト" msgid "Candidate Registration Project" msgstr "候補者登録プロジェクト" @@ -226,6 +234,9 @@ msgstr "訪問" msgid "An error occured while loading the page." msgstr "このページの読み込み中にエラーが発生しました" +msgid "Active" +msgstr "アクティブ" + msgid "Entity Type" msgstr "エンティティタイプ" @@ -403,6 +414,9 @@ msgstr "姓は必須で、120文字以内で入力してください。" msgid "Email address" msgstr "電子メールアドレス" +msgid "Password" +msgstr "パスワード" + msgid "New Password" msgstr "新しいパスワード" @@ -412,6 +426,9 @@ msgstr "パスワードを認証する" msgid "Email address is required" msgstr "メールアドレスは必須です" +msgid "Email address cannot contain any of the following characters: <, >, &, and \"" +msgstr "メールアドレスには、<、>、&、\" の文字を含めることはできません。" + msgid "The password must be at least 8 characters long." msgstr "パスワードは8文字以上である必要があります" diff --git a/locale/loris.pot b/locale/loris.pot index b0ade86d2ee..0da60e65022 100644 --- a/locale/loris.pot +++ b/locale/loris.pot @@ -125,24 +125,9 @@ msgstr "" msgid "N/A" msgstr "" -msgid "Save" -msgstr "" - -msgid "Reset" -msgstr "" - msgid "Back" msgstr "" -msgid "None" -msgstr "" - -msgid "Y" -msgstr "" - -msgid "N" -msgstr "" - msgid "Create" msgstr "" @@ -189,19 +174,15 @@ msgid "Email" msgstr "" msgid "Site" -msgstr "" - -msgid "Sites" -msgstr "" +msgid_plural "Sites" +msgstr[0] "" msgid "Module" msgstr "" msgid "Project" -msgstr "" - -msgid "Projects" -msgstr "" +msgid_plural "Projects" +msgstr[0] "" msgid "Candidate Registration Project" msgstr "" @@ -273,6 +254,12 @@ msgstr "" msgid "Ethnicity" msgstr "" +msgid "Save" +msgstr "" + +msgid "Reset" +msgstr "" + # Data table strings msgid "{{pageCount}} rows displayed of {{totalCount}}." msgstr "" @@ -418,6 +405,9 @@ msgid "Instrument" msgid_plural "Instruments" msgstr[0] "" +msgid "None" +msgstr "" + msgid "Partial" msgstr "" diff --git a/modules/user_accounts/jsx/userAccountsIndex.js b/modules/user_accounts/jsx/userAccountsIndex.js index b121c25ea8a..2b2f13989b7 100644 --- a/modules/user_accounts/jsx/userAccountsIndex.js +++ b/modules/user_accounts/jsx/userAccountsIndex.js @@ -5,6 +5,7 @@ import PropTypes from 'prop-types'; import i18n from 'I18nSetup'; import {withTranslation} from 'react-i18next'; import hiStrings from '../locale/hi/LC_MESSAGES/user_accounts.json'; +import jaStrings from '../locale/ja/LC_MESSAGES/user_accounts.json'; import Loader from 'Loader'; import FilterableDataTable from 'FilterableDataTable'; @@ -78,7 +79,7 @@ class UserAccountsIndex extends Component { let url; let result = {cell}; switch (column) { - case t('Site', {ns: 'loris'}): + case t('Site', {ns: 'loris', count: 1}): result = ( {cell @@ -94,7 +95,7 @@ class UserAccountsIndex extends Component { ); } break; - case t('Project', {ns: 'loris'}): + case t('Project', {ns: 'loris', count: 1}): result = ( {cell.map( @@ -111,7 +112,8 @@ class UserAccountsIndex extends Component { } break; case t('Username', {ns: 'loris'}): - url = loris.BaseURL + '/user_accounts/edit_user/' + row.Username; + const username = row[t('Username', {ns: 'loris'})]; + url = loris.BaseURL + '/user_accounts/edit_user/' + username; result = {cell}; break; case t('Active', {ns: 'loris'}): @@ -170,7 +172,7 @@ class UserAccountsIndex extends Component { const options = this.state.data.fieldOptions; const fields = [ { - label: t('Site', {ns: 'loris'}), + label: t('Site', {ns: 'loris', count: 1}), show: true, filter: { name: 'site', @@ -179,7 +181,7 @@ class UserAccountsIndex extends Component { }, }, { - label: t('Project', {ns: 'loris'}), + label: t('Project', {ns: 'loris', count: 1}), show: true, filter: { name: 'project', @@ -266,7 +268,7 @@ UserAccountsIndex.propTypes = { }; window.addEventListener('load', () => { - i18n.addResourceBundle('ja', 'user_accounts', {}); + i18n.addResourceBundle('ja', 'user_accounts', jaStrings); i18n.addResourceBundle('hi', 'user_accounts', hiStrings); const Index = withTranslation( ['user_accounts', 'loris'] diff --git a/modules/user_accounts/locale/ja/LC_MESSAGES/user_accounts.po b/modules/user_accounts/locale/ja/LC_MESSAGES/user_accounts.po index a2c9d55ceab..d8e0a60d403 100644 --- a/modules/user_accounts/locale/ja/LC_MESSAGES/user_accounts.po +++ b/modules/user_accounts/locale/ja/LC_MESSAGES/user_accounts.po @@ -29,3 +29,172 @@ msgstr "アカウント承認待ち" msgid "Pending account approvals" msgstr "保留中のアカウント承認" + +msgid "This user has no site affiliations" +msgstr "このユーザーにはサイト所属がありません。" + +msgid "This user has no project affiliations" +msgstr "このユーザーにはプロジェクトへの所属はありません。" + +msgid "Full Name" +msgstr "フルネーム" + +msgid "Pending Approval" +msgstr "承認待ち" + +msgid "Radiologist" +msgstr "放射線科医" + +msgid "Account Request Date" +msgstr "アカウントリクエスト日" + +msgid "Add User" +msgstr "ユーザーを追加" + +msgid "The form you submitted contains data entry errors" +msgstr "送信したフォームにデータ入力エラーが含まれています。" + +msgid "Notes" +msgstr "注記" + +msgid "It is recommended to use an email address as the username, for clarity and uniqueness." +msgstr "明確さと一意性を保つために、ユーザー名として電子メール アドレスを使用することをお勧めします。" + +msgid "When generating a new password, please notify the user by checking 'Send email to user' box below!" +msgstr "新しいパスワードを生成するときは、「ユーザーにメールを送信」ボックスをチェックしてユーザーに通知してください。" + +msgid "You must leave the password field empty if you want the system to generate one for you" +msgstr "システムでパスワードを生成する場合は、パスワード フィールドを空のままにしておく必要があります。" + +msgid "Add/Edit User" +msgstr "ユーザーの追加/編集" + +msgid "Reject User" +msgstr "ユーザーを拒否" + +msgid "Make user name match email address" +msgstr "ユーザー名をメールアドレスと一致させます。" + +msgid "Generate new password" +msgstr "新しいパスワードを生成します。" + +msgid "Degree" +msgstr "程度" + +msgid "Academic Position" +msgstr "学術的地位" + +msgid "Institution" +msgstr "機関" + +msgid "Department" +msgstr "部門" + +msgid "Street Address" +msgstr "住所" + +msgid "City" +msgstr "市" + +msgid "State/Province" +msgstr "州/県" + +msgid "Zip/Postal Code" +msgstr "郵便番号" + +msgid "Country" +msgstr "国" + +msgid "FAX" +msgstr "ファックス" + +msgid "Send email to user" +msgstr "ユーザーにメールを送信" + +msgid "Confirm Email" +msgstr "メール確認" + +msgid "Examiner At:" +msgstr "審査官:" + +msgid "Examiner Status" +msgstr "審査官のステータス" + +msgid "Pending approval" +msgstr "承認待ち" + +msgid "Active from" +msgstr "アクティブ開始日" + +msgid "Active to" +msgstr "アクティブに" + +msgid "Permissions" +msgstr "権限" + +msgid "Supervisors" +msgstr "監督者" + +msgid "You cannot enter a user name if you want it to match the email address" +msgstr "メールアドレスと一致させたい場合、ユーザー名を入力することはできません。" + +msgid "You must enter a user name or choose to make it match the email address" +msgstr "ユーザー名を入力するか、ユーザー名と電子メール アドレスを一致させるように選択する必要があります。" + +msgid "The user name already exists" +msgstr "ユーザー名は既に存在します。" + +msgid "The user name must not exceed 255 characters" +msgstr "ユーザー名は 255 文字を超えてはなりません。" + +msgid "You cannot have the user name match an email address that contains a whitespace character" +msgstr "ユーザー名を、空白文字を含む電子メール アドレスと一致させることはできません。" + +msgid "Whitespace characters are not allowed in user names" +msgstr "ユーザー名には空白文字は使用できません。" + +msgid "Please specify password or click Generate new password" +msgstr "パスワードを指定するか、「新しいパスワードを生成」をクリックしてください。" + +msgid "Password is required" +msgstr "パスワードが必要です。" + +msgid "You must enter an email address" +msgstr "メールアドレスを入力する必要があります。" + +msgid "Email and confirmed email do not match" +msgstr "メールアドレスと確認メールアドレスが一致しません。" + +msgid "You must select at least one site/affiliation" +msgstr "少なくとも 1 つのサイト/所属先を選択する必要があります。" + +msgid "You must select at least one project/affiliation" +msgstr "少なくとも 1 つのプロジェクト/所属を選択する必要があります。" + +msgid "Please specify if examiner is a radiologist" +msgstr "検査者が放射線科医の場合は選択してください。" + +msgid "Please set pending approval Yes or No" +msgstr "保留中の承認を「はい」または「いいえ」に設定してください。" + +msgid "Please select at least one examiner site or clear the 'Examiner status' fields below (i.e. 'Radiologist' and 'Pending Approval')." +msgstr "少なくとも 1 つの検査官サイトを選択するか、以下の「検査官ステータス」フィールド (「放射線科医」および「承認待ち」など) をクリアしてください。" + +msgid "Please notice that the \"Active from\" date should be lesser or equal to the \"Active to\" date." +msgstr "「アクティブ開始日」は「アクティブ終了日」と同じかそれより小さい日付にする必要があることに注意してください。" + +msgid "Your password cannot be your email." +msgstr "パスワードにメールアドレスは使用できません。" + +msgid "Your password cannot be your user name." +msgstr "パスワードをユーザー名と同じにすることはできません。" + +msgid "The passwords do not match." +msgstr "パスワードが一致しません。" + +msgid "New and old passwords are identical" +msgstr "新しいパスワードと古いパスワードは同一です。" + +msgid "This email address is already in use" +msgstr "このメールアドレスはすでに使用されています。" + diff --git a/modules/user_accounts/locale/user_accounts.pot b/modules/user_accounts/locale/user_accounts.pot index e999aa55091..53ae197e90f 100644 --- a/modules/user_accounts/locale/user_accounts.pot +++ b/modules/user_accounts/locale/user_accounts.pot @@ -24,6 +24,12 @@ msgstr "" msgid "Edit User" msgstr "" +msgid "Pending account approval" +msgstr "" + +msgid "Pending account approvals" +msgstr "" + msgid "This user has no site affiliations" msgstr "" @@ -54,7 +60,7 @@ msgstr "" msgid "It is recommended to use an email address as the username, for clarity and uniqueness." msgstr "" -msgid "When generating a new password, please notify the user by checking 'Send email to user' box" +msgid "When generating a new password, please notify the user by checking 'Send email to user' box below!" msgstr "" msgid "You must leave the password field empty if you want the system to generate one for you" diff --git a/modules/user_accounts/php/edit_user.class.inc b/modules/user_accounts/php/edit_user.class.inc index f3ae4d5d625..5a0b1bdd825 100644 --- a/modules/user_accounts/php/edit_user.class.inc +++ b/modules/user_accounts/php/edit_user.class.inc @@ -730,7 +730,7 @@ class Edit_User extends \NDB_Form $onInvalidMsg = "this.setCustomValidity('" . dgettext( - "user_accounts", + "loris", "First name is required and should not exceed 120 characters" ) . "')"; @@ -752,7 +752,7 @@ class Edit_User extends \NDB_Form $onInvalidMsg = "this.setCustomValidity('" . dgettext( - "user_accounts", + "loris", "Last name is required and should not exceed 120 characters" ) . "')"; @@ -861,7 +861,7 @@ class Edit_User extends \NDB_Form $this->addSelect( 'CenterIDs', - dgettext("loris", "Sites"), + dngettext("loris", "Site", "Sites", count($siteOptions)), $siteOptions, [ 'class' => 'form-control input-sm resizable', @@ -881,7 +881,7 @@ class Edit_User extends \NDB_Form $this->addSelect( 'ProjectIDs', - dgettext("loris", "Projects"), + dngettext("loris", "Project", "Projects", count($projects)), $projectOptions, [ 'class' => 'form-control input-sm resizable',