PageRenderTime 57ms CodeModel.GetById 7ms RepoModel.GetById 0ms app.codeStats 0ms

/client/galaxy/scripts/layout/menu.js

https://bitbucket.org/galaxy/galaxy-central/
JavaScript | 399 lines | 350 code | 17 blank | 32 comment | 46 complexity | 7e56d3ad7c747b9b4d4a65278f1adfcd MD5 | raw file
Possible License(s): CC-BY-3.0
  1. /** Masthead Collection **/
  2. define(['mvc/tours'], function( Tours ) {
  3. var Collection = Backbone.Collection.extend({
  4. model: Backbone.Model.extend({
  5. defaults: {
  6. visible : true,
  7. target : '_parent'
  8. }
  9. }),
  10. fetch: function( options ){
  11. options = options || {};
  12. this.reset();
  13. //
  14. // Analyze data tab.
  15. //
  16. this.add({
  17. id : 'analysis',
  18. title : 'Analyze Data',
  19. url : '',
  20. tooltip : 'Analysis home view'
  21. });
  22. //
  23. // Workflow tab.
  24. //
  25. this.add({
  26. id : 'workflow',
  27. title : 'Workflow',
  28. url : 'workflow',
  29. tooltip : 'Chain tools into workflows',
  30. disabled : !Galaxy.user.id
  31. });
  32. //
  33. // 'Shared Items' or Libraries tab.
  34. //
  35. this.add({
  36. id : 'shared',
  37. title : 'Shared Data',
  38. url : 'library/index',
  39. tooltip : 'Access published resources',
  40. menu : [{
  41. title : 'Data Libraries deprecated',
  42. url : 'library/index'
  43. },{
  44. title : 'Data Libraries',
  45. url : 'library/list',
  46. divider : true
  47. },{
  48. title : 'Published Histories',
  49. url : 'history/list_published'
  50. },{
  51. title : 'Published Workflows',
  52. url : 'workflow/list_published'
  53. },{
  54. title : 'Published Visualizations',
  55. url : 'visualization/list_published'
  56. },{
  57. title : 'Published Pages',
  58. url : 'page/list_published'
  59. }]
  60. });
  61. //
  62. // Lab menu.
  63. //
  64. options.user_requests && this.add({
  65. id : 'lab',
  66. title : 'Lab',
  67. menu : [{
  68. title : 'Sequencing Requests',
  69. url : 'requests/index'
  70. },{
  71. title : 'Find Samples',
  72. url : 'requests/find_samples_index'
  73. },{
  74. title : 'Help',
  75. url : options.lims_doc_url
  76. }]
  77. });
  78. //
  79. // Visualization tab.
  80. //
  81. this.add({
  82. id : 'visualization',
  83. title : 'Visualization',
  84. url : 'visualization/list',
  85. tooltip : 'Visualize datasets',
  86. disabled : !Galaxy.user.id,
  87. menu : [{
  88. title : 'New Track Browser',
  89. url : 'visualization/trackster',
  90. target : '_frame'
  91. },{
  92. title : 'Saved Visualizations',
  93. url : 'visualization/list',
  94. target : '_frame'
  95. }]
  96. });
  97. //
  98. // Admin.
  99. //
  100. Galaxy.user.get( 'is_admin' ) && this.add({
  101. id : 'admin',
  102. title : 'Admin',
  103. url : 'admin',
  104. tooltip : 'Administer this Galaxy',
  105. cls : 'admin-only'
  106. });
  107. //
  108. // Help tab.
  109. //
  110. var helpTab = {
  111. id : 'help',
  112. title : 'Help',
  113. tooltip : 'Support, contact, and community hubs',
  114. menu : [{
  115. title : 'Support',
  116. url : options.support_url,
  117. target : '_blank'
  118. },{
  119. title : 'Search',
  120. url : options.search_url,
  121. target : '_blank'
  122. },{
  123. title : 'Mailing Lists',
  124. url : options.mailing_lists,
  125. target : '_blank'
  126. },{
  127. title : 'Videos',
  128. url : options.screencasts_url,
  129. target : '_blank'
  130. },{
  131. title : 'Wiki',
  132. url : options.wiki_url,
  133. target : '_blank'
  134. },{
  135. title : 'How to Cite Galaxy',
  136. url : options.citation_url,
  137. target : '_blank'
  138. },{
  139. title : 'Interactive Tours',
  140. onclick : function(c){
  141. Galaxy.app.display(new Tours.ToursView());
  142. },
  143. target : 'galaxy_main'
  144. }]
  145. };
  146. options.terms_url && helpTab.menu.push({
  147. title : 'Terms and Conditions',
  148. url : options.terms_url,
  149. target : '_blank'
  150. });
  151. options.biostar_url && helpTab.menu.unshift({
  152. title : 'Ask a question',
  153. url : 'biostar/biostar_question_redirect',
  154. target : '_blank'
  155. });
  156. options.biostar_url && helpTab.menu.unshift({
  157. title : 'Galaxy Biostar',
  158. url : options.biostar_url_redirect,
  159. target : '_blank'
  160. });
  161. this.add( helpTab );
  162. //
  163. // User tab.
  164. //
  165. if ( !Galaxy.user.id ){
  166. var userTab = {
  167. id : 'user',
  168. title : 'User',
  169. cls : 'loggedout-only',
  170. tooltip : 'Account registration or login',
  171. menu : [{
  172. title : 'Login',
  173. url : 'user/login',
  174. target : 'galaxy_main'
  175. }]
  176. };
  177. options.allow_user_creation && userTab.menu.push({
  178. title : 'Register',
  179. url : 'user/create',
  180. target : 'galaxy_main'
  181. });
  182. this.add( userTab );
  183. } else {
  184. var userTab = {
  185. id : 'user',
  186. title : 'User',
  187. cls : 'loggedin-only',
  188. tooltip : 'Account preferences and saved data',
  189. menu : [{
  190. title : 'Logged in as ' + Galaxy.user.get( 'email' )
  191. },{
  192. title : 'Preferences',
  193. url : 'user?cntrller=user',
  194. target : 'galaxy_main'
  195. },{
  196. title : 'Custom Builds',
  197. url : 'user/dbkeys',
  198. target : 'galaxy_main'
  199. },{
  200. title : 'Logout',
  201. url : 'user/logout',
  202. target : '_top',
  203. divider : true
  204. },{
  205. title : 'Saved Histories',
  206. url : 'history/list',
  207. target : 'galaxy_main'
  208. },{
  209. title : 'Saved Datasets',
  210. url : 'dataset/list',
  211. target : 'galaxy_main'
  212. },{
  213. title : 'Saved Pages',
  214. url : 'page/list',
  215. target : '_top'
  216. },{
  217. title : 'API Keys',
  218. url : 'user/api_keys?cntrller=user',
  219. target : 'galaxy_main'
  220. }]
  221. };
  222. options.use_remote_user && userTab.menu.push({
  223. title : 'Public Name',
  224. url : 'user/edit_username?cntrller=user',
  225. target : 'galaxy_main'
  226. });
  227. this.add( userTab );
  228. }
  229. var activeView = this.get( options.active_view );
  230. activeView && activeView.set( 'active', true );
  231. return new jQuery.Deferred().resolve().promise();
  232. }
  233. });
  234. /** Masthead tab **/
  235. var Tab = Backbone.View.extend({
  236. initialize: function ( options ) {
  237. var self = this;
  238. this.setElement( this._template() );
  239. this.$dropdown = this.$( '.dropdown' );
  240. this.$toggle = this.$( '.dropdown-toggle' );
  241. this.$menu = this.$( '.dropdown-menu' );
  242. this.$note = this.$( '.dropdown-note' );
  243. this.model = options.model;
  244. this.$el.attr( 'id', this.model.id );
  245. this.model.on( 'init change:title', function() {
  246. this.get( 'title' ) && self.$toggle.html( this.get( 'title' ) );
  247. }).on( 'init change:visible', function() {
  248. self.$el.css( { visibility : this.get( 'visible' ) && 'visible' || 'hidden' } );
  249. }).on( 'init change:note', function() {
  250. self.$note.html( this.get( 'note' ) );
  251. }).on( 'init change:note_cls', function() {
  252. this._prevNoteCls && self.$note.removeClass( this._prevNoteCls );
  253. this.get( 'note_cls' ) && self.$note.addClass( this._prevNoteCls = this.get( 'note_cls' ) );
  254. }).on( 'init change:show_note', function() {
  255. self.$note.css( { 'display' : this.get( 'show_note' ) && 'block' || 'none' } );
  256. }).on( 'init change:target', function() {
  257. self.$toggle.attr( 'target', this.get( 'target' ) );
  258. }).on( 'init change:url', function() {
  259. this.set( 'url', self._formatUrl( this.get( 'url' ) ) );
  260. self.$toggle.attr( 'href', this.get( 'url' ) );
  261. }).on( 'init change:tooltip', function() {
  262. $( '.tooltip' ).remove();
  263. self.$toggle.tooltip( 'destroy' ).attr( 'title', this.get( 'tooltip' ) );
  264. this.get( 'tooltip' ) && self.$toggle.tooltip( { placement: 'bottom' } );
  265. }).on( 'init change:cls', function() {
  266. this._prevCls && self.$toggle.removeClass( this._prevCls );
  267. this.get( 'cls' ) && self.$toggle.addClass( this._prevCls = this.get( 'cls' ) );
  268. }).on( 'init change:icon', function() {
  269. this._prevIcon && self.$toggle.removeClass( this._prevIcon );
  270. this.get( 'icon' ) && self.$toggle.addClass( this._prevIcon = 'fa fa-2x ' + this.get( 'icon' ) );
  271. }).on( 'init change:toggle', function() {
  272. self.$toggle[ this.get( 'toggle' ) && 'addClass' || 'removeClass' ]( 'toggle' );
  273. }).on( 'init change:disabled', function() {
  274. self.$dropdown[ this.get( 'disabled' ) && 'addClass' || 'removeClass' ]( 'disabled' );
  275. self._configurePopover();
  276. }).on( 'init change:active', function() {
  277. self.$dropdown[ this.get( 'active' ) && 'addClass' || 'removeClass' ]( 'active' );
  278. }).on( 'init change:show_menu', function() {
  279. if ( this.get( 'menu' ) && this.get( 'show_menu' ) ) {
  280. self.$menu.show();
  281. $( '#dd-helper' ).show().off().on( 'click', function() {
  282. $( '#dd-helper' ).hide();
  283. self.model.set( 'show_menu', false );
  284. });
  285. } else {
  286. self.$menu.hide();
  287. $( '#dd-helper' ).hide();
  288. }
  289. }).on( 'init change:menu', function() {
  290. self.$menu.empty().removeClass( 'dropdown-menu' );
  291. self.$toggle.find( 'b' ).remove();
  292. if ( this.get( 'menu' ) ) {
  293. _.each( this.get( 'menu' ), function( menuItem ) {
  294. self.$menu.append( self._buildMenuItem( menuItem ) );
  295. menuItem.divider && self.$menu.append( $( '<li/>' ).addClass( 'divider' ) );
  296. });
  297. self.$menu.addClass( 'dropdown-menu' );
  298. self.$toggle.append( $( '<b/>' ).addClass( 'caret' ) );
  299. }
  300. }).trigger( 'init' );
  301. },
  302. /** Attach events */
  303. events: {
  304. 'click .dropdown-toggle' : '_toggleClick'
  305. },
  306. /** Add new menu item */
  307. _buildMenuItem: function ( options ) {
  308. var self = this;
  309. options = _.defaults( options || {}, {
  310. title : '',
  311. url : '',
  312. target : '_parent'
  313. });
  314. options.url = self._formatUrl( options.url );
  315. return $( '<li/>' ).append(
  316. $( '<a/>' ).attr( 'href', options.url )
  317. .attr( 'target', options.target )
  318. .html( options.title )
  319. .on( 'click', function( e ) {
  320. e.preventDefault();
  321. self.model.set( 'show_menu', false );
  322. if (options.onclick){
  323. options.onclick();
  324. } else {
  325. Galaxy.frame.add( options );
  326. }
  327. })
  328. );
  329. },
  330. /** Handle click event */
  331. _toggleClick: function( e ) {
  332. var self = this;
  333. var model = this.model;
  334. e.preventDefault();
  335. $( '.tooltip' ).hide();
  336. model.trigger( 'dispatch', function( m ) {
  337. model.id !== m.id && m.get( 'menu' ) && m.set( 'show_menu', false );
  338. });
  339. if ( !model.get( 'disabled' ) ) {
  340. if ( !model.get( 'menu' ) ) {
  341. model.get( 'onclick' ) ? model.get( 'onclick' )() : Galaxy.frame.add( model.attributes );
  342. } else {
  343. model.set( 'show_menu', true );
  344. }
  345. }
  346. },
  347. /** Configures login notification/popover */
  348. _configurePopover: function() {
  349. var self = this;
  350. function buildLink( label, url ) {
  351. return $( '<div/>' ).append( $( '<a/>' ).attr( 'href', Galaxy.root + url ).html( label ) ).html()
  352. }
  353. this.$toggle.popover && this.$toggle.popover( 'destroy' );
  354. this.model.get( 'disabled' ) && this.$toggle.popover({
  355. html : true,
  356. placement : 'bottom',
  357. content : 'Please ' + buildLink( 'login', 'user/login?use_panels=True' ) + ' or ' +
  358. buildLink( 'register', 'user/create?use_panels=True' ) + ' to use this feature.'
  359. }).on( 'shown.bs.popover', function() {
  360. setTimeout( function() { self.$toggle.popover( 'hide' ) }, 5000 );
  361. });
  362. },
  363. /** Url formatting */
  364. _formatUrl: function( url ) {
  365. return typeof url == 'string' && url.indexOf( '//' ) === -1 && url.charAt( 0 ) != '/' ? Galaxy.root + url : url;
  366. },
  367. /** body tempate */
  368. _template: function () {
  369. return '<ul class="nav navbar-nav">' +
  370. '<li class="dropdown">' +
  371. '<a class="dropdown-toggle"/>' +
  372. '<ul class="dropdown-menu"/>' +
  373. '<div class="dropdown-note"/>' +
  374. '</li>' +
  375. '</ul>';
  376. }
  377. });
  378. return {
  379. Collection : Collection,
  380. Tab : Tab
  381. };
  382. });