Show alerting availability in data source details (#53391)

* Show alerting availability in data source details

* Show tooltip info in data source dropdown when creating an alert

* return earlier in HeaderExtras component

* Use getDataSourceSrv().getInstanceSettings instead of getDataSourceSrv().get to simplify

* Make information icon clickable and open a new window with documentation url
This commit is contained in:
Sonia Aguilar 2022-08-12 15:32:07 +02:00 committed by GitHub
parent fde5147d71
commit f416651842
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 110 additions and 42 deletions

View File

@ -1,6 +1,6 @@
import { css } from '@emotion/css';
import { cloneDeep } from 'lodash';
import React, { FC, ReactNode, useState } from 'react';
import React, { FC, useState } from 'react';
import {
CoreApp,
@ -13,7 +13,7 @@ import {
RelativeTimeRange,
ThresholdsConfig,
} from '@grafana/data';
import { RelativeTimeRangePicker, useStyles2 } from '@grafana/ui';
import { RelativeTimeRangePicker, useStyles2, Tooltip, Icon } from '@grafana/ui';
import { isExpressionQuery } from 'app/features/expressions/guards';
import { QueryEditorRow } from 'app/features/query/components/QueryEditorRow';
import { AlertQuery } from 'app/types/unified-alerting-dto';
@ -58,18 +58,49 @@ export const QueryWrapper: FC<Props> = ({
const isExpression = isExpressionQuery(query.model);
const [pluginId, changePluginId] = useState<SupportedPanelPlugins>(isExpression ? TABLE : TIMESERIES);
const renderTimePicker = (query: AlertQuery, index: number): ReactNode => {
if (isExpressionQuery(query.model) || !onChangeTimeRange) {
return null;
}
function SelectingDataSourceTooltip() {
const styles = useStyles2(getStyles);
return (
<RelativeTimeRangePicker
timeRange={query.relativeTimeRange ?? getDefaultRelativeTimeRange()}
onChange={(range) => onChangeTimeRange(range, index)}
/>
<div className={styles.dsTooltip}>
<Tooltip
content={
<>
Not finding the data source you want? Some data sources are not supported for alerting. Click on the icon
for more information.
</>
}
>
<Icon
name="info-circle"
onClick={() =>
window.open(
' https://grafana.com/docs/grafana/latest/alerting/fundamentals/data-source-alerting/',
'_blank'
)
}
/>
</Tooltip>
</div>
);
};
}
function HeaderExtras({ query, index }: { query: AlertQuery; index: number }) {
if (isExpressionQuery(query.model)) {
return null;
} else {
return (
<>
<SelectingDataSourceTooltip />
{onChangeTimeRange && (
<RelativeTimeRangePicker
timeRange={query.relativeTimeRange ?? getDefaultRelativeTimeRange()}
onChange={(range) => onChangeTimeRange(range, index)}
/>
)}
</>
);
}
}
return (
<div className={styles.wrapper}>
@ -87,7 +118,7 @@ export const QueryWrapper: FC<Props> = ({
onAddQuery={() => onDuplicateQuery(cloneDeep(query))}
onRunQuery={onRunQueries}
queries={queries}
renderHeaderExtras={() => renderTimePicker(query, index)}
renderHeaderExtras={() => <HeaderExtras query={query} index={index} />}
app={CoreApp.UnifiedAlerting}
visualization={
data.state !== LoadingState.NotStarted ? (
@ -118,4 +149,13 @@ const getStyles = (theme: GrafanaTheme2) => ({
border: 1px solid ${theme.colors.border.medium};
border-radius: ${theme.shape.borderRadius(1)};
`,
dsTooltip: css`
display: flex;
align-items: center;
margin-right: ${theme.spacing(2)};
&:hover {
opacity: 0.85;
cursor: pointer;
}
`,
});

View File

@ -1,7 +1,10 @@
import { css } from '@emotion/css';
import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { InlineField, InlineSwitch, Input } from '@grafana/ui';
import { getDataSourceSrv } from '@grafana/runtime';
import { InlineField, InlineSwitch, Input, Badge, useStyles2 } from '@grafana/ui';
export interface Props {
dataSourceName: string;
@ -11,40 +14,65 @@ export interface Props {
}
export function BasicSettings({ dataSourceName, isDefault, onDefaultChange, onNameChange }: Props) {
const ds = getDataSourceSrv()?.getInstanceSettings(dataSourceName);
const hasAlertingEnabled = Boolean(ds?.meta?.alerting ?? false);
return (
<div className="gf-form-group" aria-label="Datasource settings page basic settings">
<div className="gf-form-inline">
{/* Name */}
<div className="gf-form max-width-30">
<InlineField
label="Name"
tooltip="The name is used when you select the data source in panels. The default data source is
<>
<AlertingEnabled enabled={hasAlertingEnabled} />
<div className="gf-form-group" aria-label="Datasource settings page basic settings">
<div className="gf-form-inline">
{/* Name */}
<div className="gf-form max-width-30">
<InlineField
label="Name"
tooltip="The name is used when you select the data source in panels. The default data source is
'preselected in new panels."
grow
>
<Input
id="basic-settings-name"
type="text"
value={dataSourceName}
placeholder="Name"
onChange={(event) => onNameChange(event.currentTarget.value)}
required
aria-label={selectors.pages.DataSource.name}
grow
>
<Input
id="basic-settings-name"
type="text"
value={dataSourceName}
placeholder="Name"
onChange={(event) => onNameChange(event.currentTarget.value)}
required
aria-label={selectors.pages.DataSource.name}
/>
</InlineField>
</div>
{/* Is Default */}
<InlineField label="Default" labelWidth={8}>
<InlineSwitch
id="basic-settings-default"
value={isDefault}
onChange={(event: React.FormEvent<HTMLInputElement>) => {
onDefaultChange(event.currentTarget.checked);
}}
/>
</InlineField>
</div>
{/* Is Default */}
<InlineField label="Default" labelWidth={8}>
<InlineSwitch
id="basic-settings-default"
value={isDefault}
onChange={(event: React.FormEvent<HTMLInputElement>) => {
onDefaultChange(event.currentTarget.checked);
}}
/>
</InlineField>
</div>
</>
);
}
export function AlertingEnabled({ enabled }: { enabled: boolean }) {
const styles = useStyles2(getStyles);
return (
<div className={styles.badge}>
{enabled ? (
<Badge color="green" icon="check-circle" text="Alerting supported" />
) : (
<Badge color="orange" icon="exclamation-triangle" text="Alerting not supported" />
)}
</div>
);
}
const getStyles = (theme: GrafanaTheme2) => ({
badge: css`
margin-bottom: ${theme.spacing(2)};
`,
});