AlertBox: Merged Alertbox into Alert (#19212)

* refatoring alert box and using alert

* refactoring alertbox to alert

* Changed default to Error

* added buttonText, onButtonClick, omRemove

* Minor fix to buttons

* fixed onRemove
This commit is contained in:
srid12
2019-09-20 17:11:00 +05:30
committed by Torkel Ödegaard
parent bf24cbba76
commit 2a1e130000
15 changed files with 158 additions and 103 deletions

View File

@@ -1,32 +1,58 @@
import React, { FC, ReactNode } from 'react'; import React, { FC, ReactNode } from 'react';
import classNames from 'classnames';
interface Props { export type AlertVariant = 'success' | 'warning' | 'error' | 'info';
interface AlertProps {
title: string; title: string;
button?: { buttonText?: string;
text: string; onButtonClick?: (event: React.MouseEvent) => void;
onClick: (event: React.MouseEvent) => void; onRemove?: (event: React.MouseEvent) => void;
}; severity?: AlertVariant;
children?: ReactNode; children?: ReactNode;
} }
export const Alert: FC<Props> = props => { function getIconFromSeverity(severity: AlertVariant): string {
const { title, button, children } = props; switch (severity) {
case 'error': {
return 'fa fa-exclamation-triangle';
}
case 'warning': {
return 'fa fa-exclamation-triangle';
}
case 'info': {
return 'fa fa-info-circle';
}
case 'success': {
return 'fa fa-check';
}
default:
return '';
}
}
export const Alert: FC<AlertProps> = ({ title, buttonText, onButtonClick, onRemove, children, severity = 'error' }) => {
const alertClass = classNames('alert', `alert-${severity}`);
return ( return (
<div className="alert-container"> <div className="alert-container">
<div className="alert-error alert"> <div className={alertClass}>
<div className="alert-icon"> <div className="alert-icon">
<i className="fa fa-exclamation-triangle" /> <i className={getIconFromSeverity(severity)} />
</div> </div>
<div className="alert-body"> <div className="alert-body">
<div className="alert-title">{title}</div> <div className="alert-title">{title}</div>
{children && <div className="alert-text">{children}</div>} {children && <div className="alert-text">{children}</div>}
</div> </div>
{button && ( {/* If onRemove is specified , giving preference to onRemove */}
<div className="alert-button"> {onRemove && (
<button className="btn btn-outline-danger" onClick={button.onClick}> <button type="button" className="alert-close" onClick={onRemove}>
{button.text} <i className="fa fa fa-remove" />
</button> </button>
</div> )}
{onButtonClick && (
<button type="button" className="btn btn-outline-danger" onClick={onButtonClick}>
{buttonText}
</button>
)} )}
</div> </div>
</div> </div>

View File

@@ -0,0 +1,85 @@
//
// Alerts
// --------------------------------------------------
// Base styles
// -------------------------
.alert {
padding: 15px 20px;
margin-bottom: $space-xs;
text-shadow: 0 2px 0 rgba(255, 255, 255, 0.5);
background: $alert-error-bg;
position: relative;
color: $white;
text-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
border-radius: $border-radius;
display: flex;
flex-direction: row;
align-items: center;
}
// Alternate styles
// -------------------------
.alert-success {
background: $alert-success-bg;
}
.alert-danger,
.alert-error {
background: $alert-error-bg;
}
.alert-info {
background: $alert-info-bg;
}
.alert-warning {
background: $alert-warning-bg;
}
.page-alert-list {
z-index: 8000;
min-width: 400px;
max-width: 600px;
position: fixed;
right: 10px;
top: 60px;
}
.alert-close {
padding: 0 0 0 $space-md;
border: none;
background: none;
display: flex;
align-items: center;
.fa {
align-self: flex-end;
font-size: 21px;
color: rgba(255, 255, 255, 0.75);
}
}
.alert-title {
font-weight: $font-weight-semi-bold;
}
.alert-icon {
padding: 0 $space-md 0 0;
display: flex;
align-items: center;
justify-content: center;
width: 35px;
.fa {
font-size: 21px;
}
}
.alert-body {
flex-grow: 1;
}
.alert-icon-on-top {
align-items: flex-start;
}

View File

@@ -62,7 +62,7 @@ export {
LegendPlacement, LegendPlacement,
LegendDisplayMode, LegendDisplayMode,
} from './Legend/Legend'; } from './Legend/Legend';
export { Alert } from './Alert/Alert'; export { Alert, AlertVariant } from './Alert/Alert';
export { GraphSeriesToggler, GraphSeriesTogglerAPI } from './Graph/GraphSeriesToggler'; export { GraphSeriesToggler, GraphSeriesTogglerAPI } from './Graph/GraphSeriesToggler';
export { Collapse } from './Collapse/Collapse'; export { Collapse } from './Collapse/Collapse';
export { LogLabels } from './Logs/LogLabels'; export { LogLabels } from './Logs/LogLabels';

View File

@@ -176,7 +176,7 @@ $zindex-typeahead: ${theme.zIndex.typeahead};
// //
$btn-padding-x: 14px !default; $btn-padding-x: 14px !default;
$btn-padding-y: 10px !default; $btn-padding-y: 8px !default;
$btn-line-height: 1 !default; $btn-line-height: 1 !default;
$btn-font-weight: ${theme.typography.weight.semibold} !default; $btn-font-weight: ${theme.typography.weight.semibold} !default;

View File

@@ -1,50 +0,0 @@
import React, { FunctionComponent, ReactNode } from 'react';
import classNames from 'classnames';
import { AppNotificationSeverity } from 'app/types';
interface Props {
title: string;
icon?: string;
body?: ReactNode;
severity: AppNotificationSeverity;
onClose?: () => void;
}
function getIconFromSeverity(severity: AppNotificationSeverity): string {
switch (severity) {
case AppNotificationSeverity.Error: {
return 'fa fa-exclamation-triangle';
}
case AppNotificationSeverity.Warning: {
return 'fa fa-exclamation-triangle';
}
case AppNotificationSeverity.Info: {
return 'fa fa-info-circle';
}
case AppNotificationSeverity.Success: {
return 'fa fa-check';
}
default:
return '';
}
}
export const AlertBox: FunctionComponent<Props> = ({ title, icon, body, severity, onClose }) => {
const alertClass = classNames('alert', `alert-${severity}`);
return (
<div className={alertClass}>
<div className="alert-icon">
<i className={icon || getIconFromSeverity(severity)} />
</div>
<div className="alert-body">
<div className="alert-title">{title}</div>
{body && <div className="alert-text">{body}</div>}
</div>
{onClose && (
<button type="button" className="alert-close" onClick={onClose}>
<i className="fa fa fa-remove" />
</button>
)}
</div>
);
};

View File

@@ -1,6 +1,6 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { AppNotification } from 'app/types'; import { AppNotification } from 'app/types';
import { AlertBox } from '../AlertBox/AlertBox'; import { Alert } from '@grafana/ui';
interface Props { interface Props {
appNotification: AppNotification; appNotification: AppNotification;
@@ -23,12 +23,11 @@ export default class AppNotificationItem extends Component<Props> {
const { appNotification, onClearNotification } = this.props; const { appNotification, onClearNotification } = this.props;
return ( return (
<AlertBox <Alert
severity={appNotification.severity} severity={appNotification.severity}
title={appNotification.title} title={appNotification.title}
body={appNotification.text} children={appNotification.text}
icon={appNotification.icon} onRemove={() => onClearNotification(appNotification.id)}
onClose={() => onClearNotification(appNotification.id)}
/> />
); );
} }

View File

@@ -1,5 +1,5 @@
import React, { FC } from 'react'; import React, { FC } from 'react';
import { AlertBox } from 'app/core/components/AlertBox/AlertBox'; import { Alert } from '@grafana/ui';
import { AppNotificationSeverity, LdapConnectionInfo, LdapServerInfo } from 'app/types'; import { AppNotificationSeverity, LdapConnectionInfo, LdapServerInfo } from 'app/types';
interface Props { interface Props {
@@ -78,5 +78,5 @@ export const LdapErrorBox: FC<LdapConnectionErrorProps> = ({ ldapConnectionInfo
</div> </div>
)); ));
return <AlertBox title="Connection error" severity={AppNotificationSeverity.Error} body={errorElements} />; return <Alert title="Connection error" severity={AppNotificationSeverity.Error} children={errorElements} />;
}; };

View File

@@ -2,11 +2,10 @@ import React, { PureComponent } from 'react';
import { hot } from 'react-hot-loader'; import { hot } from 'react-hot-loader';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { NavModel } from '@grafana/data'; import { NavModel } from '@grafana/data';
import { FormField } from '@grafana/ui'; import { FormField, Alert } from '@grafana/ui';
import { getNavModel } from 'app/core/selectors/navModel'; import { getNavModel } from 'app/core/selectors/navModel';
import config from 'app/core/config'; import config from 'app/core/config';
import Page from 'app/core/components/Page/Page'; import Page from 'app/core/components/Page/Page';
import { AlertBox } from 'app/core/components/AlertBox/AlertBox';
import { LdapConnectionStatus } from './LdapConnectionStatus'; import { LdapConnectionStatus } from './LdapConnectionStatus';
import { LdapSyncInfo } from './LdapSyncInfo'; import { LdapSyncInfo } from './LdapSyncInfo';
import { LdapUserInfo } from './LdapUserInfo'; import { LdapUserInfo } from './LdapUserInfo';
@@ -81,7 +80,7 @@ export class LdapPage extends PureComponent<Props, State> {
<> <>
{ldapError && ldapError.title && ( {ldapError && ldapError.title && (
<div className="gf-form-group"> <div className="gf-form-group">
<AlertBox title={ldapError.title} severity={AppNotificationSeverity.Error} body={ldapError.body} /> <Alert title={ldapError.title} severity={AppNotificationSeverity.Error} children={ldapError.body} />
</div> </div>
)} )}
@@ -100,11 +99,11 @@ export class LdapPage extends PureComponent<Props, State> {
</div> </div>
{userError && userError.title && ( {userError && userError.title && (
<div className="gf-form-group"> <div className="gf-form-group">
<AlertBox <Alert
title={userError.title} title={userError.title}
severity={AppNotificationSeverity.Error} severity={AppNotificationSeverity.Error}
body={userError.body} children={userError.body}
onClose={this.onClearUserError} onRemove={this.onClearUserError}
/> />
</div> </div>
)} )}

View File

@@ -2,8 +2,8 @@ import React, { PureComponent } from 'react';
import { hot } from 'react-hot-loader'; import { hot } from 'react-hot-loader';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { NavModel } from '@grafana/data'; import { NavModel } from '@grafana/data';
import { Alert } from '@grafana/ui';
import Page from 'app/core/components/Page/Page'; import Page from 'app/core/components/Page/Page';
import { AlertBox } from 'app/core/components/AlertBox/AlertBox';
import { getNavModel } from 'app/core/selectors/navModel'; import { getNavModel } from 'app/core/selectors/navModel';
import { import {
AppNotificationSeverity, AppNotificationSeverity,
@@ -106,11 +106,11 @@ export class LdapUserPage extends PureComponent<Props, State> {
</div> </div>
{userError && userError.title && ( {userError && userError.title && (
<div className="gf-form-group"> <div className="gf-form-group">
<AlertBox <Alert
title={userError.title} title={userError.title}
severity={AppNotificationSeverity.Error} severity={AppNotificationSeverity.Error}
body={userError.body} children={userError.body}
onClose={this.onClearUserError} onRemove={this.onClearUserError}
/> />
</div> </div>
)} )}

View File

@@ -10,12 +10,12 @@ import { EditorTabBody, EditorToolbarView } from '../dashboard/panel_editor/Edit
import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA';
import StateHistory from './StateHistory'; import StateHistory from './StateHistory';
import 'app/features/alerting/AlertTabCtrl'; import 'app/features/alerting/AlertTabCtrl';
import { Alert } from '@grafana/ui';
// Types // Types
import { DashboardModel } from '../dashboard/state/DashboardModel'; import { DashboardModel } from '../dashboard/state/DashboardModel';
import { PanelModel } from '../dashboard/state/PanelModel'; import { PanelModel } from '../dashboard/state/PanelModel';
import { TestRuleResult } from './TestRuleResult'; import { TestRuleResult } from './TestRuleResult';
import { AlertBox } from 'app/core/components/AlertBox/AlertBox';
import { AppNotificationSeverity } from 'app/types'; import { AppNotificationSeverity } from 'app/types';
interface Props { interface Props {
@@ -135,7 +135,7 @@ export class AlertTab extends PureComponent<Props> {
if (!alert && hasTransformations) { if (!alert && hasTransformations) {
return ( return (
<EditorTabBody heading="Alert"> <EditorTabBody heading="Alert">
<AlertBox <Alert
severity={AppNotificationSeverity.Warning} severity={AppNotificationSeverity.Warning}
title="Transformations are not supported in alert queries" title="Transformations are not supported in alert queries"
/> />
@@ -156,7 +156,7 @@ export class AlertTab extends PureComponent<Props> {
<EditorTabBody heading="Alert" toolbarItems={toolbarItems}> <EditorTabBody heading="Alert" toolbarItems={toolbarItems}>
<> <>
{alert && hasTransformations && ( {alert && hasTransformations && (
<AlertBox <Alert
severity={AppNotificationSeverity.Error} severity={AppNotificationSeverity.Error}
title="Transformations are not supported in alert queries" title="Transformations are not supported in alert queries"
/> />

View File

@@ -14,8 +14,7 @@ import { DashboardGrid } from '../dashgrid/DashboardGrid';
import { DashNav } from '../components/DashNav'; import { DashNav } from '../components/DashNav';
import { SubMenu } from '../components/SubMenu'; import { SubMenu } from '../components/SubMenu';
import { DashboardSettings } from '../components/DashboardSettings'; import { DashboardSettings } from '../components/DashboardSettings';
import { CustomScrollbar } from '@grafana/ui'; import { CustomScrollbar, Alert } from '@grafana/ui';
import { AlertBox } from 'app/core/components/AlertBox/AlertBox';
// Redux // Redux
import { initDashboard } from '../state/initDashboard'; import { initDashboard } from '../state/initDashboard';
@@ -32,7 +31,6 @@ import {
AppNotificationSeverity, AppNotificationSeverity,
} from 'app/types'; } from 'app/types';
import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; import { DashboardModel, PanelModel } from 'app/features/dashboard/state';
export interface Props { export interface Props {
urlUid?: string; urlUid?: string;
urlSlug?: string; urlSlug?: string;
@@ -242,10 +240,10 @@ export class DashboardPage extends PureComponent<Props, State> {
return ( return (
<div className="dashboard-loading"> <div className="dashboard-loading">
<AlertBox <Alert
severity={AppNotificationSeverity.Error} severity={AppNotificationSeverity.Error}
title={initError.message} title={initError.message}
body={getMessageFromError(initError.error)} children={getMessageFromError(initError.error)}
/> />
</div> </div>
); );

View File

@@ -2,12 +2,9 @@
import _ from 'lodash'; import _ from 'lodash';
import React, { PureComponent, ReactNode } from 'react'; import React, { PureComponent, ReactNode } from 'react';
// Components
import { AlertBox } from 'app/core/components/AlertBox/AlertBox';
// Types // Types
import { AppNotificationSeverity } from 'app/types'; import { AppNotificationSeverity } from 'app/types';
import { PanelProps, PanelPlugin, PluginType, PanelPluginMeta } from '@grafana/ui'; import { PanelProps, PanelPlugin, PluginType, PanelPluginMeta, Alert } from '@grafana/ui';
interface Props { interface Props {
title: string; title: string;
@@ -29,7 +26,7 @@ class PanelPluginError extends PureComponent<Props> {
return ( return (
<div style={style}> <div style={style}>
<AlertBox severity={AppNotificationSeverity.Error} {...this.props} /> <Alert severity={AppNotificationSeverity.Error} {...this.props} />
</div> </div>
); );
} }

View File

@@ -280,7 +280,8 @@ export class Explore extends React.PureComponent<ExploreProps> {
<div className="explore-container"> <div className="explore-container">
<Alert <Alert
title={`Error connecting to datasource: ${datasourceError}`} title={`Error connecting to datasource: ${datasourceError}`}
button={{ text: 'Reconnect', onClick: this.onReconnect }} buttonText={'Reconnect'}
onButtonClick={this.onReconnect}
/> />
</div> </div>
</FadeIn> </FadeIn>

View File

@@ -8,6 +8,7 @@ import find from 'lodash/find';
import { UrlQueryMap } from '@grafana/runtime'; import { UrlQueryMap } from '@grafana/runtime';
import { StoreState, AppNotificationSeverity } from 'app/types'; import { StoreState, AppNotificationSeverity } from 'app/types';
import { import {
Alert,
PluginType, PluginType,
GrafanaPlugin, GrafanaPlugin,
PluginInclude, PluginInclude,
@@ -30,7 +31,6 @@ import { PluginDashboards } from './PluginDashboards';
import { appEvents } from 'app/core/core'; import { appEvents } from 'app/core/core';
import { config } from 'app/core/config'; import { config } from 'app/core/config';
import { ContextSrv } from '../../core/services/context_srv'; import { ContextSrv } from '../../core/services/context_srv';
import { AlertBox } from 'app/core/components/AlertBox/AlertBox';
export function getLoadingNav(): NavModel { export function getLoadingNav(): NavModel {
const node = { const node = {
@@ -141,7 +141,7 @@ class PluginPage extends PureComponent<Props, State> {
const { plugin, nav } = this.state; const { plugin, nav } = this.state;
if (!plugin) { if (!plugin) {
return <AlertBox severity={AppNotificationSeverity.Error} title="Plugin Not Found" />; return <Alert severity={AppNotificationSeverity.Error} title="Plugin Not Found" />;
} }
const active = nav.main.children.find(tab => tab.active); const active = nav.main.children.find(tab => tab.active);
@@ -300,10 +300,10 @@ class PluginPage extends PureComponent<Props, State> {
<div className="sidebar-container"> <div className="sidebar-container">
<div className="sidebar-content"> <div className="sidebar-content">
{plugin.loadError && ( {plugin.loadError && (
<AlertBox <Alert
severity={AppNotificationSeverity.Error} severity={AppNotificationSeverity.Error}
title="Error Loading Plugin" title="Error Loading Plugin"
body={ children={
<> <>
Check the server startup logs for more information. <br /> Check the server startup logs for more information. <br />
If this plugin was loaded from git, make sure it was compiled. If this plugin was loaded from git, make sure it was compiled.

View File

@@ -179,7 +179,7 @@ $zindex-typeahead: 1060;
// //
$btn-padding-x: 14px !default; $btn-padding-x: 14px !default;
$btn-padding-y: 10px !default; $btn-padding-y: 8px !default;
$btn-line-height: 1 !default; $btn-line-height: 1 !default;
$btn-font-weight: 500 !default; $btn-font-weight: 500 !default;