import { Link } from 'react-router';
import { FormattedMessage } from 'react-intl';
import ComponentNavLicenseNotif from './ComponentNavLicenseNotif';
-import NavBarNotif from '../../../../components/nav/NavBarNotif';
-import PendingIcon from '../../../../components/icons-components/PendingIcon';
import { STATUSES } from '../../../../apps/background-tasks/constants';
import { getComponentBackgroundTaskUrl } from '../../../../helpers/urls';
import { hasMessage, translate } from '../../../../helpers/l10n';
+import { Alert } from '../../../../components/ui/Alert';
interface Props {
component: T.Component;
const { currentTask, currentTaskOnSameBranch, isInProgress, isPending } = this.props;
if (isInProgress) {
return (
- <NavBarNotif variant="info">
- <i className="spinner spacer-right text-bottom" />
+ <Alert display="banner" variant="info">
{this.renderMessage('component_navigation.status.in_progress')}
- </NavBarNotif>
+ </Alert>
);
} else if (isPending) {
return (
- <NavBarNotif variant="info">
- <PendingIcon className="spacer-right" />
+ <Alert display="banner" variant="info">
{this.renderMessage('component_navigation.status.pending', STATUSES.ALL)}
- </NavBarNotif>
+ </Alert>
);
} else if (currentTask && currentTask.status === STATUSES.FAILED) {
if (
message = this.renderMessage('component_navigation.status.failed');
}
- return <NavBarNotif variant="error">{message}</NavBarNotif>;
+ return (
+ <Alert display="banner" variant="error">
+ {message}
+ </Alert>
+ );
}
return null;
}
*/
import * as React from 'react';
import { Link } from 'react-router';
-import NavBarNotif from '../../../../components/nav/NavBarNotif';
import { translate } from '../../../../helpers/l10n';
import { isValidLicense } from '../../../../api/marketplace';
import { withAppState } from '../../../../components/withAppState';
+import { Alert } from '../../../../components/ui/Alert';
interface Props {
appState: Pick<T.AppState, 'canAdmin'>;
if (isValidLicense && currentTask.errorType !== 'LICENSING_LOC') {
return (
- <NavBarNotif variant="error">
- <span className="little-spacer-right">
- {translate('component_navigation.status.last_blocked_due_to_bad_license')}
- </span>
- </NavBarNotif>
+ <Alert display="banner" variant="error">
+ {translate('component_navigation.status.last_blocked_due_to_bad_license')}
+ </Alert>
);
}
return (
- <NavBarNotif variant="error">
+ <Alert display="banner" variant="error">
<span className="little-spacer-right">{currentTask.errorMessage}</span>
{this.props.appState.canAdmin ? (
<Link to="/admin/extension/license/app">
) : (
translate('please_contact_administrator')
)}
- </NavBarNotif>
+ </Alert>
);
}
}
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders background task error correctly 1`] = `
-<NavBarNotif
+<Alert
+ display="banner"
variant="error"
>
<FormattedMessage
}
}
/>
-</NavBarNotif>
+</Alert>
`;
exports[`renders background task error correctly for a different branch/PR 1`] = `
-<NavBarNotif
+<Alert
+ display="banner"
variant="error"
>
<FormattedMessage
}
}
/>
-</NavBarNotif>
+</Alert>
`;
exports[`renders background task error correctly for a different branch/PR 2`] = `
-<NavBarNotif
+<Alert
+ display="banner"
variant="error"
>
<FormattedMessage
}
}
/>
-</NavBarNotif>
+</Alert>
`;
exports[`renders background task in progress info correctly 1`] = `
-<NavBarNotif
+<Alert
+ display="banner"
variant="info"
>
- <i
- className="spinner spacer-right text-bottom"
- />
<FormattedMessage
defaultMessage="component_navigation.status.in_progress"
id="component_navigation.status.in_progress"
}
}
/>
-</NavBarNotif>
+</Alert>
`;
exports[`renders background task license info correctly 1`] = `
`;
exports[`renders background task pending info correctly 1`] = `
-<NavBarNotif
+<Alert
+ display="banner"
variant="info"
>
- <PendingIcon
- className="spacer-right"
- />
<FormattedMessage
defaultMessage="component_navigation.status.pending"
id="component_navigation.status.pending"
}
}
/>
-</NavBarNotif>
+</Alert>
`;
exports[`renders background task pending info correctly for admin 1`] = `
-<NavBarNotif
+<Alert
+ display="banner"
variant="info"
>
- <PendingIcon
- className="spacer-right"
- />
<FormattedMessage
defaultMessage="component_navigation.status.pending.admin"
id="component_navigation.status.pending.admin"
}
}
/>
-</NavBarNotif>
+</Alert>
`;
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders a different message if the license is valid 1`] = `
-<NavBarNotif
+<Alert
+ display="banner"
variant="error"
>
- <span
- className="little-spacer-right"
- >
- component_navigation.status.last_blocked_due_to_bad_license
- </span>
-</NavBarNotif>
+ component_navigation.status.last_blocked_due_to_bad_license
+</Alert>
`;
exports[`renders background task license info correctly 1`] = `
-<NavBarNotif
+<Alert
+ display="banner"
variant="error"
>
<span
license.component_navigation.button.LICENSING
.
</Link>
-</NavBarNotif>
+</Alert>
`;
exports[`renders background task license info correctly 2`] = `
-<NavBarNotif
+<Alert
+ display="banner"
variant="error"
>
<span
Foo
</span>
please_contact_administrator
-</NavBarNotif>
+</Alert>
`;
exports[`renders correctly for LICENSING_LOC error 1`] = `
-<NavBarNotif
+<Alert
+ display="banner"
variant="error"
>
<span
license.component_navigation.button.LICENSING_LOC
.
</Link>
-</NavBarNotif>
+</Alert>
`;
import * as React from 'react';
import { FormattedMessage } from 'react-intl';
import InstanceMessage from '../../../../components/common/InstanceMessage';
-import NavBarNotif from '../../../../components/nav/NavBarNotif';
import RestartForm from '../../../../components/common/RestartForm';
import { cancelPendingPlugins, PluginPendingResult } from '../../../../api/plugins';
import { Button } from '../../../../components/ui/buttons';
import { translate } from '../../../../helpers/l10n';
+import { Alert } from '../../../../components/ui/Alert';
interface Props {
pending: PluginPendingResult;
}
return (
- <NavBarNotif className="js-pending" variant="info">
- <span className="little-spacer-right">
- <InstanceMessage message={translate('marketplace.instance_needs_to_be_restarted_to')} />
- </span>
- {[
- { length: installing.length, msg: 'marketplace.install_x_plugins' },
- { length: updating.length, msg: 'marketplace.update_x_plugins' },
- { length: removing.length, msg: 'marketplace.uninstall_x_plugins' }
- ]
- .filter(({ length }) => length > 0)
- .map(({ length, msg }, idx) => (
- <span key={msg}>
- {idx > 0 && '; '}
- <FormattedMessage
- defaultMessage={translate(msg)}
- id={msg}
- values={{ nb: <strong>{length}</strong> }}
- />
- </span>
- ))}
- <Button className="spacer-left js-restart" onClick={this.handleOpenRestart}>
- {translate('marketplace.restart')}
- </Button>
- <Button className="spacer-left js-cancel-all button-red" onClick={this.handleRevert}>
- {translate('marketplace.revert')}
- </Button>
- {this.state.openRestart && <RestartForm onClose={this.hanleCloseRestart} />}
- </NavBarNotif>
+ <Alert className="js-pending" display="banner" variant="info">
+ <div className="display-flex-center">
+ <span className="little-spacer-right">
+ <InstanceMessage message={translate('marketplace.instance_needs_to_be_restarted_to')} />
+ </span>
+ {[
+ { length: installing.length, msg: 'marketplace.install_x_plugins' },
+ { length: updating.length, msg: 'marketplace.update_x_plugins' },
+ { length: removing.length, msg: 'marketplace.uninstall_x_plugins' }
+ ]
+ .filter(({ length }) => length > 0)
+ .map(({ length, msg }, idx) => (
+ <span key={msg}>
+ {idx > 0 && '; '}
+ <FormattedMessage
+ defaultMessage={translate(msg)}
+ id={msg}
+ values={{ nb: <strong>{length}</strong> }}
+ />
+ </span>
+ ))}
+ <Button className="spacer-left js-restart" onClick={this.handleOpenRestart}>
+ {translate('marketplace.restart')}
+ </Button>
+ <Button className="spacer-left js-cancel-all button-red" onClick={this.handleRevert}>
+ {translate('marketplace.revert')}
+ </Button>
+ {this.state.openRestart && <RestartForm onClose={this.hanleCloseRestart} />}
+ </div>
+ </Alert>
);
}
}
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should display pending actions 1`] = `
-<NavBarNotif
+<Alert
className="js-pending"
+ display="banner"
variant="info"
>
- <span
- className="little-spacer-right"
+ <div
+ className="display-flex-center"
>
- <InstanceMessage
- message="marketplace.instance_needs_to_be_restarted_to"
- />
- </span>
- <span
- key="marketplace.install_x_plugins"
- >
- <FormattedMessage
- defaultMessage="marketplace.install_x_plugins"
- id="marketplace.install_x_plugins"
- values={
- Object {
- "nb": <strong>
- 2
- </strong>,
+ <span
+ className="little-spacer-right"
+ >
+ <InstanceMessage
+ message="marketplace.instance_needs_to_be_restarted_to"
+ />
+ </span>
+ <span
+ key="marketplace.install_x_plugins"
+ >
+ <FormattedMessage
+ defaultMessage="marketplace.install_x_plugins"
+ id="marketplace.install_x_plugins"
+ values={
+ Object {
+ "nb": <strong>
+ 2
+ </strong>,
+ }
}
- }
- />
- </span>
- <span
- key="marketplace.uninstall_x_plugins"
- >
- ;
- <FormattedMessage
- defaultMessage="marketplace.uninstall_x_plugins"
- id="marketplace.uninstall_x_plugins"
- values={
- Object {
- "nb": <strong>
- 1
- </strong>,
+ />
+ </span>
+ <span
+ key="marketplace.uninstall_x_plugins"
+ >
+ ;
+ <FormattedMessage
+ defaultMessage="marketplace.uninstall_x_plugins"
+ id="marketplace.uninstall_x_plugins"
+ values={
+ Object {
+ "nb": <strong>
+ 1
+ </strong>,
+ }
}
- }
- />
- </span>
- <Button
- className="spacer-left js-restart"
- onClick={[Function]}
- >
- marketplace.restart
- </Button>
- <Button
- className="spacer-left js-cancel-all button-red"
- onClick={[Function]}
- >
- marketplace.revert
- </Button>
-</NavBarNotif>
+ />
+ </span>
+ <Button
+ className="spacer-left js-restart"
+ onClick={[Function]}
+ >
+ marketplace.restart
+ </Button>
+ <Button
+ className="spacer-left js-cancel-all button-red"
+ onClick={[Function]}
+ >
+ marketplace.revert
+ </Button>
+ </div>
+</Alert>
`;
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
.alert {
- display: flex;
- align-items: stretch;
margin-bottom: var(--gridSize);
border: 1px solid;
border-radius: 2px;
display: none;
}
+.alert-inner {
+ display: flex;
+ align-items: stretch;
+}
+
+.alert-inner.is-banner {
+ min-width: var(--minPageWidth);
+ max-width: var(--maxPageWidth);
+ margin-left: auto;
+ margin-right: auto;
+ padding-left: var(--pagePadding);
+ padding-right: var(--pagePadding);
+ box-sizing: border-box;
+}
+
.alert-icon {
flex: 0 0 auto;
display: flex;
border-right: 1px solid;
}
+.alert-icon.is-banner {
+ width: calc(2 * var(--gridSize));
+ border-right: none;
+}
+
.alert-content {
flex: 1 0 0;
padding: var(--gridSize) calc(2 * var(--gridSize));
}
.page-container {
- min-width: 1080px;
+ min-width: var(--minPageWidth);
}
.page-wrapper {
contextNavHeightRaw: 9 * grid,
+ maxPageWidth: '1320px',
+ minPageWidth: '1080px',
pagePadding: '20px',
// different
background-color: var(--sonarcloudBlack800);
color: var(--sonarcloudBlack300);
font-size: 12px;
- min-width: 1080px;
+ min-width: var(--minPageWidth);
}
.sc-footer *:focus {
.sc-header-background {
position: absolute;
width: 100%;
- min-width: 1080px;
+ min-width: var(--minPageWidth);
z-index: 0;
}
.sc-functionality-background {
position: relative;
width: 100%;
- min-width: 1080px;
+ min-width: var(--minPageWidth);
margin-top: -150px;
z-index: 0;
}
.navbar-limited {
position: relative;
- min-width: 1080px;
- max-width: 1320px;
+ min-width: var(--minPageWidth);
+ max-width: var(--maxPageWidth);
margin-left: auto;
margin-right: auto;
- padding-left: 20px;
- padding-right: 20px;
+ padding-left: var(--pagePadding);
+ padding-right: var(--pagePadding);
}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-.navbar-notif {
- margin-bottom: var(--gridSize);
- border: 1px solid;
- border-left: none;
- border-right: none;
- padding: var(--gridSize) 0;
-}
-
-.navbar-notif a,
-.navbar-notif .button-link {
- border-color: var(--darkBlue);
-}
-
-.navbar-notif-error {
- border-color: var(--alertBorderError);
- background-color: var(--alertBackgroundError);
- color: var(--alertTextError);
-}
-
-.navbar-notif-info {
- border-color: var(--alertBorderInfo);
- background-color: var(--alertBackgroundInfo);
- color: var(--alertTextInfo);
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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 React from 'react';
-import * as classNames from 'classnames';
-import './NavBarNotif.css';
-
-type NavBarNotifVariant = 'error' | 'info';
-
-interface Props {
- children?: React.ReactNode;
- className?: string;
- variant: NavBarNotifVariant;
-}
-
-export default function NavBarNotif(props: Props) {
- if (!props.children) {
- return null;
- }
- return (
- <div className={classNames('navbar-notif', `navbar-notif-${props.variant}`, props.className)}>
- <div className="navbar-limited clearfix">{props.children}</div>
- </div>
- );
-}
import Tooltip from '../controls/Tooltip';
import { translate } from '../../helpers/l10n';
-type AlertDisplay = 'block' | 'inline';
+type AlertDisplay = 'banner' | 'block' | 'inline';
type AlertVariant = 'error' | 'warning' | 'success' | 'info';
export interface AlertProps {
})}
role="alert"
{...domProps}>
- <Tooltip overlay={translate('alert.tooltip', variant)}>
- <div className="alert-icon">
- {variant === 'error' && <AlertErrorIcon fill={theme.alertIconError} />}
- {variant === 'warning' && <AlertWarnIcon fill={theme.alertIconWarning} />}
- {variant === 'success' && <AlertSuccessIcon fill={theme.alertIconSuccess} />}
- {variant === 'info' && <InfoIcon fill={theme.alertIconInfo} />}
- </div>
- </Tooltip>
-
- <div className="alert-content">{props.children}</div>
+ <div className={classNames('alert-inner', { 'is-banner': display === 'banner' })}>
+ <Tooltip overlay={translate('alert.tooltip', variant)}>
+ <div className={classNames('alert-icon', { 'is-banner': display === 'banner' })}>
+ {variant === 'error' && <AlertErrorIcon fill={theme.alertIconError} />}
+ {variant === 'warning' && <AlertWarnIcon fill={theme.alertIconWarning} />}
+ {variant === 'success' && <AlertSuccessIcon fill={theme.alertIconSuccess} />}
+ {variant === 'info' && <InfoIcon fill={theme.alertIconInfo} />}
+ </div>
+ </Tooltip>
+ <div className="alert-content">{props.children}</div>
+ </div>
</div>
);
}
id="error-message"
role="alert"
>
- <Tooltip
- overlay="alert.tooltip.error"
+ <div
+ className="alert-inner"
>
+ <Tooltip
+ overlay="alert.tooltip.error"
+ >
+ <div
+ className="alert-icon"
+ >
+ <AlertErrorIcon
+ fill="#b81723"
+ />
+ </div>
+ </Tooltip>
<div
- className="alert-icon"
+ className="alert-content"
>
- <AlertErrorIcon
- fill="#b81723"
- />
+ This is an error!
</div>
- </Tooltip>
- <div
- className="alert-content"
- >
- This is an error!
</div>
</div>
`;