From 8e3f03c23df160390068485010284f6b70a5cd47 Mon Sep 17 00:00:00 2001 From: Rida Abou-Haidar Date: Thu, 2 Apr 2020 09:57:31 -0400 Subject: [PATCH 01/15] [Instruments] Bugfix multi-escaped special characters (#6223) Removed duplicate call to HTMLSpecialChars() causing double escaping on any instrument field with one of the following characters & < > " The removal is justified since these fields are being escaped directly in the database class https://github.com/aces/Loris/blob/master/php/libraries/Database.class.inc#L538 --- php/libraries/LorisForm.class.inc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/php/libraries/LorisForm.class.inc b/php/libraries/LorisForm.class.inc index a81cb7cd899..49543aaa35e 100644 --- a/php/libraries/LorisForm.class.inc +++ b/php/libraries/LorisForm.class.inc @@ -695,10 +695,6 @@ class LorisForm } } } - // Always sanitize user-controlled input - if (!is_array($newValue)) { - $newValue = htmlspecialchars($newValue); - } return $newValue; } From ce4ee70d87e5f6adff71b48a8ca1ecd6c886ec59 Mon Sep 17 00:00:00 2001 From: Shen Date: Fri, 3 Apr 2020 14:30:07 -0400 Subject: [PATCH 02/15] [EEG] Fix error loading session (#6238) Lower case name of autoloaded file. The filename must be lowercase to be autoloaded on case sensitive filesystems. --- .../{ElectrophysioFile.class.inc => electrophysiofile.class.inc} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename modules/electrophysiology_browser/php/models/{ElectrophysioFile.class.inc => electrophysiofile.class.inc} (100%) diff --git a/modules/electrophysiology_browser/php/models/ElectrophysioFile.class.inc b/modules/electrophysiology_browser/php/models/electrophysiofile.class.inc similarity index 100% rename from modules/electrophysiology_browser/php/models/ElectrophysioFile.class.inc rename to modules/electrophysiology_browser/php/models/electrophysiofile.class.inc From e391855239312fb238fc1216e22555042fa56bc7 Mon Sep 17 00:00:00 2001 From: Ling Ma Date: Wed, 8 Apr 2020 11:12:46 -0400 Subject: [PATCH 03/15] Timepoint list baseurl fix, remove sessionid route from base router (#6324) This solves wrong URL problem in timepoint list at single parameter mode and the 404 error in the #6323. --- src/Router/BaseRouter.php | 36 ++++++++++-------------------------- 1 file changed, 10 insertions(+), 26 deletions(-) diff --git a/src/Router/BaseRouter.php b/src/Router/BaseRouter.php index 1faf8e007e1..e6e45a140ac 100644 --- a/src/Router/BaseRouter.php +++ b/src/Router/BaseRouter.php @@ -110,38 +110,22 @@ public function handle(ServerRequestInterface $request) : ResponseInterface if (preg_match("/^([0-9]{6})$/", $components[0])) { // FIXME: This assumes the baseURL is under / $path = $uri->getPath(); - $baseurl = $uri->withPath("/")->withQuery(""); + $baseurl = $uri->withPath("")->withQuery(""); $factory = \NDB_Factory::singleton(); $factory->setBaseURL($baseurl); - switch (count($components)) { - case 1: - $request = $request - ->withAttribute("baseurl", rtrim($baseurl->__toString(), '/')) - ->withAttribute("CandID", $components[0]); - $module = \Module::factory("timepoint_list"); - $mr = new ModuleRouter($module); - return $mr->handle($request); - case 2: - // CandID/SessionID, inherited from htaccess - $request = $request - ->withAttribute("baseurl", $baseurl->__toString()) - ->withAttribute("CandID", $components[0]); - // FIXME: Validate CandID is valid before continuing. - $request = $request - ->withAttribute( - "TimePoint", - \TimePoint::singleton($components[1]) - ); - $module = \Module::factory("instrument_list"); - $mr = new ModuleRouter($module); - return $mr->handle($request); - default: - // Fall through to 404. We don't have any routes that go farther - // than 2 levels.. + if (count($components) == 1) { + $request = $request + ->withAttribute("baseurl", $baseurl->__toString()) + ->withAttribute("CandID", $components[0]); + $module = \Module::factory("timepoint_list"); + $mr = new ModuleRouter($module); + return $mr->handle($request); } } + // Fall through to 404. We don't have any routes that go farther + // than 1 level.. return (new \LORIS\Middleware\PageDecorationMiddleware( $this->user ))->process( From 4d25c56f61feead58bcf5ad003613b977a808ccb Mon Sep 17 00:00:00 2001 From: Dave MacFarlane Date: Wed, 8 Apr 2020 13:41:19 -0400 Subject: [PATCH 04/15] [candidate_profile] Fix breadcrumb links in candidate_profile (#6339) Breadcrumb should go to the new module, not the old one. Fixes #6305 --- modules/candidate_profile/php/candidate_profile.class.inc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/candidate_profile/php/candidate_profile.class.inc b/modules/candidate_profile/php/candidate_profile.class.inc index 38f04eec6c4..9bb174182f2 100644 --- a/modules/candidate_profile/php/candidate_profile.class.inc +++ b/modules/candidate_profile/php/candidate_profile.class.inc @@ -130,7 +130,7 @@ class Candidate_Profile extends \NDB_Page return new \LORIS\BreadcrumbTrail( new \LORIS\Breadcrumb( 'Access Profile', - '/candidate_list' + '/candidate_list/?betaprofile=1' ), ); } @@ -140,11 +140,11 @@ class Candidate_Profile extends \NDB_Page return new \LORIS\BreadcrumbTrail( new \LORIS\Breadcrumb( 'Access Profile', - '/candidate_list' + '/candidate_list/?betaprofile=1' ), new \LORIS\Breadcrumb( "Candidate Dashboard $candid / $pscid", - "/$candid" + "/candidate_profile/$candid" ) ); } From 49b023e4c5b9eac315ff1091bad1645da88b3048 Mon Sep 17 00:00:00 2001 From: maltheism <16293415+maltheism@users.noreply.github.com> Date: Wed, 8 Apr 2020 13:42:59 -0400 Subject: [PATCH 05/15] [issue_tracker] Update testing plan for issue attachments (#6217) Updated the testing plan for issue_tracker module. In regard to uploading attachments. Fixes #6214 --- modules/issue_tracker/test/issue_tracker_test_plan.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/modules/issue_tracker/test/issue_tracker_test_plan.md b/modules/issue_tracker/test/issue_tracker_test_plan.md index de46ed5e743..6d903504e4c 100644 --- a/modules/issue_tracker/test/issue_tracker_test_plan.md +++ b/modules/issue_tracker/test/issue_tracker_test_plan.md @@ -1,5 +1,5 @@ Issue Tracker Filter Form [Automation Testing] -1. User can access the page iff they have issue tracker reporter or developer permission +1. A user can access the module only if they have one or more of the `issue_tracker_reporter` or `issue_tracker_developer` permissions. 2. User can see data from other sites iff they have access_all_profiles permission 3. Test that all filters work. Nothing should be filtered at first loading. 4. Test that all tabs (with filters) work and redirect to the correct table. My issues should be missing assignee filter and closed issues should be missing status filter. @@ -14,7 +14,8 @@ Issue Tracker Create New Issue [Manual Testing] 4. Submit invalid and valid PSCID and visit label pairs. Error messages should respond accordingly. Not that you cannot submit PSCIDs from other sites unless you have access all profiles permission 5. Submit just a visit label - this should give an error message. 6. Check that all values are propagated and saved correctly. -7. Check that watching logging is working - turn it off and on for your current user, and for other watchers on the issue +7. Add an attachment to the new issue and make sure that it is successfully uploaded. +8. Check that watching logging is working - turn it off and on for your current user, and for other watchers on the issue Issue Tracker Edit Existing Issue [Manual Testing] 1. User can access the page if they have (developer or reporter permission) and (they have either access_all_profiles or are a member of the site of the issue or the site has no issue). @@ -24,7 +25,10 @@ Issue Tracker Edit Existing Issue [Manual Testing] 5. Submit just a visit label - this should give an error message. 6. Check that all values are propagated and saved correctly. 7. Check that watching logging is working - turn it off and on for your current user, and for other watchers on the issue - +8. Check that an attachment can be adding to an existing issue. +9. Test if users assigned to issues can upload attachments. +10. Test if users can delete their own uploaded attachments. +11. Test if user assigned to issue cannot delete attachments of issue owner. Permissions [Automation Testing] 1. Remove access all profile permission. From dde77f89cf3683955f0193265ed67aa02fa40b31 Mon Sep 17 00:00:00 2001 From: sruthymathew123 Date: Thu, 9 Apr 2020 09:48:00 -0400 Subject: [PATCH 06/15] [publication] Fix Publication Filename display Issue (#6340) Fix bug where filename not displayed after the file is uploaded. Fixes #6308 --- modules/publication/jsx/projectFields.js | 4 ++-- modules/publication/jsx/viewProject.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/publication/jsx/projectFields.js b/modules/publication/jsx/projectFields.js index c18f2ea0e88..9d4f8c3d8e9 100644 --- a/modules/publication/jsx/projectFields.js +++ b/modules/publication/jsx/projectFields.js @@ -129,10 +129,10 @@ class ProjectFormFields extends React.Component { // Create download link & edit fields for existing files if (this.props.files) { this.props.files.forEach(function(f) { - let downloadURL = loris.BaseURL + '/publication/ajax/FileDownload.php?File=' + encodeURIComponent(f.URL); + let downloadURL = loris.BaseURL + '/publication/ajax/FileDownload.php?File=' + encodeURIComponent(f.Filename); let link = ( - {f.URL} + {f.Filename}    getSubjectData($outputType); $response['database'] = array_values( - $this->getFilesData($sessionID, $outputType) + $this->getFilesData($outputType) ); $response['sessions'] = $sessions; - $currentIndex = array_search($sessionID, $sessions); + $currentIndex = array_search($this->sessionID, $sessions); $response['nextSession'] = $sessions[$currentIndex+1] ?? ''; $response['prevSession'] = $sessions[$currentIndex-1] ?? ''; @@ -204,18 +205,17 @@ class Sessions extends \NDB_Page /** * Get the list of electrophysiology recordings with their recording information. * - * @param int $sessionID ID of the electrophysiology session * @param string $outputType output type to be displayed * * @return array with the file collection */ - function getFilesData(int $sessionID, string $outputType) + function getFilesData(string $outputType) { $db = \NDB_Factory::singleton()->database(); $fileCollection = array(); $params = array(); - $params['SID'] = $sessionID; + $params['SID'] = $this->sessionID; $query = 'SELECT pf.PhysiologicalFileID, pf.FilePath @@ -458,4 +458,23 @@ class Sessions extends \NDB_Page return $depends; } + /** + * Generate a breadcrumb trail for this page. + * + * @return \LORIS\BreadcrumbTrail + */ + public function getBreadcrumbs(): \LORIS\BreadcrumbTrail + { + return new \LORIS\BreadcrumbTrail( + new \LORIS\Breadcrumb( + 'Electrophysiology Browser', + '/electrophysiology_browser' + ), + new \LORIS\Breadcrumb( + 'View Session', + "/electrophysiology_browser/sessions/$this->sessionID" + ) + ); + } + } From 299cfc4aaa6b4b12c211c4d52d7636ef9a746f58 Mon Sep 17 00:00:00 2001 From: nicolasbrossard Date: Wed, 15 Apr 2020 09:34:31 -0400 Subject: [PATCH 08/15] [MRI Violations] Link to DICOM archive broken. (#6370) This fixes the broken links that you find on the MRI protocol checks violations sub-page of the MRI violations module. --- .../mri_violations/php/mri_protocol_check_violations.class.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/mri_violations/php/mri_protocol_check_violations.class.inc b/modules/mri_violations/php/mri_protocol_check_violations.class.inc index 161aecd41dd..4aa2340b65b 100644 --- a/modules/mri_violations/php/mri_protocol_check_violations.class.inc +++ b/modules/mri_violations/php/mri_protocol_check_violations.class.inc @@ -86,6 +86,7 @@ class Mri_Protocol_Check_Violations extends \NDB_Menu_Filter 'ValidRange', 'ValidRegex', 'SeriesUID', + 'TarchiveID' ); $this->tpl_data['hiddenHeaders'] = json_encode(['TarchiveID']); $this->validFilters = array( From 737dc3e1129e8061bc5cda04907f192439ea70c2 Mon Sep 17 00:00:00 2001 From: Zaliqa Date: Wed, 15 Apr 2020 09:36:24 -0400 Subject: [PATCH 09/15] [Instruments] Control Panel on Mobile has bad UI (#6359) Fix colour of font in sidebar in instrument control panel. --- htdocs/css/simple-sidebar.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/css/simple-sidebar.css b/htdocs/css/simple-sidebar.css index 93f1fdcd4b7..e644168d877 100644 --- a/htdocs/css/simple-sidebar.css +++ b/htdocs/css/simple-sidebar.css @@ -119,7 +119,7 @@ #sidebar-wrapper { left: 0; - color: white; + color: #064785; } .wrapper.active { From 231a45c297f537cc40bff36ffa5b1e56f4b89aa7 Mon Sep 17 00:00:00 2001 From: John Saigle <4022790+johnsaigle@users.noreply.github.com> Date: Wed, 15 Apr 2020 09:48:44 -0400 Subject: [PATCH 10/15] Fix broken links to MCIN websites in README; cleanup (#6296) - Fix broken link to LORIS webiste - Fix broken link to MCIN website - Change wording to "The Neuro" (this is recommended branding by the institution) - Remove superfluous subheader - Remove sudden change from first- to third-person writing style --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 763b0bcce54..20efa7f5148 100644 --- a/README.md +++ b/README.md @@ -108,15 +108,14 @@ such as the OS you're using, your PHP and Apache versions, etc. ## Contributing -The [LORIS team](http://loris.ca) at the Montreal Neurological Institute (MNI) is very happy to get code contributions and features from the global LORIS community. +We are very happy to get code contributions and features from the global LORIS community. -### Contributing Code If you would like to contribute to LORIS development, please consult our [Contributing Guide](./CONTRIBUTING.md). ## Powered by MCIN -LORIS is made by staff developers at the McGill Centre for Integrative Neuroscience ([MCIN.ca](www.mcin.ca)), led by Alan Evans and Samir Das at the Montreal Neurological Institute. +LORIS is made by staff developers at the [McGill Centre for Integrative Neuroscience](http://www.mcin.ca), led by Alan Evans and Samir Das at The Neuro (Montreal Neurological Institute-Hospital). -See [LORIS.ca](www.loris.ca) for our current team, the history of LORIS, and our **Technical Papers**. +Visit [the LORIS website](https://loris.ca) for the history of LORIS and our **Technical Papers**. The original (pre-GitHub) LORIS development team from 1999-2010 included: Dario Vins, Alex Zijdenbos, Jonathan Harlap, Matt Charlet, Andrew Corderey, Sebastian Muehlboeck, and Samir Das. From eddf11fa4756d40515692422ea3312c4dbb8260e Mon Sep 17 00:00:00 2001 From: Alexandra Livadas Date: Wed, 15 Apr 2020 09:52:13 -0400 Subject: [PATCH 11/15] Removed line 5 from user_accounts TestPlan.md (#6320) Removed line 5 from modules/user_accounts/test/TestPlan.md. --- modules/user_accounts/test/TestPlan.md | 62 +++++++++++++------------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/modules/user_accounts/test/TestPlan.md b/modules/user_accounts/test/TestPlan.md index 95afbe92a35..ba88ec8a01b 100644 --- a/modules/user_accounts/test/TestPlan.md +++ b/modules/user_accounts/test/TestPlan.md @@ -13,71 +13,69 @@ User Account module - Test plan * full name, * pending approval, * email -5. Verify that if the editor does not have permission 'Across all sites add and edit users' then the site drop-down list is populated with - the editor's associated sites, otherwise all sites are displayed. -6. The empty option in the site filter should display users from all sites, even if they are different from the active user. -7. Ensure adding a new user with the same name as an existing user fails. +5. The empty option in the site filter should display users from all sites, even if they are different from the active user. +6. Ensure adding a new user with the same name as an existing user fails. When creating or editing a user: (subtest: edit_user) ======================================================== -8. Ensure password strength rules are enforced. -9. Form submission (the `Save` Button) should fail if any of the following fields are blank: +7. Ensure password strength rules are enforced. +8. Form submission (the `Save` Button) should fail if any of the following fields are blank: - User name, - Password (and confirm password), - First name, - Last name, - Email. -10. If password and confirmed password do not match, an error should be displayed. [Automated] -11. Email fields containing submitted with invalid formats should generate an error. +9. If password and confirmed password do not match, an error should be displayed. [Automated] +10. Email fields containing submitted with invalid formats should generate an error. * Ensure the confirm email text field is not displayed on the edit user page (and only on the create new user page). -12. For an existing active user, edit the user's account and click 'Generate new password' and check 'Send email'. +11. For an existing active user, edit the user's account and click 'Generate new password' and check 'Send email'. Save. Check that an email is sent to the user with the new password. Check that after logging in, the user is immediately asked to update his/her password. -13. Check that if creating a new user an email is sent to him/her (requires email server). Also check that when a new +12. Check that if creating a new user an email is sent to him/her (requires email server). Also check that when a new user is logging in for the first time he/she is asked to change his/her password. 1. Check that when creating a new user, leading and trailing spaces in the username are stripped. 2. Check that you can create a new user with name 00 (double zero). 3. Check that you can delete one of the additional fields (organization, fax, etc...) that was previously set and that the save is performed. -14. Check that if generating a new password for a user an email is sent to that user containing the new password (requires +13. Check that if generating a new password for a user an email is sent to that user containing the new password (requires email server). -15. Check that when editing a user account it is not possible to set the password to its actual value (i.e. it needs to change). [Automated] -16. Verify that if the editor does not have permission 'Across all sites add and edit users' then the site drop-down list is populated with +14. Check that when editing a user account it is not possible to set the password to its actual value (i.e. it needs to change). [Automated] +15. Verify that if the editor does not have permission 'Across all sites add and edit users' then the site drop-down list is populated with the editor's associated sites, otherwise all sites are displayed. -17. Check that if the 'Display additional information' entry is set to false in the Configuration module, fields Degree, +16. Check that if the 'Display additional information' entry is set to false in the Configuration module, fields Degree, Academic Position, Institution, Department, Street Address, City, State/Province, Zip/Postal Code, Country and FAX are not shown. -18. Check that the 'Examiner At:' and 'Examiner Status' sections are available only if you have the 'Across all sites add and certify examiners'. -19. Check that selecting sites for the "Examiner At:" Section and saving, adds user X to the Examiner list (and in examiners table). -20. Check that de-selecting sites from the "Examiner At:" section and saving, does NOT delete X from the Examiner table but rather sets them as inactive for that site. -21. Check that setting the radiologist to Yes/No changes the values for X for all sites -22. Setting the Pending Approval for user X prevents user X from logging in until his/her account is approved. -23. Setting the Active=”No” for user X prevents user X from logging in until his/her account is active again. -24. Check that the values entered in 'Active from' and 'Active to' are validated properly. Any combination that has from <= to or either one or both fields null is valid -25. Check that modifications made to the basic user infos are displayed when the user table is reloaded. -26. When editing an existing user: Check that Reset button restores previous settings (does not wipe all settings, or +17. Check that the 'Examiner At:' and 'Examiner Status' sections are available only if you have the 'Across all sites add and certify examiners'. +18. Check that selecting sites for the "Examiner At:" Section and saving, adds user X to the Examiner list (and in examiners table). +19. Check that de-selecting sites from the "Examiner At:" section and saving, does NOT delete X from the Examiner table but rather sets them as inactive for that site. +20. Check that setting the radiologist to Yes/No changes the values for X for all sites +21. Setting the Pending Approval for user X prevents user X from logging in until his/her account is approved. +22. Setting the Active=”No” for user X prevents user X from logging in until his/her account is active again. +23. Check that the values entered in 'Active from' and 'Active to' are validated properly. Any combination that has from <= to or either one or both fields null is valid +24. Check that modifications made to the basic user infos are displayed when the user table is reloaded. +25. When editing an existing user: Check that Reset button restores previous settings (does not wipe all settings, or retain any changes). -27. When editing an existing user: Check that Back button takes you to the User Account page and does not save any +26. When editing an existing user: Check that Back button takes you to the User Account page and does not save any changes. -28. When editing an existing user: Clicking on the 'User Account' breadcrumb takes you to the User Account page +27. When editing an existing user: Clicking on the 'User Account' breadcrumb takes you to the User Account page without saving any changes to the user profile. -29. Check that if config setting 'Enable "Pwned Password" check' is set to 'Yes', then validation to make sure that the password +28. Check that if config setting 'Enable "Pwned Password" check' is set to 'Yes', then validation to make sure that the password entered (both for add user and edit user pages) has not been pwned is done. Also check that disabling this setting disables the validation. Example of a pwned password: a1b2c3!! -30. Check that a 'Reject user' button will be available on the edit user page if the editee is a user whose account is awaiting approval and the editee +29. Check that a 'Reject user' button will be available on the edit user page if the editee is a user whose account is awaiting approval and the editee has not yet logged in. -31. Edit a user that fits the conditions listed above and reject it. Make sure that the user has been removed from the database and does not show up in +30. Edit a user that fits the conditions listed above and reject it. Make sure that the user has been removed from the database and does not show up in the search results anymore. ### Testing permissions: *Log in as a simple user (non-admin) and ensure the following. Define `editee` as the user being edited and `editor` as the logged in user making the changes.* -32. Editor can only see and manipulate permissions for editee if and only if editor has the permissions in question -33. When page is saved with any set of selected permissions, on reload all selected permissions are kept and all unselected permissions are removed. -34. If editee has permissions that editor does not have, said permissions are not impacted by manipulating the editee's visible permissions (requires admin user login in a side window to be able to view all permissions for editee as editor will only be able to view permissions they own) -35. See security testing below +31. Editor can only see and manipulate permissions for editee if and only if editor has the permissions in question +32. When page is saved with any set of selected permissions, on reload all selected permissions are kept and all unselected permissions are removed. +33. If editee has permissions that editor does not have, said permissions are not impacted by manipulating the editee's visible permissions (requires admin user login in a side window to be able to view all permissions for editee as editor will only be able to view permissions they own) +34. See security testing below ##### Security testing: - Try manipulating the POST request from the browser to add a permission to the editee. Make sure that the editee gets the permission if it is within the set of permissions of the editor Make sure the editee does not get the permission if it is not within the set of permissions of the editor. [See this PR](https://github.com/aces/Loris/pull/3818#issuecomment-408882440) for more details. From 7b477639748dbf46bdca2d9e6237a1def010c5e0 Mon Sep 17 00:00:00 2001 From: Dave MacFarlane Date: Wed, 15 Apr 2020 09:53:02 -0400 Subject: [PATCH 12/15] [candidate_profile] Add help text for candidate profile (#6337) This adds some help text for the candidate_profile module. The help text is somewhat vague by necessity since it isn't context sensitive and the exact set of cards shown depends on the user's permissions and LORIS install's configurations. It only explains the visit link in the Candidate Info card (which is provided by the module itself and has minimal permissions, so should always be present.) Fixes #6206 --- modules/candidate_profile/help/candidate_profile.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 modules/candidate_profile/help/candidate_profile.md diff --git a/modules/candidate_profile/help/candidate_profile.md b/modules/candidate_profile/help/candidate_profile.md new file mode 100644 index 00000000000..06f0805d733 --- /dev/null +++ b/modules/candidate_profile/help/candidate_profile.md @@ -0,0 +1,7 @@ +# Candidate Profile + +This module allows you to see a summary of a candidate's information +across all modules. + +Click on the visit link in the "Candidate Info" card in order to access +that visit for the candidate. From 00bdd837638e69b5e32bfbca76e5ca95f60cbf05 Mon Sep 17 00:00:00 2001 From: Zaliqa Date: Wed, 15 Apr 2020 09:54:46 -0400 Subject: [PATCH 13/15] [UI] Improve navigation bar + support mobile/tablet (#6346) This is primarily to address issue #6235. However, while fixing that, it also fixes number of related UI/UX bugs. The scope of this PR is only the navigation bar. Fixes #6235 --- htdocs/bootstrap/css/custom-css.css | 80 ++++++++++++++++++++++------- htdocs/js/helpHandler.js | 6 +++ htdocs/main.css | 1 - smarty/templates/main.tpl | 19 +++++-- 4 files changed, 83 insertions(+), 23 deletions(-) diff --git a/htdocs/bootstrap/css/custom-css.css b/htdocs/bootstrap/css/custom-css.css index d90de0fa778..269d9143acc 100644 --- a/htdocs/bootstrap/css/custom-css.css +++ b/htdocs/bootstrap/css/custom-css.css @@ -23,6 +23,7 @@ Note: other colors are currenly inherited from Bootstrap default color palette border-top-right-radius: 0; border-top-left-radius: 0; background-color: white; + border: 1px solid #064785; } .navbar-nav > li > .dropdown-menu > li > a, @@ -34,6 +35,18 @@ Note: other colors are currenly inherited from Bootstrap default color palette .navbar-nav > li > .dropdown-menu > li > a:hover { color: #E89A0C; } +/* For mobile and tablet, repeat the above styling */ +@media (max-width: 991px) { + .navbar-default .navbar-nav .open .dropdown-menu >li>a, + .navbar-default .navbar-nav .open .dropdown-menu >li>a:focus { + color: #064785; + background-color: white; + } + .navbar-default .navbar-nav .open .dropdown-menu>li>a:hover { + color: #E89A0C; + background-color: white; + } +} .navbar-brand { padding: 16px 15px; @@ -53,9 +66,11 @@ Note: other colors are currenly inherited from Bootstrap default color palette } /* Show submenu when hovering on menu item */ -.dropdown:hover .dropdown-menu { +/* If hover functionality exists and window size larger than tablet */ +@media (hover: hover) and (min-width: 992px) { + .dropdown:hover .dropdown-menu { display: block; - border: 1px solid #064785; + } } /* Loris logo */ @@ -73,30 +88,46 @@ Note: other colors are currenly inherited from Bootstrap default color palette border-top-left-radius: 5px; border-top-right-radius: 5px; } - -.navbar-default .navbar-nav > li:hover > a, -.navbar-default .navbar-nav > li > a:hover, -.navbar-default .navbar-nav > li > a:focus, -.navbar-default .navbar-nav > li > a:active { - color: #064785; - background-color: white; +/* Styling for clicking on menu items */ +.navbar-default .navbar-nav > li.dropdown > a:focus, +.navbar-default .navbar-nav > li.dropdown > a:active { + background-color: transparent; } - -.navbar-default .navbar-right > li.dropdown:hover > a, -.navbar-default .navbar-right > li.dropdown > a:hover, -.navbar-default .navbar-right > li.dropdown > a:focus, -.navbar-default .navbar-right > li.dropdown > a:active { +/* Styling for opened submenu dropdowns - order matters */ +.navbar-default .navbar-nav > li.open > a, +.navbar-default .navbar-nav > li.open > a:focus, +.navbar-default .navbar-nav > li.open > a:active { color: #064785; background-color: white; } +@media (hover: hover) { + /* Styling for hovering over menu items - order matters */ + .navbar-default .navbar-nav > li.dropdown:hover > a, + .navbar-default .navbar-nav > li.dropdown > a:hover { + color: #064785; + background-color: white; + } +} +/* Styling for chevron icon to toggle collapsible navigation bar */ +.navbar-default .navbar-toggle:hover, +.navbar-default .navbar-toggle:focus { + background-color: #064785; +} -/* Submenu items*/ +/* Submenu items */ .dropdown-menu { padding: 5px 1px; border-top-color: transparent !important; box-shadow: 6px 8px 8px 1px rgba(0,0,0,0.175); } +/* For mobile and tablet, submenu items */ +@media (max-width: 991px) { + .dropdown-menu { + padding: 0px; + border-top-color: transparent !important; + } +} .dropdown-menu > .active > a, .dropdown-menu > .active > a:hover { color: #246EB6; @@ -112,6 +143,8 @@ Note: other colors are currenly inherited from Bootstrap default color palette cursor: pointer; } +/* Styling for right hand side of nav bar */ + /* Question mark */ .nav > li > a > img { padding-bottom: 3px; @@ -122,10 +155,21 @@ Note: other colors are currenly inherited from Bootstrap default color palette padding: 5px 8px; } -.navbar-default .navbar-right > li:hover > a, -.navbar-default .navbar-right > li > a:hover, +/* Styling for clicking on menu items */ .navbar-default .navbar-right > li > a:focus, -.navbar-default .navbar-right > li > a:active{ +.navbar-default .navbar-right > li > a:active { + background-color: transparent; +} +/* Styling for clicking on Question mark - order matters */ +.navbar-default .navbar-right > li > a.help-open, +.navbar-default .navbar-right > li > a.help-open:focus, +.navbar-default .navbar-right > li > a.help-open:active { + color: white; + background-color: #246EB6; +} +/* Styling for hovering over menu items - order matters */ +.navbar-default .navbar-right > li:hover > a, +.navbar-default .navbar-right > li > a:hover { color: white; background-color: #246EB6; } diff --git a/htdocs/js/helpHandler.js b/htdocs/js/helpHandler.js index dafbb274dbe..72895ce9b86 100644 --- a/htdocs/js/helpHandler.js +++ b/htdocs/js/helpHandler.js @@ -7,6 +7,11 @@ $(document).ready(function() { $('.wrapper').toggleClass('active'); }); $('.help-button').click(function(e) { + if ($(this).hasClass('help-open')) { + $(this).removeClass('help-open'); + } else { + $(this).addClass('help-open'); + } let helpContent = $('div.help-content'); if (helpContent.length) { helpContent.toggle(); @@ -68,6 +73,7 @@ $(document).ready(function() { $(div).addClass('visible'); btn.addEventListener('click', function(e) { $(div).hide(); + $('.help-button').removeClass('help-open'); e.preventDefault(); }); e.preventDefault(); diff --git a/htdocs/main.css b/htdocs/main.css index 0c6f50c82ad..4385f6a587a 100644 --- a/htdocs/main.css +++ b/htdocs/main.css @@ -33,7 +33,6 @@ html, body { #page { min-height: 100vh; position: relative; - padding-top: 50px; } diff --git a/smarty/templates/main.tpl b/smarty/templates/main.tpl index 3ed7183d018..4a0a8f7f5fc 100644 --- a/smarty/templates/main.tpl +++ b/smarty/templates/main.tpl @@ -47,6 +47,17 @@ html: true, container: 'body' }); + + // Make Navigation bar toggle change glyphicon up/down + $('.nav-button').on("click", function() { + if ($(this).hasClass('collapsed')) { + // change chevron to up + $('.toggle-icon').removeClass('glyphicon-chevron-down').addClass('glyphicon-chevron-up'); + } else { + // change chevron to down + $('.toggle-icon').removeClass('glyphicon-chevron-up').addClass('glyphicon-chevron-down'); + } + }); }); @@ -67,12 +78,12 @@
{if $dynamictabs neq "dynamictabs"} -