import { css } from '@emotion/css'; import React, { useMemo, useState } from 'react'; import { useAsync } from 'react-use'; import { AnnotationQuery, DataSourceInstanceSettings, getDataSourceRef, GrafanaTheme2, SelectableValue, } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { Stack } from '@grafana/experimental'; import { DataSourcePicker, getDataSourceSrv, locationService } from '@grafana/runtime'; import { AnnotationPanelFilter } from '@grafana/schema/src/raw/dashboard/x/dashboard_types.gen'; import { Button, Checkbox, Field, FieldSet, HorizontalGroup, Input, MultiSelect, Select, useStyles2, } from '@grafana/ui'; import { ColorValueEditor } from 'app/core/components/OptionsUI/color'; import config from 'app/core/config'; import StandardAnnotationQueryEditor from 'app/features/annotations/components/StandardAnnotationQueryEditor'; import { DashboardModel } from '../../state/DashboardModel'; import { AngularEditorLoader } from './AngularEditorLoader'; type Props = { editIdx: number; dashboard: DashboardModel; }; export const newAnnotationName = 'New annotation'; export const AnnotationSettingsEdit = ({ editIdx, dashboard }: Props) => { const styles = useStyles2(getStyles); const [annotation, setAnnotation] = useState(dashboard.annotations.list[editIdx]); const panelFilter = useMemo(() => { if (!annotation.filter) { return PanelFilterType.AllPanels; } return annotation.filter.exclude ? PanelFilterType.ExcludePanels : PanelFilterType.IncludePanels; }, [annotation.filter]); const { value: ds } = useAsync(() => { return getDataSourceSrv().get(annotation.datasource); }, [annotation.datasource]); const dsi = getDataSourceSrv().getInstanceSettings(annotation.datasource); const onUpdate = (annotation: AnnotationQuery) => { const list = [...dashboard.annotations.list]; list.splice(editIdx, 1, annotation); setAnnotation(annotation); dashboard.annotations.list = list; }; const onNameChange = (ev: React.FocusEvent) => { onUpdate({ ...annotation, name: ev.currentTarget.value, }); }; const onDataSourceChange = (ds: DataSourceInstanceSettings) => { onUpdate({ ...annotation, datasource: getDataSourceRef(ds), }); }; const onChange = (ev: React.FocusEvent) => { const target = ev.currentTarget; onUpdate({ ...annotation, [target.name]: target.type === 'checkbox' ? target.checked : target.value, }); }; const onColorChange = (color?: string) => { onUpdate({ ...annotation, iconColor: color!, }); }; const onFilterTypeChange = (v: SelectableValue) => { let filter = v.value === PanelFilterType.AllPanels ? undefined : { exclude: v.value === PanelFilterType.ExcludePanels, ids: annotation.filter?.ids ?? [], }; onUpdate({ ...annotation, filter }); }; const onAddFilterPanelID = (selections: Array>) => { if (!Array.isArray(selections)) { return; } const filter: AnnotationPanelFilter = { exclude: panelFilter === PanelFilterType.ExcludePanels, ids: [], }; selections.forEach((selection) => selection.value && filter.ids.push(selection.value)); onUpdate({ ...annotation, filter }); }; const onApply = goBackToList; const onPreview = () => { locationService.partial({ editview: null, editIndex: null }); }; const onDelete = () => { const annotations = dashboard.annotations.list; dashboard.annotations.list = [...annotations.slice(0, editIdx), ...annotations.slice(editIdx + 1)]; goBackToList(); }; const isNewAnnotation = annotation.name === newAnnotationName; const sortFn = (a: SelectableValue, b: SelectableValue) => { if (a.label && b.label) { return a.label.toLowerCase().localeCompare(b.label.toLowerCase()); } return -1; }; const panels: Array> = useMemo( () => dashboard?.panels // Filtering out rows at the moment, revisit to only include panels that support annotations // However the information to know if a panel supports annotations requires it to be already loaded // panel.plugin?.dataSupport?.annotations .filter((panel) => config.panels[panel.type]) .map((panel) => ({ value: panel.id, label: panel.title ?? `Panel ${panel.id}`, description: panel.description, imgUrl: config.panels[panel.type].info.logos.small, })) .sort(sortFn) ?? [], [dashboard] ); return (
<>