123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- /*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
- import * as classNames from 'classnames';
- import * as React from 'react';
- import { IndexLink, Link } from 'react-router';
- import Dropdown from 'sonar-ui-common/components/controls/Dropdown';
- import DropdownIcon from 'sonar-ui-common/components/icons/DropdownIcon';
- import ContextNavBar from 'sonar-ui-common/components/ui/ContextNavBar';
- import NavBarTabs from 'sonar-ui-common/components/ui/NavBarTabs';
- import { translate } from 'sonar-ui-common/helpers/l10n';
- import { getBaseUrl } from 'sonar-ui-common/helpers/urls';
- import { PendingPluginResult } from '../../../../types/plugins';
- import { rawSizes } from '../../../theme';
- import PendingPluginsActionNotif from './PendingPluginsActionNotif';
- import SystemRestartNotif from './SystemRestartNotif';
-
- interface Props {
- extensions: T.Extension[];
- fetchPendingPlugins: () => void;
- fetchSystemStatus: () => void;
- location: {};
- pendingPlugins: PendingPluginResult;
- systemStatus: T.SysStatus;
- }
-
- export default class SettingsNav extends React.PureComponent<Props> {
- static defaultProps = {
- extensions: []
- };
-
- isSomethingActive(urls: string[]): boolean {
- const path = window.location.pathname;
- return urls.some((url: string) => path.indexOf(getBaseUrl() + url) === 0);
- }
-
- isSecurityActive() {
- const urls = [
- '/admin/users',
- '/admin/groups',
- '/admin/permissions',
- '/admin/permission_templates'
- ];
- return this.isSomethingActive(urls);
- }
-
- isProjectsActive() {
- const urls = ['/admin/projects_management', '/admin/background_tasks'];
- return this.isSomethingActive(urls);
- }
-
- isSystemActive() {
- const urls = ['/admin/system'];
- return this.isSomethingActive(urls);
- }
-
- isMarketplace() {
- const urls = ['/admin/marketplace'];
- return this.isSomethingActive(urls);
- }
-
- renderExtension = ({ key, name }: T.Extension) => {
- return (
- <li key={key}>
- <Link activeClassName="active" to={`/admin/extension/${key}`}>
- {name}
- </Link>
- </li>
- );
- };
-
- renderConfigurationTab() {
- const extensionsWithoutSupport = this.props.extensions.filter(
- extension => extension.key !== 'license/support'
- );
- return (
- <Dropdown
- overlay={
- <ul className="menu">
- <li>
- <IndexLink activeClassName="active" to="/admin/settings">
- {translate('settings.page')}
- </IndexLink>
- </li>
- <li>
- <IndexLink activeClassName="active" to="/admin/settings/encryption">
- {translate('property.category.security.encryption')}
- </IndexLink>
- </li>
- <li>
- <IndexLink activeClassName="active" to="/admin/webhooks">
- {translate('webhooks.page')}
- </IndexLink>
- </li>
- {extensionsWithoutSupport.map(this.renderExtension)}
- </ul>
- }
- tagName="li">
- {({ onToggleClick, open }) => (
- <a
- aria-expanded={open}
- aria-haspopup="menu"
- role="button"
- className={classNames('dropdown-toggle', {
- active:
- open ||
- (!this.isSecurityActive() &&
- !this.isProjectsActive() &&
- !this.isSystemActive() &&
- !this.isSomethingActive(['/admin/extension/license/support']) &&
- !this.isMarketplace())
- })}
- href="#"
- id="settings-navigation-configuration"
- onClick={onToggleClick}>
- {translate('sidebar.project_settings')}
- <DropdownIcon className="little-spacer-left" />
- </a>
- )}
- </Dropdown>
- );
- }
-
- renderProjectsTab() {
- return (
- <Dropdown
- overlay={
- <ul className="menu">
- <li>
- <IndexLink activeClassName="active" to="/admin/projects_management">
- {translate('management')}
- </IndexLink>
- </li>
- <li>
- <IndexLink activeClassName="active" to="/admin/background_tasks">
- {translate('background_tasks.page')}
- </IndexLink>
- </li>
- </ul>
- }
- tagName="li">
- {({ onToggleClick, open }) => (
- <a
- aria-expanded={open}
- aria-haspopup="menu"
- role="button"
- className={classNames('dropdown-toggle', { active: open || this.isProjectsActive() })}
- href="#"
- onClick={onToggleClick}>
- {translate('sidebar.projects')}
- <DropdownIcon className="little-spacer-left" />
- </a>
- )}
- </Dropdown>
- );
- }
-
- renderSecurityTab() {
- return (
- <Dropdown
- overlay={
- <ul className="menu">
- <li>
- <IndexLink activeClassName="active" to="/admin/users">
- {translate('users.page')}
- </IndexLink>
- </li>
- <li>
- <IndexLink activeClassName="active" to="/admin/groups">
- {translate('user_groups.page')}
- </IndexLink>
- </li>
- <li>
- <IndexLink activeClassName="active" to="/admin/permissions">
- {translate('global_permissions.page')}
- </IndexLink>
- </li>
- <li>
- <IndexLink activeClassName="active" to="/admin/permission_templates">
- {translate('permission_templates')}
- </IndexLink>
- </li>
- </ul>
- }
- tagName="li">
- {({ onToggleClick, open }) => (
- <a
- aria-expanded={open}
- aria-haspopup="menu"
- role="button"
- className={classNames('dropdown-toggle', { active: open || this.isSecurityActive() })}
- href="#"
- onClick={onToggleClick}>
- {translate('sidebar.security')}
- <DropdownIcon className="little-spacer-left" />
- </a>
- )}
- </Dropdown>
- );
- }
-
- render() {
- const { extensions, pendingPlugins } = this.props;
- const hasSupportExtension = extensions.find(extension => extension.key === 'license/support');
- const totalPendingPlugins =
- pendingPlugins.installing.length +
- pendingPlugins.removing.length +
- pendingPlugins.updating.length;
- const contextNavHeight = rawSizes.contextNavHeightRaw;
- let notifComponent;
- if (this.props.systemStatus === 'RESTARTING') {
- notifComponent = <SystemRestartNotif />;
- } else if (totalPendingPlugins > 0) {
- notifComponent = (
- <PendingPluginsActionNotif
- fetchSystemStatus={this.props.fetchSystemStatus}
- pending={pendingPlugins}
- refreshPending={this.props.fetchPendingPlugins}
- systemStatus={this.props.systemStatus}
- />
- );
- }
-
- return (
- <ContextNavBar
- height={notifComponent ? contextNavHeight + 30 : contextNavHeight}
- id="context-navigation"
- notif={notifComponent}>
- <header className="navbar-context-header">
- <h1>{translate('layout.settings')}</h1>
- </header>
-
- <NavBarTabs>
- {this.renderConfigurationTab()}
- {this.renderSecurityTab()}
- {this.renderProjectsTab()}
-
- <li>
- <IndexLink activeClassName="active" to="/admin/system">
- {translate('sidebar.system')}
- </IndexLink>
- </li>
-
- <li>
- <IndexLink activeClassName="active" to="/admin/marketplace">
- {translate('marketplace.page')}
- </IndexLink>
- </li>
-
- {hasSupportExtension && (
- <li>
- <IndexLink activeClassName="active" to="/admin/extension/license/support">
- {translate('support')}
- </IndexLink>
- </li>
- )}
- </NavBarTabs>
- </ContextNavBar>
- );
- }
- }
|