2021-08-31 23:14:21 -05:00
|
|
|
import { css, cx } from '@emotion/css';
|
2023-01-12 03:10:09 -06:00
|
|
|
import React from 'react';
|
2022-04-22 08:33:13 -05:00
|
|
|
|
2021-07-16 14:48:47 -05:00
|
|
|
import { DataLink, GrafanaTheme2, PanelData } from '@grafana/data';
|
2020-04-27 02:09:05 -05:00
|
|
|
import { selectors } from '@grafana/e2e-selectors';
|
2023-08-25 13:56:02 -05:00
|
|
|
import { config, reportInteraction } from '@grafana/runtime';
|
2022-07-06 02:33:25 -05:00
|
|
|
import { Icon, useStyles2, ClickOutsideWrapper } from '@grafana/ui';
|
2019-01-31 01:56:17 -06:00
|
|
|
import { DashboardModel } from 'app/features/dashboard/state/DashboardModel';
|
|
|
|
import { PanelModel } from 'app/features/dashboard/state/PanelModel';
|
2021-11-10 04:05:36 -06:00
|
|
|
import { getPanelLinksSupplier } from 'app/features/panel/panellinks/linkSuppliers';
|
2022-04-22 08:33:13 -05:00
|
|
|
|
|
|
|
import PanelHeaderCorner from './PanelHeaderCorner';
|
2021-02-08 23:05:34 -06:00
|
|
|
import { PanelHeaderLoadingIndicator } from './PanelHeaderLoadingIndicator';
|
2022-04-22 08:33:13 -05:00
|
|
|
import { PanelHeaderMenuTrigger } from './PanelHeaderMenuTrigger';
|
2021-02-08 23:05:34 -06:00
|
|
|
import { PanelHeaderMenuWrapper } from './PanelHeaderMenuWrapper';
|
2022-04-22 08:33:13 -05:00
|
|
|
import { PanelHeaderNotices } from './PanelHeaderNotices';
|
2018-11-07 06:55:02 -06:00
|
|
|
|
|
|
|
export interface Props {
|
|
|
|
panel: PanelModel;
|
|
|
|
dashboard: DashboardModel;
|
2018-12-05 07:57:57 -06:00
|
|
|
title?: string;
|
|
|
|
description?: string;
|
2019-06-25 04:38:51 -05:00
|
|
|
links?: DataLink[];
|
2019-02-12 10:01:07 -06:00
|
|
|
error?: string;
|
2020-04-12 15:20:02 -05:00
|
|
|
alertState?: string;
|
2020-04-10 09:37:26 -05:00
|
|
|
isViewing: boolean;
|
|
|
|
isEditing: boolean;
|
2020-03-18 07:00:14 -05:00
|
|
|
data: PanelData;
|
2018-10-25 05:47:09 -05:00
|
|
|
}
|
2020-11-05 10:03:34 -06:00
|
|
|
|
2023-01-12 03:10:09 -06:00
|
|
|
export function PanelHeader({ panel, error, isViewing, isEditing, data, alertState, dashboard }: Props) {
|
2021-02-08 23:05:34 -06:00
|
|
|
const onCancelQuery = () => panel.getQueryRunner().cancelQuery();
|
2021-03-15 02:44:13 -05:00
|
|
|
const title = panel.getDisplayTitle();
|
2021-02-08 23:05:34 -06:00
|
|
|
const className = cx('panel-header', !(isViewing || isEditing) ? 'grid-drag-handle' : '');
|
2021-07-16 14:48:47 -05:00
|
|
|
const styles = useStyles2(panelStyles);
|
2021-02-08 23:05:34 -06:00
|
|
|
|
2023-04-28 05:19:39 -05:00
|
|
|
const onOpenMenu = () => {
|
|
|
|
reportInteraction('dashboards_panelheader_menu', { item: 'menu' });
|
|
|
|
};
|
|
|
|
|
2021-02-08 23:05:34 -06:00
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<PanelHeaderLoadingIndicator state={data.state} onClick={onCancelQuery} />
|
2021-07-26 12:19:07 -05:00
|
|
|
<PanelHeaderCorner
|
|
|
|
panel={panel}
|
|
|
|
title={panel.title}
|
|
|
|
description={panel.description}
|
|
|
|
scopedVars={panel.scopedVars}
|
|
|
|
links={getPanelLinksSupplier(panel)}
|
|
|
|
error={error}
|
|
|
|
/>
|
2021-02-08 23:05:34 -06:00
|
|
|
<div className={className}>
|
2023-04-28 05:19:39 -05:00
|
|
|
<PanelHeaderMenuTrigger data-testid={selectors.components.Panels.Panel.title(title)} onOpenMenu={onOpenMenu}>
|
2021-02-08 23:05:34 -06:00
|
|
|
{({ closeMenu, panelMenuOpen }) => {
|
|
|
|
return (
|
2022-07-06 02:33:25 -05:00
|
|
|
<ClickOutsideWrapper onClick={closeMenu} parent={document}>
|
|
|
|
<div className="panel-title">
|
|
|
|
<PanelHeaderNotices frames={data.series} panelId={panel.id} />
|
|
|
|
{alertState ? (
|
|
|
|
<Icon
|
|
|
|
name={alertState === 'alerting' ? 'heart-break' : 'heart'}
|
|
|
|
className="icon-gf panel-alert-icon"
|
|
|
|
style={{ marginRight: '4px' }}
|
|
|
|
size="sm"
|
2022-06-02 15:57:55 -05:00
|
|
|
/>
|
2022-07-06 02:33:25 -05:00
|
|
|
) : null}
|
|
|
|
<h2 className={styles.titleText}>{title}</h2>
|
2023-08-25 13:56:02 -05:00
|
|
|
{!config.publicDashboardAccessToken && (
|
2022-07-06 02:33:25 -05:00
|
|
|
<div data-testid="panel-dropdown">
|
|
|
|
<Icon name="angle-down" className="panel-menu-toggle" />
|
2023-02-23 22:23:56 -06:00
|
|
|
{panelMenuOpen ? <PanelHeaderMenuWrapper panel={panel} dashboard={dashboard} /> : null}
|
2022-07-06 02:33:25 -05:00
|
|
|
</div>
|
|
|
|
)}
|
|
|
|
{data.request && data.request.timeInfo && (
|
|
|
|
<span className="panel-time-info">
|
|
|
|
<Icon name="clock-nine" size="sm" /> {data.request.timeInfo}
|
|
|
|
</span>
|
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
</ClickOutsideWrapper>
|
2021-02-08 23:05:34 -06:00
|
|
|
);
|
|
|
|
}}
|
|
|
|
</PanelHeaderMenuTrigger>
|
|
|
|
</div>
|
|
|
|
</>
|
|
|
|
);
|
2023-01-12 03:10:09 -06:00
|
|
|
}
|
2021-07-16 14:48:47 -05:00
|
|
|
|
|
|
|
const panelStyles = (theme: GrafanaTheme2) => {
|
|
|
|
return {
|
|
|
|
titleText: css`
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
overflow: hidden;
|
|
|
|
white-space: nowrap;
|
|
|
|
max-width: calc(100% - 38px);
|
|
|
|
cursor: pointer;
|
|
|
|
font-weight: ${theme.typography.fontWeightMedium};
|
|
|
|
font-size: ${theme.typography.body.fontSize};
|
|
|
|
margin: 0;
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
color: ${theme.colors.text.primary};
|
|
|
|
}
|
|
|
|
.panel-has-alert & {
|
|
|
|
max-width: calc(100% - 54px);
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
};
|
|
|
|
};
|