Custom Menu Items for New UI

  This idea has been developed and deployed to Canvas

 

  Idea open for vote Wed. January 6, 2016 - Wed. April 6, 2016  Learn more about voting...

 

I have had discussions with a number of institutions looking for a way to add custom items to the left hand navigation in the new UI.

Adding custom menu items

Additional Navigation Menu Item

Re: Has anyone been working on scripts for the new Beta UI? 

Like these schools, we have some items we have customized for our faculty and students that we would like to bring over to the new UI.

137362_Screen Shot 2015-12-03 at 10.36.47 AM.pngScreen Shot 2015-12-03 at 10.36.47 AM.png

I have created some JavaScript code to add an individual item, but it would be great if there was a way to add an item that had a slide out list like the other navigation items in Canvas

137363_Screen Shot 2015-12-03 at 10.41.38 AM.pngScreen Shot 2015-12-03 at 10.41.38 AM.png

The icing on the cake would also be the ability for the navigation to be targeted to a user's roles (additional resources for teachers verses resources for students) and if there was a way to choose an icon.

 

I understand that there is limited space in the left navigation for smaller screen sizes, but this would be a wonderful addition to the existing customization options in the new UI.

 

 

  

  Comments from Instructure

 

For more information, please read through the Canvas Production Release Notes (2016-08-27)

114 Comments
petermarchetti
Community Novice

Hi  @tfullwood thanks for your work on this, it's been really useful!

Just a quick question on the react try by role - As admins we are trying to cut down on the amount of clicking around we are doing when trying to find students when they call for support (click on the admin icon from wherever you are, click on the org name, click on users, find search box, click, click click etc) by adding an all users fly out from the menu. I believe there was a feature request about making the admin menu item more useful (can't find the feature request for the life of me at the moment) but until then we were hoping to have an "admin only" item modified from your js code.

I used your js from github for the react tray by role, modified it so that it would show an all users icon and have a link to the user list on the flyout, and removed the "else if" conditions for user roles after admins which worked perfectly...admins see the menu item, all other users do not. However, it seemed to throw up various different issues for non-admin users including but not limited to, inbox not loading in the page, speedgrader not loading in page, and students unable to submit work. Removing the js reverted the issues.

I suspect that removing the else if conditions meant that pages are struggling to display certain items (for users with non admin roles). Not sure why. Is there a mod that I can make to the following that says ok if you are an admin then show the icon in the menu, else if you are a teacher, student, observer, etc don't show it?

Current section of code modified:

$(document).ready(function() {

  if(ENV.current_user_roles.indexOf('admin') >= 0){

  var trayLinks = [

  {key: 'http:OURDOMAIN.instructure.com/accounts/1/users', val: 'All users'},

  ];

  }

  var slide_out_title = "All users"

  var global_nav_name = "All users"

tfullwood
Instructure
Instructure

Hey  @petermarchetti ​

If you would like to only display the menu to your admins I'd recommend wrapping the entire block with the if statement that checks if it's an admin (if(ENV.current_user_roles.indexOf('admin') >= 0){).

So it would look something like this:

$(document).ready(function() {

  if(ENV.current_user_roles.indexOf('admin') >= 0){

    var trayLinks = [

      {key: 'http:OURDOMAIN.instructure.com/accounts/1/users', val: 'All users'}

    ];

    var slide_out_title = "All users"

    var global_nav_name = "All users"

   

    //Everything else

  }

});

petermarchetti
Community Novice

Thanks for the pointers  @tfullwood ​ and please forgive the lateness of my reply - only just getting some Canvas time now. Not sure what "//Everything else" is I'm afraid. The rest of the js was pretty much as in your Github js.

When I implemented the js from github the changes I made were to remove the else if statements (from lines 10 down to 23) and editing the icon class (from icon-resources to icon-search (line 92 and line 103  - also modified the css to accommodate the use of a different icon). Worked perfectly for admins but brought up issues for any other role type.

The full js that I have for this functionality is at the end of my custom js and, in full, is below. Could you annotate to suggest where I would wrap this? The net result desired is that it checks what the role is, if it is admin then it adds an additional menu item with a link to search all users, if they are anything else then it does not add the additional menu item. While it did do this, the code below also messed with a lot of other functionality for non admin users.

$(document).ready(function() {

  if(ENV.current_user_roles.indexOf('admin') >= 0){

  //items to show to admins

  var trayLinks = [

  {key: 'http:OURDOMAIN.instructure.com/accounts/1/users', val: 'All users'},

  ];

  }

  var slide_out_title = "All users" //Changes the title on the slide out menu

  var global_nav_name = "All users" //Change the title on the global navigation menu

  var footerContent = 'Footer text area. Put whatever you want here.'; //Changes the text of the bottom on the slide out tray

  ////////////////////////////////////////////////////////////////////////////////

  //DO NOT EDIT ANYTHING BELOW THIS LINE!

  ////////////////////////////////////////////////////////////////////////////////

  //Browser Detection

  navigator.agentDetect = (function(){

     var ua= navigator.userAgent, tem,

     M= ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];

     if(/trident/i.test(M[1])){

         tem=  /\brv[ :]+(\d+)/g.exec(ua) || [];

         return 'IE '+(tem[1] || '');

     }

     if(M[1]=== 'Chrome'){

         tem= ua.match(/\b(OPR|Edge)\/(\d+)/);

         if(tem!= null) return tem.slice(1).join(' ').replace('OPR', 'Opera');

     }

     M= M[2]? [M[1], M[2]]: [navigator.appName, navigator.appVersion, '-?'];

     if((tem= ua.match(/version\/(\d+)/i))!= null) M.splice(1, 1, tem[1]);

     return M;

  })();

  //Array, 0 = browser, 1 = version

  var agent = navigator.agentDetect;

  var reactId;

  switch(agent[0]) {

     case "Firefox":

         reactId = "2";

         break;

     case "Safari":

         reactId = "2";

         break;

     default:

         reactId = "1";

         break;

  }

  var displayVals = '';

  function displayLinks(element, index, array) {

  displayVals += '<li>';

  displayVals += '<a href="' + element.key + '">' + element.val + '</a>';

  displayVals += '</li>';

  }

  trayLinks.forEach(displayLinks);

  var trayHtml = '<div style="position:absolute;background:#fff;" class="ReactTray__Content ReactTray__Content--after-open " tabindex="-1" data-reactid=".' +

   reactId + '.0"><div class="ReactTray__layout" data-reactid=".' +

   reactId + '.0.0"><div class="ReactTray__primary-content" data-reactid=".' +

   reactId + '.0.0.0"><div class="ReactTray__header" data-reactid=".' +

   reactId + '.0.0.0.0"><h1 class="ReactTray__headline" data-reactid=".' +

   reactId + '.0.0.0.0.0">' +

   slide_out_title + '</h1><button class="Button Button--icon-action ReactTray__closeBtn" type="button" data-reactid=".' +

   reactId + '.0.0.0.0.1"><i class="icon-x" data-reactid=".' +

   reactId + '.0.0.0.0.1.0"></i><span class="screenreader-only" data-reactid=".' +

   reactId + '.0.0.0.0.1.1">Close</span></button></div><ul class="ReactTray__link-list" data-reactid=".' +

   reactId + '.0.0.0.1">' +

   displayVals + '</ul></div><div class="ReactTray__secondary-content" data-reactid=".' +

   reactId + '.0.0.1"><div class="ReactTray__info-box" data-reactid=".' +

   reactId + '.0.0.1.0">' +

   footerContent + '</div></div></div></div>' +

   '<script>$(\'.Button.Button--icon-action.ReactTray__closeBtn, .Button.Button--icon-action.ReactTray__closeBtn .icon-x\').click(function () {$(\'.ReactTrayPortal div\').removeAttr(\'style\');$(\'.ReactTrayPortal div\').removeAttr(\'class\');$(\'.ReactTrayPortal div\').html("");$(\'#menu, .menu-item.ic-app-header__menu-list-item a\').removeClass(\'ui-state-disabled\').removeAttr(\'disabled\');$(\'#customTrayOverlay\').hide();$(\'#custom_nav\').css(\'background-color\', \'\');$(\'.icon-search\').css(\'color\', \'#fff\');});</script>';

  trayHtml = trayHtml.replace(/(?:\r\n|\r|\n|  )/g, '');

  var menu = $('#menu');

  if (!menu.length) return;

  var custom_nav = $('<li/>', {

  'id': 'custom_nav',

  'class': 'menu-item ic-app-header__menu-list-item',

  html: '<a id="global_nav_resources_link" href="javascript:void(0)" class="ic-app-header__menu-list-link">' +

  '<div class="menu-item-icon-container" aria-hidden="true">' +

  '<i class="icon-search"></i>' +

  '<div class="menu-item__text">' + global_nav_name + '</div>' +

  '</div></a></li>'

  });

  menu.append(custom_nav);

  $('body').append('<div id="customTrayOverlay" style="width:' + $('#menu').width() + 'px;height: ' + $('#menu').height() + 'px;;left: 0;top: 87px;z-index: 999;display:none;"></div>');

  $('#global_nav_resources_link').click(function () {

  $('.ReactTrayPortal div').addClass('ReactTray__Overlay ReactTray__Overlay--after-open');

  $('.ReactTrayPortal div').css({

  'position' : 'fixed',

  'top' : '0px',

  'left': '0px',

  'right' : '0px',

  'bottom': '0px'

  });

  $('.ReactTrayPortal div').append(trayHtml);

  $('#menu, .menu-item.ic-app-header__menu-list-item a').addClass('ui-state-disabled').attr('disabled', 'disabled');

  $('#customTrayOverlay').show();

  $('#custom_nav').css('background-color', '#fff');

  });

});

tfullwood
Instructure
Instructure

Hey  @petermarchetti ​

Sorry for the delay. It's that time of year when things get a bit crazy.

Since you posted this we've released the beta notes, Canvas Beta Release Notes (2016-08-15).​​ There is some good news with this release. The updatable menu links feature should make this JS script unnecessary. If you don't think this feature will fit your needs let me know and I can take a look through your script in more detail.

Renee_Carney
Community Team
Community Team
  This idea has been developed and deployed to Canvas

For more information, please read through the Canvas Production Release Notes (2016-08-27)

powellj
Community Participant

I'm not seeing anything in the Release Notes about the ability to add a custom menu? The only changes I'm seeing are for the Help Menu, but that's not what this Idea was about?

kenneth_larsen
Community Champion

 @powellj , what functionality are you looking for that this release doesn't cover? Aside from the fact that it is merged into the Help Menu rather than being a separate item, this feature meets all of the criteria I included when I suggested this idea. It even includes the "icing on the cake" of being able to target a link based on the user's role. I don't view the merge with the help menu as a bad thing because it gives the ability to change the name from "Help" to whatever you want. In my opinion, this simplifies the left navigation by allowing me to group all of our custom resources and support links into one menu.

sadenniston
Community Contributor

This update is very helpful, but how does one change the Help to something else? As I will be putting non-help links in there, I don’t want the title of the menu to be misleading.

Cheers

kenneth_larsen
Community Champion

At the moment this can only be done in your beta instance of Canvas, but when you open the Help menu you will see a link that says "Customize this menu"

2016-08-23_19-55-16.png

This link takes you to the account navigation where you can adjust the name and icon for the help menu as well as add in additional links, change link order and so on.

Screen Shot 2016-08-23 at 7.56.13 PM.png

powellj
Community Participant

Hi  @kenneth_larsen ​, thanks for your reply! When you stated, "Aside from the fact that it is merged into the Help Menu rather than being a separate item" - that summed it up exactly. We heavily promote the use of the existing Help menu for all our users as we have higher tier support. However, we previously had a custom menu in the old UI for "TCC Resources", which linked to a few common systems at the College which was also heavily used by both faculty and students. So merging the two into one provided me with little benefit. Not a big deal, since it sounds like it was right on the mark for most people, I was just thoroughly confused as I was expecting one thing from this Idea and received another. Smiley Happy Disappointed, but c'est la vie!

Jacci