Action button refactor
This commit is contained in:
13
src/components/AckButton/AckButton.tsx
Normal file
13
src/components/AckButton/AckButton.tsx
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import React, { FC } from 'react';
|
||||||
|
import { ActionButton } from '../ActionButton/ActionButton';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
className?: string;
|
||||||
|
onClick(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AckButton: FC<Props> = ({ className, onClick }) => {
|
||||||
|
return (
|
||||||
|
<ActionButton className={className} icon="reply-all" tooltip="Acknowledge problem" onClick={onClick} />
|
||||||
|
);
|
||||||
|
};
|
||||||
71
src/components/ActionButton/ActionButton.tsx
Normal file
71
src/components/ActionButton/ActionButton.tsx
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
import React, { FC } from 'react';
|
||||||
|
import { cx, css } from 'emotion';
|
||||||
|
import { stylesFactory, useTheme } from '@grafana/ui';
|
||||||
|
import { GrafanaTheme, GrafanaThemeType } from '@grafana/data';
|
||||||
|
import { FAIcon } from '../FAIcon/FAIcon';
|
||||||
|
import { Tooltip } from '../Tooltip/Tooltip';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
icon?: string;
|
||||||
|
width?: number;
|
||||||
|
tooltip?: string;
|
||||||
|
className?: string;
|
||||||
|
onClick(event: React.MouseEvent<HTMLButtonElement>): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ActionButton: FC<Props> = ({ icon, width, tooltip, className, children, onClick }) => {
|
||||||
|
const theme = useTheme();
|
||||||
|
const styles = getStyles(theme);
|
||||||
|
const buttonClass = cx(
|
||||||
|
'btn',
|
||||||
|
styles.button,
|
||||||
|
css`width: ${width || 3}rem`,
|
||||||
|
className,
|
||||||
|
);
|
||||||
|
|
||||||
|
let button = (
|
||||||
|
<button className={buttonClass} onClick={onClick}>
|
||||||
|
{icon && <FAIcon icon={icon} customClass={styles.icon} />}
|
||||||
|
{children}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
|
||||||
|
if (tooltip) {
|
||||||
|
button = (
|
||||||
|
<Tooltip placement="bottom" content={tooltip}>
|
||||||
|
{button}
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return button;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getStyles = stylesFactory((theme: GrafanaTheme) => {
|
||||||
|
const actionBlue = theme.type === GrafanaThemeType.Light ? '#497dc0' : '#005f81';
|
||||||
|
const hoverBlue = theme.type === GrafanaThemeType.Light ? '#456ba4' : '#354f77';
|
||||||
|
|
||||||
|
return {
|
||||||
|
button: css`
|
||||||
|
height: 2rem;
|
||||||
|
background-image: none;
|
||||||
|
background-color: ${actionBlue};
|
||||||
|
border: 1px solid ${theme.colors.gray1};
|
||||||
|
border-radius: 1px;
|
||||||
|
color: ${theme.colors.text};
|
||||||
|
|
||||||
|
i {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: ${hoverBlue};
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
icon: css`
|
||||||
|
i {
|
||||||
|
color: ${theme.colors.text};
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
};
|
||||||
|
});
|
||||||
@@ -1,13 +1,10 @@
|
|||||||
import React, { FC } from 'react';
|
import React, { FC } from 'react';
|
||||||
import { cx, css } from 'emotion';
|
|
||||||
import { stylesFactory, useTheme } from '@grafana/ui';
|
|
||||||
import { GrafanaTheme, GrafanaThemeType } from '@grafana/data';
|
|
||||||
import { getLocationSrv } from '@grafana/runtime';
|
import { getLocationSrv } from '@grafana/runtime';
|
||||||
import { MODE_METRICS, MODE_ITEMID } from '../../datasource-zabbix/constants';
|
import { MODE_METRICS, MODE_ITEMID } from '../../datasource-zabbix/constants';
|
||||||
import { renderUrl } from '../../panel-triggers/utils';
|
import { renderUrl } from '../../panel-triggers/utils';
|
||||||
import { expandItemName } from '../../datasource-zabbix/utils';
|
import { expandItemName } from '../../datasource-zabbix/utils';
|
||||||
import { FAIcon } from '../FAIcon/FAIcon';
|
|
||||||
import { ProblemDTO } from '../../datasource-zabbix/types';
|
import { ProblemDTO } from '../../datasource-zabbix/types';
|
||||||
|
import { ActionButton } from '../ActionButton/ActionButton';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
problem: ProblemDTO;
|
problem: ProblemDTO;
|
||||||
@@ -15,14 +12,10 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const ExploreButton: FC<Props> = ({ problem, panelId }) => {
|
export const ExploreButton: FC<Props> = ({ problem, panelId }) => {
|
||||||
const theme = useTheme();
|
|
||||||
const styles = getStyles(theme);
|
|
||||||
const buttonClass = cx('btn', styles.button);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button className={buttonClass} onClick={() => openInExplore(problem, panelId)}>
|
<ActionButton icon="compass" width={6} onClick={() => openInExplore(problem, panelId)}>
|
||||||
<FAIcon icon="compass" customClass={styles.icon} /><span>Explore</span>
|
Explore
|
||||||
</button>
|
</ActionButton>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -59,31 +52,3 @@ const openInExplore = (problem: ProblemDTO, panelId: number) => {
|
|||||||
const url = renderUrl('/explore', { left: exploreState });
|
const url = renderUrl('/explore', { left: exploreState });
|
||||||
getLocationSrv().update({ path: url, query: {} });
|
getLocationSrv().update({ path: url, query: {} });
|
||||||
};
|
};
|
||||||
|
|
||||||
const getStyles = stylesFactory((theme: GrafanaTheme) => {
|
|
||||||
const actionBlue = theme.type === GrafanaThemeType.Light ? '#497dc0' : '#005f81';
|
|
||||||
return {
|
|
||||||
button: css`
|
|
||||||
width: 6rem;
|
|
||||||
height: 2rem;
|
|
||||||
background-image: none;
|
|
||||||
background-color: ${actionBlue};
|
|
||||||
border: 1px solid darken(${actionBlue}, 6%);
|
|
||||||
border-radius: 1px;
|
|
||||||
margin-right: 1.6rem;
|
|
||||||
|
|
||||||
i {
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: darken(${actionBlue}, 4%);
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
icon: css`
|
|
||||||
i {
|
|
||||||
color: ${theme.colors.text};
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
export { GFHeartIcon } from './GFHeartIcon/GFHeartIcon';
|
export { GFHeartIcon } from './GFHeartIcon/GFHeartIcon';
|
||||||
export { FAIcon } from './FAIcon/FAIcon';
|
export { FAIcon } from './FAIcon/FAIcon';
|
||||||
|
export { AckButton } from './AckButton/AckButton';
|
||||||
export { ExploreButton } from './ExploreButton/ExploreButton';
|
export { ExploreButton } from './ExploreButton/ExploreButton';
|
||||||
export { Tooltip } from './Tooltip/Tooltip';
|
export { Tooltip } from './Tooltip/Tooltip';
|
||||||
export { ModalController } from './Modal/ModalController';
|
export { ModalController } from './Modal/ModalController';
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import EventTag from '../EventTag';
|
|||||||
import ProblemStatusBar from './ProblemStatusBar';
|
import ProblemStatusBar from './ProblemStatusBar';
|
||||||
import AcknowledgesList from './AcknowledgesList';
|
import AcknowledgesList from './AcknowledgesList';
|
||||||
import ProblemTimeline from './ProblemTimeline';
|
import ProblemTimeline from './ProblemTimeline';
|
||||||
import { FAIcon, ExploreButton, Tooltip, ModalController } from '../../../components';
|
import { FAIcon, ExploreButton, AckButton, Tooltip, ModalController } from '../../../components';
|
||||||
|
|
||||||
interface ProblemDetailsProps extends RTRow<ProblemDTO> {
|
interface ProblemDetailsProps extends RTRow<ProblemDTO> {
|
||||||
rootWidth: number;
|
rootWidth: number;
|
||||||
@@ -96,16 +96,16 @@ export class ProblemDetails extends PureComponent<ProblemDetailsProps, ProblemDe
|
|||||||
</div>
|
</div>
|
||||||
{problem.items && <ProblemItems items={problem.items} />}
|
{problem.items && <ProblemItems items={problem.items} />}
|
||||||
</div>
|
</div>
|
||||||
<ExploreButton problem={problem} panelId={this.props.panelId} />
|
<div className="problem-actions-left">
|
||||||
|
<ExploreButton problem={problem} panelId={this.props.panelId} />
|
||||||
|
</div>
|
||||||
<ProblemStatusBar problem={problem} alerts={alerts} className={compactStatusBar && 'compact'} />
|
<ProblemStatusBar problem={problem} alerts={alerts} className={compactStatusBar && 'compact'} />
|
||||||
{problem.showAckButton &&
|
{problem.showAckButton &&
|
||||||
<div className="problem-actions">
|
<div className="problem-actions">
|
||||||
<ModalController>
|
<ModalController>
|
||||||
{({ showModal, hideModal }) => (
|
{({ showModal, hideModal }) => (
|
||||||
<ProblemActionButton
|
<AckButton
|
||||||
className="navbar-button navbar-button--settings"
|
className="navbar-button navbar-button--settings"
|
||||||
icon="reply-all"
|
|
||||||
tooltip="Acknowledge problem"
|
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
showModal(AckModal, {
|
showModal(AckModal, {
|
||||||
canClose: problem.manual_close === '1',
|
canClose: problem.manual_close === '1',
|
||||||
@@ -241,33 +241,3 @@ class ProblemHosts extends PureComponent<ProblemHostsProps> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ProblemActionButtonProps {
|
|
||||||
icon: string;
|
|
||||||
tooltip?: string;
|
|
||||||
className?: string;
|
|
||||||
onClick?: (event?) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
class ProblemActionButton extends PureComponent<ProblemActionButtonProps> {
|
|
||||||
handleClick = (event) => {
|
|
||||||
this.props.onClick(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { icon, tooltip, className } = this.props;
|
|
||||||
let button = (
|
|
||||||
<button className={`btn problem-action-button ${className || ''}`} onClick={this.handleClick}>
|
|
||||||
<FAIcon icon={icon} />
|
|
||||||
</button>
|
|
||||||
);
|
|
||||||
if (tooltip) {
|
|
||||||
button = (
|
|
||||||
<Tooltip placement="bottom" content={tooltip}>
|
|
||||||
{button}
|
|
||||||
</Tooltip>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return button;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -339,51 +339,8 @@
|
|||||||
margin-left: 1.6rem;
|
margin-left: 1.6rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.problem-action-button {
|
.problem-actions-left {
|
||||||
&.btn {
|
margin-right: 1.6rem;
|
||||||
width: 3rem;
|
|
||||||
height: 2rem;
|
|
||||||
align-items: baseline;
|
|
||||||
|
|
||||||
background-image: none;
|
|
||||||
background-color: $action-button-color;
|
|
||||||
border: 1px solid darken($action-button-color, 6%);
|
|
||||||
border-radius: 1px;
|
|
||||||
|
|
||||||
span {
|
|
||||||
color: $action-button-text-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: darken($action-button-color, 4%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.problem-explore-button {
|
|
||||||
&.btn {
|
|
||||||
width: 6rem;
|
|
||||||
height: 2rem;
|
|
||||||
|
|
||||||
background-image: none;
|
|
||||||
background-color: $action-button-color;
|
|
||||||
border: 1px solid darken($action-button-color, 6%);
|
|
||||||
border-radius: 1px;
|
|
||||||
|
|
||||||
margin-right: 1.6rem;
|
|
||||||
|
|
||||||
span {
|
|
||||||
color: $action-button-text-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
i {
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: darken($action-button-color, 4%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.problem-details-middle {
|
.problem-details-middle {
|
||||||
|
|||||||
Reference in New Issue
Block a user