diff options
Diffstat (limited to 'server/sonar-web/src/main/js/app/components/nav/global')
8 files changed, 169 insertions, 148 deletions
diff --git a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.js b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.js index d4a04a25860..ef83aed3921 100644 --- a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.js +++ b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.js @@ -27,11 +27,11 @@ import ShortcutsHelpView from './ShortcutsHelpView'; import { getCurrentUser, getAppState } from '../../../../store/rootReducer'; class GlobalNav extends React.Component { - componentDidMount () { + componentDidMount() { window.addEventListener('keypress', this.onKeyPress); } - componentWillUnmount () { + componentWillUnmount() { window.removeEventListener('keypress', this.onKeyPress); } @@ -53,25 +53,25 @@ class GlobalNav extends React.Component { new ShortcutsHelpView().render(); }; - render () { + render() { return ( - <nav className="navbar navbar-global page-container" id="global-navigation"> - <div className="container"> - <GlobalNavBranding/> + <nav className="navbar navbar-global page-container" id="global-navigation"> + <div className="container"> + <GlobalNavBranding /> - <GlobalNavMenu {...this.props}/> + <GlobalNavMenu {...this.props} /> - <ul className="nav navbar-nav navbar-right"> - <GlobalNavUser {...this.props}/> - <GlobalNavSearch {...this.props}/> - <li> - <a onClick={this.openHelp} href="#"> - <i className="icon-help navbar-icon"/> - </a> - </li> - </ul> - </div> - </nav> + <ul className="nav navbar-nav navbar-right"> + <GlobalNavUser {...this.props} /> + <GlobalNavSearch {...this.props} /> + <li> + <a onClick={this.openHelp} href="#"> + <i className="icon-help navbar-icon" /> + </a> + </li> + </ul> + </div> + </nav> ); } } diff --git a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavBranding.js b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavBranding.js index a1f73443ea2..8e6dd891305 100644 --- a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavBranding.js +++ b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavBranding.js @@ -29,23 +29,22 @@ class GlobalNavBranding extends React.Component { customLogoWidth: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]) }; - renderLogo () { + renderLogo() { const url = this.props.customLogoUrl || `${window.baseUrl}/images/logo.svg`; const width = this.props.customLogoWidth || 100; const height = 30; const title = translate('layout.sonar.slogan'); - return ( - <img src={url} width={width} height={height} alt={title} title={title}/> - ); + return <img src={url} width={width} height={height} alt={title} title={title} />; } - render () { + render() { const homeController = this.props.currentUser.isLoggedIn ? '/projects' : '/about'; - const homeLinkClassName = 'navbar-brand' + (this.props.customLogoUrl ? ' navbar-brand-custom' : ''); + const homeLinkClassName = 'navbar-brand' + + (this.props.customLogoUrl ? ' navbar-brand-custom' : ''); return ( - <div className="navbar-header"> - <Link to={homeController} className={homeLinkClassName}>{this.renderLogo()}</Link> - </div> + <div className="navbar-header"> + <Link to={homeController} className={homeLinkClassName}>{this.renderLogo()}</Link> + </div> ); } } diff --git a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavMenu.js b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavMenu.js index 3693e493fcf..b1e556af9d0 100644 --- a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavMenu.js +++ b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavMenu.js @@ -33,112 +33,114 @@ export default class GlobalNavMenu extends React.Component { globalPages: [] }; - activeLink (url) { + activeLink(url) { return window.location.pathname.indexOf(window.baseUrl + url) === 0 ? 'active' : null; } - renderProjects () { + renderProjects() { return ( - <li> - <Link to="/projects" activeClassName="active"> - {translate('projects.page')} - </Link> - </li> + <li> + <Link to="/projects" activeClassName="active"> + {translate('projects.page')} + </Link> + </li> ); } - renderIssuesLink () { - const query = this.props.currentUser.isLoggedIn ? '#resolved=false|assigned_to_me=true' : '#resolved=false'; + renderIssuesLink() { + const query = this.props.currentUser.isLoggedIn + ? '#resolved=false|assigned_to_me=true' + : '#resolved=false'; const url = '/issues' + query; return ( - <li> - <Link to={url} className={this.activeLink('/issues')}> - {translate('issues.page')} - </Link> - </li> + <li> + <Link to={url} className={this.activeLink('/issues')}> + {translate('issues.page')} + </Link> + </li> ); } - renderRulesLink () { + renderRulesLink() { return ( - <li> - <Link to="/coding_rules" className={this.activeLink('/coding_rules')}> - {translate('coding_rules.page')} - </Link> - </li> + <li> + <Link to="/coding_rules" className={this.activeLink('/coding_rules')}> + {translate('coding_rules.page')} + </Link> + </li> ); } - renderProfilesLink () { + renderProfilesLink() { return ( - <li> - <Link to="/profiles" activeClassName="active"> - {translate('quality_profiles.page')} - </Link> - </li> + <li> + <Link to="/profiles" activeClassName="active"> + {translate('quality_profiles.page')} + </Link> + </li> ); } - renderQualityGatesLink () { + renderQualityGatesLink() { return ( - <li> - <Link to="/quality_gates" activeClassName="active"> - {translate('quality_gates.page')} - </Link> - </li> + <li> + <Link to="/quality_gates" activeClassName="active"> + {translate('quality_gates.page')} + </Link> + </li> ); } - renderAdministrationLink () { + renderAdministrationLink() { if (!isUserAdmin(this.props.currentUser)) { return null; } return ( - <li> - <Link to="/settings" className="navbar-admin-link" activeClassName="active"> - {translate('layout.settings')} - </Link> - </li> + <li> + <Link to="/settings" className="navbar-admin-link" activeClassName="active"> + {translate('layout.settings')} + </Link> + </li> ); } renderGlobalPageLink = ({ key, name }) => { return ( - <li key={key}> - <Link to={`/extension/${key}`}>{name}</Link> - </li> + <li key={key}> + <Link to={`/extension/${key}`}>{name}</Link> + </li> ); }; - renderMore () { + renderMore() { const { globalPages } = this.props.appState; if (globalPages.length === 0) { return null; } return ( - <li className="dropdown"> - <a className="dropdown-toggle" id="global-navigation-more" data-toggle="dropdown" href="#"> - {translate('more')} - <span className="icon-dropdown"/> - </a> - <ul className="dropdown-menu"> - {globalPages.map(this.renderGlobalPageLink)} - </ul> - </li> + <li className="dropdown"> + <a className="dropdown-toggle" id="global-navigation-more" data-toggle="dropdown" href="#"> + {translate('more')} + <span className="icon-dropdown" /> + </a> + <ul className="dropdown-menu"> + {globalPages.map(this.renderGlobalPageLink)} + </ul> + </li> ); } - render () { + render() { return ( - <ul className="nav navbar-nav"> - {this.renderProjects()} - {this.renderIssuesLink()} - {this.renderRulesLink()} - {this.renderProfilesLink()} - {this.renderQualityGatesLink()} - {this.renderAdministrationLink()} - {this.renderMore()} - </ul> + <ul className="nav navbar-nav"> + {this.renderProjects()} + {this.renderIssuesLink()} + {this.renderRulesLink()} + {this.renderProfilesLink()} + {this.renderQualityGatesLink()} + {this.renderAdministrationLink()} + {this.renderMore()} + </ul> ); } } diff --git a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavSearch.js b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavSearch.js index fdcb24c2881..2b5aa6ccf63 100644 --- a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavSearch.js +++ b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavSearch.js @@ -23,7 +23,7 @@ import { connect } from 'react-redux'; import SearchView from './SearchView'; import { getCurrentUser } from '../../../../store/rootReducer'; -function contains (root, node) { +function contains(root, node) { while (node) { if (node === root) { return true; @@ -36,7 +36,7 @@ function contains (root, node) { class GlobalNavSearch extends React.Component { state = { open: false }; - componentDidMount () { + componentDidMount() { key('s', () => { const isModalOpen = document.querySelector('html').classList.contains('modal-open'); if (!isModalOpen) { @@ -46,7 +46,7 @@ class GlobalNavSearch extends React.Component { }); } - componentWillUnmount () { + componentWillUnmount() { this.closeSearch(); key.unbind('s'); } @@ -92,15 +92,18 @@ class GlobalNavSearch extends React.Component { } }; - render () { + render() { const dropdownClassName = 'dropdown' + (this.state.open ? ' open' : ''); return ( - <li ref="dropdown" className={dropdownClassName}> - <a className="navbar-search-dropdown" href="#" onClick={this.onClick}> - <i className="icon-search navbar-icon"/> <i className="icon-dropdown"/> - </a> - <div ref="container" className="dropdown-menu dropdown-menu-right global-navbar-search-dropdown"/> - </li> + <li ref="dropdown" className={dropdownClassName}> + <a className="navbar-search-dropdown" href="#" onClick={this.onClick}> + <i className="icon-search navbar-icon" /> <i className="icon-dropdown" /> + </a> + <div + ref="container" + className="dropdown-menu dropdown-menu-right global-navbar-search-dropdown" + /> + </li> ); } } diff --git a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavUser.js b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavUser.js index b8a5fe7c1df..57fda1a1492 100644 --- a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavUser.js +++ b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavUser.js @@ -49,35 +49,35 @@ class GlobalNavUser extends React.Component { this.props.router.push('/sessions/logout'); }; - renderAuthenticated () { + renderAuthenticated() { const { currentUser } = this.props; return ( - <li className="dropdown js-user-authenticated"> - <a className="dropdown-toggle" data-toggle="dropdown" href="#"> - <Avatar email={currentUser.email} size={20}/> - {currentUser.name} <i className="icon-dropdown"/> - </a> - <ul className="dropdown-menu dropdown-menu-right"> - <li> - <Link to="/account">{translate('my_account.page')}</Link> - </li> - <li> - <a onClick={this.handleLogout} href="#">{translate('layout.logout')}</a> - </li> - </ul> - </li> + <li className="dropdown js-user-authenticated"> + <a className="dropdown-toggle" data-toggle="dropdown" href="#"> + <Avatar email={currentUser.email} size={20} /> + {currentUser.name} <i className="icon-dropdown" /> + </a> + <ul className="dropdown-menu dropdown-menu-right"> + <li> + <Link to="/account">{translate('my_account.page')}</Link> + </li> + <li> + <a onClick={this.handleLogout} href="#">{translate('layout.logout')}</a> + </li> + </ul> + </li> ); } - renderAnonymous () { + renderAnonymous() { return ( - <li> - <a onClick={this.handleLogin} href="#">{translate('layout.login')}</a> - </li> + <li> + <a onClick={this.handleLogin} href="#">{translate('layout.login')}</a> + </li> ); } - render () { + render() { return this.props.currentUser.isLoggedIn ? this.renderAuthenticated() : this.renderAnonymous(); } } diff --git a/server/sonar-web/src/main/js/app/components/nav/global/SearchView.js b/server/sonar-web/src/main/js/app/components/nav/global/SearchView.js index cf711c889e8..e98a0397a3a 100644 --- a/server/sonar-web/src/main/js/app/components/nav/global/SearchView.js +++ b/server/sonar-web/src/main/js/app/components/nav/global/SearchView.js @@ -31,7 +31,10 @@ import { translate } from '../../../../helpers/l10n'; import { isUserAdmin } from '../../../../helpers/users'; import { getFavorites } from '../../../../api/favorites'; import { getSuggestions } from '../../../../api/components'; -import { getOrganization, areThereCustomOrganizations } from '../../../../store/organizations/utils'; +import { + getOrganization, + areThereCustomOrganizations +} from '../../../../store/organizations/utils'; type Finding = { name: string, @@ -45,19 +48,19 @@ const SearchItemView = Marionette.ItemView.extend({ tagName: 'li', template: SearchItemTemplate, - select () { + select() { this.$el.addClass('active'); }, - deselect () { + deselect() { this.$el.removeClass('active'); }, - submit () { + submit() { this.$('a')[0].click(); }, - onRender () { + onRender() { this.$('[data-toggle="tooltip"]').tooltip({ container: 'body', html: true, @@ -66,11 +69,11 @@ const SearchItemView = Marionette.ItemView.extend({ }); }, - onDestroy () { + onDestroy() { this.$('[data-toggle="tooltip"]').tooltip('destroy'); }, - serializeData () { + serializeData() { return { ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), index: this.options.index @@ -105,7 +108,7 @@ export default Marionette.LayoutView.extend({ 'keyup .js-search-input': 'onKeyUp' }, - initialize () { + initialize() { this.results = new Backbone.Collection(); this.favorite = []; if (this.model.get('currentUser').isLoggedIn) { @@ -121,15 +124,18 @@ export default Marionette.LayoutView.extend({ this._bufferedValue = ''; }, - onRender () { + onRender() { const that = this; this.resultsRegion.show(this.resultsView); - setTimeout(() => { - that.$('.js-search-input').focus(); - }, 0); + setTimeout( + () => { + that.$('.js-search-input').focus(); + }, + 0 + ); }, - onKeyDown (e) { + onKeyDown(e) { if (e.keyCode === 38) { this.resultsView.selectPrev(); return false; @@ -149,7 +155,7 @@ export default Marionette.LayoutView.extend({ } }, - onKeyUp () { + onKeyUp() { const value = this.$('.js-search-input').val(); if (value === this._bufferedValue) { return; @@ -158,18 +164,21 @@ export default Marionette.LayoutView.extend({ this.searchRequest = this.debouncedSearch(value); }, - onSubmit () { + onSubmit() { return false; }, - fetchFavorite (): Promise<*> { + fetchFavorite(): Promise<*> { const customOrganizations = areThereCustomOrganizations(); return getFavorites().then(r => { this.favorite = r.favorites.map(f => { const showOrganization = customOrganizations && f.organization != null; const organization = showOrganization ? getOrganization(f.organization) : null; return { - url: window.baseUrl + '/dashboard/index?id=' + encodeURIComponent(f.key) + window.dashboardParameters(true), + url: window.baseUrl + + '/dashboard/index?id=' + + encodeURIComponent(f.key) + + window.dashboardParameters(true), name: f.name, icon: 'favorite', organization @@ -179,12 +188,14 @@ export default Marionette.LayoutView.extend({ }); }, - resetResultsToDefault () { + resetResultsToDefault() { const recentHistory = RecentHistory.get(); const customOrganizations = areThereCustomOrganizations(); const history = recentHistory.map((historyItem, index) => { - const url = window.baseUrl + '/dashboard/index?id=' + encodeURIComponent(historyItem.key) + - window.dashboardParameters(true); + const url = window.baseUrl + + '/dashboard/index?id=' + + encodeURIComponent(historyItem.key) + + window.dashboardParameters(true); const showOrganization = customOrganizations && historyItem.organization != null; // $FlowFixMe flow doesn't check the above condition on `historyItem.organization != null` const organization = showOrganization ? getOrganization(historyItem.organization) : null; @@ -202,7 +213,7 @@ export default Marionette.LayoutView.extend({ this.results.reset([].concat(history, favorite)); }, - search (q) { + search(q) { if (q.length < 2) { this.resetResultsToDefault(); return; @@ -219,8 +230,9 @@ export default Marionette.LayoutView.extend({ const collection = []; r.results.forEach(({ items, q }) => { items.forEach((item, index) => { - const showOrganization = customOrganizations && item.organization != null && - SHOW_ORGANIZATION_FOR_QUALIFIERS.includes(q); + const showOrganization = customOrganizations && + item.organization != null && + SHOW_ORGANIZATION_FOR_QUALIFIERS.includes(q); const organization = showOrganization ? getOrganization(item.organization) : null; collection.push({ ...item, @@ -240,10 +252,13 @@ export default Marionette.LayoutView.extend({ }); }, - getNavigationFindings (q) { + getNavigationFindings(q) { const DEFAULT_ITEMS = [ { name: translate('issues.page'), url: window.baseUrl + '/issues/search' }, - { name: translate('layout.measures'), url: window.baseUrl + '/measures/search?qualifiers[]=TRK' }, + { + name: translate('layout.measures'), + url: window.baseUrl + '/measures/search?qualifiers[]=TRK' + }, { name: translate('coding_rules.page'), url: window.baseUrl + '/coding_rules' }, { name: translate('quality_profiles.page'), url: window.baseUrl + '/profiles' }, { name: translate('quality_gates.page'), url: window.baseUrl + '/quality_gates' } @@ -261,10 +276,13 @@ export default Marionette.LayoutView.extend({ return findings.slice(0, 6); }, - getGlobalDashboardFindings (q) { + getGlobalDashboardFindings(q) { const dashboards = this.model.get('globalDashboards') || []; const items = dashboards.map(d => { - return { name: d.name, url: window.baseUrl + '/dashboard/index?did=' + encodeURIComponent(d.key) }; + return { + name: d.name, + url: window.baseUrl + '/dashboard/index?did=' + encodeURIComponent(d.key) + }; }); const findings = items.filter(f => { return f.name.match(new RegExp(q, 'i')); @@ -275,7 +293,7 @@ export default Marionette.LayoutView.extend({ return findings.slice(0, 6); }, - getFavoriteFindings (q) { + getFavoriteFindings(q) { const findings = this.favorite.filter(f => { return f.name.match(new RegExp(q, 'i')); }); diff --git a/server/sonar-web/src/main/js/app/components/nav/global/ShortcutsHelpView.js b/server/sonar-web/src/main/js/app/components/nav/global/ShortcutsHelpView.js index 6c9f8cbc4b1..893e4930ad6 100644 --- a/server/sonar-web/src/main/js/app/components/nav/global/ShortcutsHelpView.js +++ b/server/sonar-web/src/main/js/app/components/nav/global/ShortcutsHelpView.js @@ -24,4 +24,3 @@ export default ModalView.extend({ className: 'modal modal-large', template: ShortcutsHelpTemplate }); - diff --git a/server/sonar-web/src/main/js/app/components/nav/global/__tests__/GlobalNavMenu-test.js b/server/sonar-web/src/main/js/app/components/nav/global/__tests__/GlobalNavMenu-test.js index 43e5359b962..8631913e07f 100644 --- a/server/sonar-web/src/main/js/app/components/nav/global/__tests__/GlobalNavMenu-test.js +++ b/server/sonar-web/src/main/js/app/components/nav/global/__tests__/GlobalNavMenu-test.js @@ -29,6 +29,6 @@ it('should work with extensions', () => { isLoggedIn: false, permissions: { global: [] } }; - const wrapper = shallow(<GlobalNavMenu appState={appState} currentUser={currentUser}/>); + const wrapper = shallow(<GlobalNavMenu appState={appState} currentUser={currentUser} />); expect(wrapper).toMatchSnapshot(); }); |