mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
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:
parent
fde5147d71
commit
f416651842
@ -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;
|
||||
}
|
||||
`,
|
||||
});
|
||||
|
@ -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)};
|
||||
`,
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user