From 270ceeaeaf3e96f44b110c8154634709bd3a09a8 Mon Sep 17 00:00:00 2001 From: Rares Mardare Date: Mon, 3 Jun 2024 15:36:02 +0300 Subject: [PATCH 1/5] Theming backwards compatibility (#4438) # What this PR does Closes https://github.com/grafana/oncall/issues/4437 --- .../src/containers/IntegrationForm/IntegrationForm.styles.ts | 2 +- grafana-plugin/src/containers/Rotations/Rotations.styles.ts | 2 +- .../src/containers/ServiceNowConfigDrawer/ServiceNow.styles.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/grafana-plugin/src/containers/IntegrationForm/IntegrationForm.styles.ts b/grafana-plugin/src/containers/IntegrationForm/IntegrationForm.styles.ts index 5a472663d5..e231473c71 100644 --- a/grafana-plugin/src/containers/IntegrationForm/IntegrationForm.styles.ts +++ b/grafana-plugin/src/containers/IntegrationForm/IntegrationForm.styles.ts @@ -11,7 +11,7 @@ export const getIntegrationFormStyles = (theme: GrafanaTheme2) => { padding: 12px; margin-bottom: 24px; border: 1px solid ${theme.colors.border.weak}; - border-radius: ${theme.shape.radius.default}; + border-radius: 2px; `, extraFieldsRadio: css` diff --git a/grafana-plugin/src/containers/Rotations/Rotations.styles.ts b/grafana-plugin/src/containers/Rotations/Rotations.styles.ts index c0f9104679..717b522257 100644 --- a/grafana-plugin/src/containers/Rotations/Rotations.styles.ts +++ b/grafana-plugin/src/containers/Rotations/Rotations.styles.ts @@ -8,7 +8,7 @@ export const getRotationsStyles = (theme: GrafanaTheme2) => { border: 1px solid ${theme.colors.border.weak}; display: flex; flex-direction: column; - border-radius: ${theme.shape.radius.default}; + border-radius: 2px; &--withNoBackgroundAndBorder { background: none; diff --git a/grafana-plugin/src/containers/ServiceNowConfigDrawer/ServiceNow.styles.ts b/grafana-plugin/src/containers/ServiceNowConfigDrawer/ServiceNow.styles.ts index b65d12c1b0..d47a3f9074 100644 --- a/grafana-plugin/src/containers/ServiceNowConfigDrawer/ServiceNow.styles.ts +++ b/grafana-plugin/src/containers/ServiceNowConfigDrawer/ServiceNow.styles.ts @@ -7,7 +7,7 @@ export const getCommonServiceNowConfigStyles = (theme: GrafanaTheme2) => { padding: 12px; margin-bottom: 24px; border: 1px solid ${theme.colors.border.weak}; - border-radius: ${theme.shape.radius.default}; + border-radius: 2px; `, tokenContainer: css` From cca2d0d960be1fe65bc454d8a648c09526b6f7a4 Mon Sep 17 00:00:00 2001 From: Rares Mardare Date: Mon, 3 Jun 2024 15:46:17 +0300 Subject: [PATCH 2/5] Allow user unset the escalation chain on the integration (#4436) # What this PR does - Allow user unset the escalation chain on the integration ## Which issue(s) this PR closes Closes https://github.com/grafana/oncall/issues/4434 --- .../ExpandedIntegrationRouteDisplay.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.tsx b/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.tsx index a71a7cc605..f4caea5691 100644 --- a/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.tsx +++ b/grafana-plugin/src/containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay.tsx @@ -218,6 +218,7 @@ export const ExpandedIntegrationRouteDisplay: React.FC { } renderTimeRange() { - const { data, isDisabled } = this.props; + const { data, isDisabled, theme } = this.props; + const styles = getEscalationPolicyStyles(theme); return ( @@ -260,46 +253,58 @@ class _EscalationPolicy extends React.Component { to={data.to_time} disabled={isDisabled} onChange={this.getOnTimeRangeChangeHandler()} - className={cx(this.styles.select, this.styles.control)} + className={cx(styles.select, styles.control)} /> ); } renderWaitDelays() { - const { data, isDisabled, waitDelays = [] } = this.props; + const { data, isDisabled, theme } = this.props; const { wait_delay } = data; + const styles = getEscalationPolicyStyles(theme); + const silenceOptions: SelectableValue[] = [...POLICY_DURATION_LIST_MINUTES]; + + const waitDelayInSeconds = wait_delay ? parseFloat(wait_delay) : 0; + const waitDelayInMinutes = waitDelayInSeconds / 60; + + const waitDelayOptionItem = silenceOptions.find((opt) => opt.value === waitDelayInMinutes) || { + value: waitDelayInMinutes, + label: waitDelayInMinutes, + }; // either find it in the list or initialize it to show in the dropdown + return ( { @@ -314,8 +319,16 @@ class _EscalationPolicy extends React.Component { } renderNumMinutesInWindowOptions() { - const { data, isDisabled, numMinutesInWindowOptions = [] } = this.props; + const { data, isDisabled, theme } = this.props; const { num_minutes_in_window } = data; + const styles = getEscalationPolicyStyles(theme); + + const options: SelectableValue[] = [...POLICY_DURATION_LIST_MINUTES]; + + const optionValue = options.find((opt) => opt.value === num_minutes_in_window) || { + value: num_minutes_in_window, + label: num_minutes_in_window, + }; // either find it in the list or initialize it to show in the dropdown return ( @@ -323,14 +336,12 @@ class _EscalationPolicy extends React.Component { menuShouldPortal disabled={isDisabled} placeholder="Period" - className={cx(this.styles.select, this.styles.control)} - // @ts-ignore - value={num_minutes_in_window} + className={cx(styles.select, styles.control)} + value={num_minutes_in_window ? optionValue : undefined} onChange={this.getOnSelectChangeHandler('num_minutes_in_window')} - options={numMinutesInWindowOptions.map((waitDelay: SelectOption) => ({ - value: waitDelay.value, - label: waitDelay.display_name, - }))} + allowCustomValue + onCreateOption={(option) => this.onCreateOption('num_minutes_in_window', option)} + options={options} /> ); @@ -339,10 +350,12 @@ class _EscalationPolicy extends React.Component { renderNotifySchedule() { const { data, + theme, isDisabled, store: { grafanaTeamStore, scheduleStore }, } = this.props; const { notify_schedule } = data; + const styles = getEscalationPolicyStyles(theme); return ( @@ -356,7 +369,7 @@ class _EscalationPolicy extends React.Component { displayField="name" valueField="id" placeholder="Select Schedule" - className={cx(this.styles.select, this.styles.control)} + className={cx(styles.select, styles.control)} value={notify_schedule} onChange={this.getOnChangeHandler('notify_schedule')} getOptionLabel={(item: SelectableValue) => { @@ -376,10 +389,13 @@ class _EscalationPolicy extends React.Component { renderNotifyUserGroup() { const { data, + theme, isDisabled, store: { userGroupStore }, } = this.props; + const { notify_to_group } = data; + const styles = getEscalationPolicyStyles(theme); return ( @@ -393,7 +409,7 @@ class _EscalationPolicy extends React.Component { displayField="name" valueField="id" placeholder="Select User Group" - className={cx(this.styles.select, this.styles.control)} + className={cx(styles.select, styles.control)} value={notify_to_group} onChange={this.getOnChangeHandler('notify_to_group')} width={'auto'} @@ -405,10 +421,13 @@ class _EscalationPolicy extends React.Component { renderTriggerCustomWebhook() { const { data, + theme, isDisabled, store: { grafanaTeamStore, outgoingWebhookStore }, } = this.props; + const { custom_webhook } = data; + const styles = getEscalationPolicyStyles(theme); return ( @@ -421,7 +440,7 @@ class _EscalationPolicy extends React.Component { displayField="name" valueField="id" placeholder="Select Webhook" - className={cx(this.styles.select, this.styles.control)} + className={cx(styles.select, styles.control)} value={custom_webhook} onChange={this.getOnChangeHandler('custom_webhook')} getOptionLabel={(item: SelectableValue) => { @@ -471,6 +490,24 @@ class _EscalationPolicy extends React.Component { ); } + onCreateOption = (fieldName: string, option: string, parseToSeconds = false) => { + if (!isNumber(+option)) { + return; + } + + const num = parseFloat(option); + + if (!Number.isInteger(+option)) { + return openWarningNotification('Given number must be an integer'); + } + + if (num < 1 || num > 24 * 60) { + return openWarningNotification('Given number must be in the range of 1 minute and 24 hours'); + } + + this.getOnSelectChangeHandler(fieldName)({ value: num * (parseToSeconds ? 60 : 1) }); + }; + getOnSelectChangeHandler = (field: string) => { return (option: SelectableValue) => { const { data, onChange = () => {} } = this.props; @@ -536,5 +573,5 @@ class _EscalationPolicy extends React.Component { } export const EscalationPolicy = withMobXProviderContext( - SortableElement(withTheme2(_EscalationPolicy)) as React.ComponentClass -); + SortableElement(withTheme2(_EscalationPolicy)) +) as unknown as React.ComponentClass; diff --git a/grafana-plugin/src/components/Policy/NotificationPolicy.tsx b/grafana-plugin/src/components/Policy/NotificationPolicy.tsx index 4e9a5d552a..68308dbe83 100644 --- a/grafana-plugin/src/components/Policy/NotificationPolicy.tsx +++ b/grafana-plugin/src/components/Policy/NotificationPolicy.tsx @@ -3,6 +3,7 @@ import React from 'react'; import { css, cx } from '@emotion/css'; import { GrafanaTheme2, SelectableValue } from '@grafana/data'; import { Button, IconButton, Select, Themeable2, withTheme2 } from '@grafana/ui'; +import { isNumber } from 'lodash'; import { SortableElement } from 'react-sortable-hoc'; import { PluginLink } from 'components/PluginLink/PluginLink'; @@ -15,8 +16,10 @@ import { AppFeature } from 'state/features'; import { RootStore } from 'state/rootStore'; import { SelectOption } from 'state/types'; import { UserAction } from 'utils/authorization/authorization'; +import { openWarningNotification } from 'utils/utils'; import { DragHandle } from './DragHandle'; +import { POLICY_DURATION_LIST_MINUTES, POLICY_DURATION_LIST_SECONDS } from './Policy.consts'; import { PolicyNote } from './PolicyNote'; export interface NotificationPolicyProps extends Themeable2 { @@ -182,24 +185,51 @@ export class NotificationPolicy extends React.Component delay.duration === waitDelayInMinutes) || { + value: waitDelayInMinutes, + label: waitDelayInMinutes, + }; + return ( - this._getOnChangeHandler('wait_delay')({ value: option.value * 60 })} + options={optionsList} + allowCustomValue + onCreateOption={(option: string) => { + if (!isNumber(+option)) { + return; + } + + const num = parseFloat(option); + + if (!Number.isInteger(+option)) { + return openWarningNotification('Given number must be an integer'); + } + + if (num < 1 || num > 24 * 60) { + return openWarningNotification('Given number must be in the range of 1 minute and 24 hours'); + } + + this._getOnChangeHandler('wait_delay')({ value: num * 60 }); + }} + /> + minute(s) + ); } @@ -298,6 +328,17 @@ const getStyles = (_theme: GrafanaTheme2) => { width: 200px !important; flex-shrink: 0; `, + + delay: css` + width: 100px !important; + `, + + container: css` + width: 200px; + display: flex; + align-items: center; + margin-right: 12px; + `, }; }; diff --git a/grafana-plugin/src/components/Policy/Policy.consts.ts b/grafana-plugin/src/components/Policy/Policy.consts.ts new file mode 100644 index 0000000000..7f749666a9 --- /dev/null +++ b/grafana-plugin/src/components/Policy/Policy.consts.ts @@ -0,0 +1,46 @@ +import { SelectableValue } from '@grafana/data'; + +const POLICY_DURATION_LIST: SelectableValue[] = [ + { + value: 1, + label: '1', + }, + { + value: 5, + label: '5', + }, + { + value: 15, + label: '15', + }, + { + value: 30, + label: '30', + }, + { + value: 60, + label: '60', + }, +]; + +// SECONDS +export const POLICY_DURATION_LIST_SECONDS: SelectableValue[] = POLICY_DURATION_LIST.map((item: SelectableValue) => ({ + value: item.value * 60, + label: item.label, +})); + +// MINUTES +export const POLICY_DURATION_LIST_MINUTES: SelectableValue[] = [...POLICY_DURATION_LIST]; + +export const CUSTOM_SILENCE_VALUE = -100; + +export const SILENCE_DURATION_LIST: SelectableValue[] = [ + { value: CUSTOM_SILENCE_VALUE, label: 'Custom' }, + { value: 30 * 60, label: '30 minutes' }, + { value: 1 * 60 * 60, label: '1 hour' }, + { value: 2 * 60 * 60, label: '2 hours' }, + { value: 6 * 60 * 60, label: '6 hours' }, + { value: 12 * 60 * 60, label: '12 hours' }, + { value: 24 * 60 * 60, label: '24 hours' }, + { value: -1, label: 'Forever' }, +]; diff --git a/grafana-plugin/src/containers/EscalationChainSteps/EscalationChainSteps.tsx b/grafana-plugin/src/containers/EscalationChainSteps/EscalationChainSteps.tsx index 97ae2cd43f..f3e324262a 100644 --- a/grafana-plugin/src/containers/EscalationChainSteps/EscalationChainSteps.tsx +++ b/grafana-plugin/src/containers/EscalationChainSteps/EscalationChainSteps.tsx @@ -4,7 +4,6 @@ import { css } from '@emotion/css'; import { GrafanaTheme2 } from '@grafana/data'; import { LoadingPlaceholder, Select, useStyles2, useTheme2 } from '@grafana/ui'; import cn from 'classnames/bind'; -import { get } from 'lodash-es'; import { observer } from 'mobx-react'; import { getLabelBackgroundTextColorObject } from 'styles/utils.styles'; @@ -51,8 +50,6 @@ export const EscalationChainSteps = observer((props: EscalationChainStepsProps) useEffect(() => { escalationPolicyStore.updateWebEscalationPolicyOptions(); - escalationPolicyStore.updateEscalationPolicyOptions(); - escalationPolicyStore.updateNumMinutesInWindowOptions(); }, []); const handleSortEnd = useCallback( @@ -107,14 +104,9 @@ export const EscalationChainSteps = observer((props: EscalationChainStepsProps) data={escalationPolicy} number={index + offset + 1} escalationChoices={escalationPolicyStore.webEscalationChoices} - waitDelays={get(escalationPolicyStore.escalationChoices, 'wait_delay.choices', [])} - numMinutesInWindowOptions={escalationPolicyStore.numMinutesInWindowOptions} onChange={escalationPolicyStore.saveEscalationPolicy.bind(escalationPolicyStore)} onDelete={escalationPolicyStore.deleteEscalationPolicy.bind(escalationPolicyStore)} isSlackInstalled={isSlackInstalled} - teamStore={store.grafanaTeamStore} - scheduleStore={store.scheduleStore} - outgoingWebhookStore={store.outgoingWebhookStore} isDisabled={isDisabled} {...extraProps} /> diff --git a/grafana-plugin/src/models/alertgroup/alertgroup.ts b/grafana-plugin/src/models/alertgroup/alertgroup.ts index abb53c14b3..8241213a50 100644 --- a/grafana-plugin/src/models/alertgroup/alertgroup.ts +++ b/grafana-plugin/src/models/alertgroup/alertgroup.ts @@ -24,7 +24,6 @@ export class AlertGroupStore { rootStore: RootStore; alerts = new Map(); bulkActions: any = []; - silenceOptions: Array; searchResult: { [key: string]: Array } = {}; incidentFilters: any; initialQuery = qs.parse(window.location.search); @@ -126,14 +125,6 @@ export class AlertGroupStore { this.setLiveUpdatesPaused(false); } - async fetchSilenceOptions() { - const { data } = await onCallApi().GET('/alertgroups/silence_options/', undefined); - - runInAction(() => { - this.silenceOptions = data; - }); - } - @AutoLoadingState(ActionKey.RESET_COLUMNS_FROM_ALERT_GROUP) @WithGlobalNotification({ success: 'Columns list has been reset' }) async resetColumns() { diff --git a/grafana-plugin/src/models/escalation_policy/escalation_policy.ts b/grafana-plugin/src/models/escalation_policy/escalation_policy.ts index 81b394ee84..20801ccda5 100644 --- a/grafana-plugin/src/models/escalation_policy/escalation_policy.ts +++ b/grafana-plugin/src/models/escalation_policy/escalation_policy.ts @@ -1,4 +1,3 @@ -import { get } from 'lodash-es'; import { action, observable, makeObservable, runInAction } from 'mobx'; import { BaseStore } from 'models/base_store'; @@ -7,7 +6,6 @@ import { EscalationPolicy } from 'models/escalation_policy/escalation_policy.typ import { makeRequest } from 'network/network'; import { move } from 'state/helpers'; import { RootStore } from 'state/rootStore'; -import { SelectOption } from 'state/types'; export class EscalationPolicyStore extends BaseStore { @observable.shallow @@ -21,9 +19,6 @@ export class EscalationPolicyStore extends BaseStore { @observable escalationChoices: any = []; - @observable - numMinutesInWindowOptions: SelectOption[] = []; - @observable webEscalationChoices: any = []; @@ -44,26 +39,6 @@ export class EscalationPolicyStore extends BaseStore { }); } - @action.bound - async updateEscalationPolicyOptions() { - const response = await makeRequest('/escalation_policies/', { - method: 'OPTIONS', - }); - - runInAction(() => { - this.escalationChoices = get(response, 'actions.POST', []); - }); - } - - @action.bound - async updateNumMinutesInWindowOptions() { - const response = await makeRequest('/escalation_policies/num_minutes_in_window_options/', {}); - - runInAction(() => { - this.numMinutesInWindowOptions = response; - }); - } - @action.bound async updateEscalationPolicies(escalationChainId: EscalationChain['id']) { const response = await makeRequest(this.path, { diff --git a/grafana-plugin/src/pages/incident/Incident.tsx b/grafana-plugin/src/pages/incident/Incident.tsx index 94c838f428..d3c6bdd3a5 100644 --- a/grafana-plugin/src/pages/incident/Incident.tsx +++ b/grafana-plugin/src/pages/incident/Incident.tsx @@ -40,6 +40,7 @@ import { initErrorDataState, } from 'components/PageErrorHandlingWrapper/PageErrorHandlingWrapper.helpers'; import { PluginLink } from 'components/PluginLink/PluginLink'; +import { CUSTOM_SILENCE_VALUE } from 'components/Policy/Policy.consts'; import { RenderConditionally } from 'components/RenderConditionally/RenderConditionally'; import { SourceCode } from 'components/SourceCode/SourceCode'; import { Text } from 'components/Text/Text'; @@ -54,7 +55,7 @@ import { AlertGroupHelper } from 'models/alertgroup/alertgroup.helpers'; import { AlertAction, TimeLineItem, TimeLineRealm, GroupedAlert } from 'models/alertgroup/alertgroup.types'; import { ResolutionNoteSourceTypesToDisplayName } from 'models/resolution_note/resolution_note.types'; import { ApiSchemas } from 'network/oncall-api/api.types'; -import { CUSTOM_SILENCE_VALUE, IncidentDropdown } from 'pages/incidents/parts/IncidentDropdown'; +import { IncidentDropdown } from 'pages/incidents/parts/IncidentDropdown'; import { IncidentSilenceModal } from 'pages/incidents/parts/IncidentSilenceModal'; import { AppFeature } from 'state/features'; import { PageProps, WithStoreProps } from 'state/types'; @@ -92,11 +93,7 @@ class _IncidentPage extends React.Component ( this.setState({ silenceModalData: undefined })} diff --git a/grafana-plugin/src/pages/incidents/Incidents.tsx b/grafana-plugin/src/pages/incidents/Incidents.tsx index ed7d2cfb3d..1924e014c4 100644 --- a/grafana-plugin/src/pages/incidents/Incidents.tsx +++ b/grafana-plugin/src/pages/incidents/Incidents.tsx @@ -148,7 +148,6 @@ class _IncidentsPage extends React.Component Promise; @@ -199,7 +198,6 @@ export const IncidentDropdown: FC<{
} setIsSilenceModalOpen(false)} diff --git a/grafana-plugin/src/pages/incidents/parts/IncidentSilenceModal.tsx b/grafana-plugin/src/pages/incidents/parts/IncidentSilenceModal.tsx index baf804ff72..c959d2663e 100644 --- a/grafana-plugin/src/pages/incidents/parts/IncidentSilenceModal.tsx +++ b/grafana-plugin/src/pages/incidents/parts/IncidentSilenceModal.tsx @@ -1,6 +1,6 @@ import React, { useState } from 'react'; -import { css } from '@emotion/css'; +import { css, cx } from '@emotion/css'; import { DateTime, addDurationToDate, @@ -11,18 +11,26 @@ import { parseDuration, } from '@grafana/data'; import { Button, DateTimePicker, Field, HorizontalGroup, Input, Modal, useStyles2 } from '@grafana/ui'; +import { Controller, useForm } from 'react-hook-form'; +import { bem, getUtilStyles } from 'styles/utils.styles'; +import { Text } from 'components/Text/Text'; import { useDebouncedCallback } from 'utils/hooks'; +import { openWarningNotification } from 'utils/utils'; interface IncidentSilenceModalProps { isOpen: boolean; - alertGroupID: string; + alertGroupID: number; alertGroupName: string; onDismiss: () => void; onSave: (value: number) => void; } +interface FormFields { + duration: string; +} + const IncidentSilenceModal: React.FC = ({ isOpen, alertGroupID, @@ -31,66 +39,118 @@ const IncidentSilenceModal: React.FC = ({ onDismiss, onSave, }) => { - const [date, setDate] = useState(dateTime('2021-05-05 12:00:00')); - const [duration, setDuration] = useState(''); + const [date, setDate] = useState(dateTime()); const debouncedUpdateDateTime = useDebouncedCallback(updateDateTime, 500); const styles = useStyles2(getStyles); - const isDurationValid = isValidDuration(duration); + const utilStyles = useStyles2(getUtilStyles); + + const { + control, + setValue, + getValues, + handleSubmit, + formState: { errors }, + } = useForm({ + mode: 'onSubmit', + }); return ( + Silence alert group #${alertGroupID} ${alertGroupName} + + } className={styles.root} > -
- - - - - - - -
- - - - - +
+
+ +
+ +
+
+ + { + return value?.trim() && isValidDuration(value) ? true : 'Duration is invalid'; + }, + }} + render={({ field }) => ( + + ) => { + const newDuration: string = event.currentTarget.value; + field.onChange(newDuration); + + debouncedUpdateDateTime(newDuration); + }} + placeholder="Enter duration (2h 30m)" + /> + + )} + /> +
+ + + + + +
); - function onDateChange(date: DateTime) { - setDate(date); + function onFormSubmit() { + onSave(durationToMilliseconds(parseDuration(getValues('duration'))) / 1000); + } + + function onDateChange(newDate: DateTime) { const duration = intervalToAbbreviatedDurationString({ start: new Date(), - end: new Date(date.toDate()), + end: new Date(newDate.toDate()), }); - setDuration(duration); - } - function onDurationChange(event: React.SyntheticEvent) { - const newDuration = event.currentTarget.value; - if (newDuration !== duration) { - setDuration(newDuration); - debouncedUpdateDateTime(newDuration); + if (!duration) { + openWarningNotification('Silence Date is either invalid or in the past'); + } else { + setDate(newDate); + setValue('duration', duration); } } function updateDateTime(newDuration: string) { setDate(dateTime(addDurationToDate(new Date(), parseDuration(newDuration)))); } - - function onSubmit() { - onSave(durationToMilliseconds(parseDuration(duration)) / 1000); - } }; const getStyles = () => ({ @@ -101,10 +161,15 @@ const getStyles = () => ({ container: css` width: 100%; display: flex; - column-gap: 16px; + column-gap: 8px; `, containerChild: css` - flex-grow: 1; + flex-basis: 50%; + `, + datePicker: css` + label { + display: none; + } `, }); diff --git a/grafana-plugin/src/pages/incidents/parts/SilenceButtonCascader.tsx b/grafana-plugin/src/pages/incidents/parts/SilenceButtonCascader.tsx index 89056dee86..7b1b2064c1 100644 --- a/grafana-plugin/src/pages/incidents/parts/SilenceButtonCascader.tsx +++ b/grafana-plugin/src/pages/incidents/parts/SilenceButtonCascader.tsx @@ -3,13 +3,10 @@ import React from 'react'; import { ButtonCascader, CascaderOption, ComponentSize } from '@grafana/ui'; import { observer } from 'mobx-react'; +import { SILENCE_DURATION_LIST } from 'components/Policy/Policy.consts'; import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip'; -import { SelectOption } from 'state/types'; -import { useStore } from 'state/useStore'; import { UserActions } from 'utils/authorization/authorization'; -import { CUSTOM_SILENCE_VALUE } from './IncidentDropdown'; - interface SilenceButtonCascaderProps { className?: string; disabled?: boolean; @@ -20,9 +17,6 @@ interface SilenceButtonCascaderProps { export const SilenceButtonCascader = observer((props: SilenceButtonCascaderProps) => { const { onSelect, className, disabled = false, buttonSize } = props; - const { alertGroupStore } = useStore(); - - const silenceOptions = alertGroupStore.silenceOptions || []; return ( @@ -41,14 +35,6 @@ export const SilenceButtonCascader = observer((props: SilenceButtonCascaderProps ); function getOptions(): CascaderOption[] { - return silenceOptions - .map((silenceOption: SelectOption) => ({ - value: silenceOption.value, - label: silenceOption.display_name, - })) - .concat({ - value: CUSTOM_SILENCE_VALUE, - label: 'Custom', - }) as CascaderOption[]; + return [...SILENCE_DURATION_LIST] as CascaderOption[]; } }); diff --git a/grafana-plugin/src/pages/incidents/parts/SilenceSelect.tsx b/grafana-plugin/src/pages/incidents/parts/SilenceSelect.tsx index fd83a7dd47..f78a2e78b5 100644 --- a/grafana-plugin/src/pages/incidents/parts/SilenceSelect.tsx +++ b/grafana-plugin/src/pages/incidents/parts/SilenceSelect.tsx @@ -3,26 +3,18 @@ import React from 'react'; import { Select } from '@grafana/ui'; import { observer } from 'mobx-react'; +import { SILENCE_DURATION_LIST } from 'components/Policy/Policy.consts'; import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip'; -import { SelectOption } from 'state/types'; -import { useStore } from 'state/useStore'; import { UserActions } from 'utils/authorization/authorization'; interface SilenceSelectProps { placeholder?: string; - customValueNum: number; onSelect: (value: number) => void; } export const SilenceSelect = observer((props: SilenceSelectProps) => { - const { customValueNum, placeholder = 'Silence for', onSelect } = props; - - const store = useStore(); - - const { alertGroupStore } = store; - - const silenceOptions = alertGroupStore.silenceOptions || []; + const { placeholder = 'Silence for', onSelect } = props; return ( <> @@ -42,14 +34,6 @@ export const SilenceSelect = observer((props: SilenceSelectProps) => { ); function getOptions() { - return silenceOptions - .map((silenceOption: SelectOption) => ({ - value: silenceOption.value, - label: silenceOption.display_name, - })) - .concat({ - value: customValueNum, - label: 'Custom', - }); + return [...SILENCE_DURATION_LIST]; } }); From 3566de38b9907a915187286311d302003e34a783 Mon Sep 17 00:00:00 2001 From: Levente Balogh Date: Mon, 3 Jun 2024 15:21:01 +0200 Subject: [PATCH 4/5] Plugin.json: update with extensions info (#4407) ### What changed? - Manually added ui-extensions metadata to the plugin.json (to be able to lazy-load plugins in Grafana, based on [this PR](https://github.com/grafana/grafana/pull/88288) --- grafana-plugin/src/plugin.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/grafana-plugin/src/plugin.json b/grafana-plugin/src/plugin.json index ed3dba004d..831866cfed 100644 --- a/grafana-plugin/src/plugin.json +++ b/grafana-plugin/src/plugin.json @@ -592,5 +592,13 @@ "dependencies": { "grafanaDependency": ">=9.2.0", "plugins": [] - } + }, + "extensions": [ + { + "extensionPointId": "grafana/user/profile/tab", + "title": "IRM", + "description": "IRM settings", + "type": "component" + } + ] } From 66f807a6712635ab3f7852724eed5b71f991cc23 Mon Sep 17 00:00:00 2001 From: Dominik Broj Date: Mon, 3 Jun 2024 16:14:16 +0200 Subject: [PATCH 5/5] Fix escaping quotes in Insights queries (#4442) # What this PR does Use backticks to correctly escape quotes in queries ## Which issue(s) this PR closes Closes https://github.com/grafana/oncall/issues/4439 ## Checklist - [ ] Unit, integration, and e2e (if applicable) tests updated - [x] Documentation added (or `pr:no public docs` PR label added if not required) - [x] Added the relevant release notes label (see labels prefixed w/ `release:`). These labels dictate how your PR will show up in the autogenerated release notes. --- .../dashboards/oncall_metrics_dashboard.json | 36 +++++++++---------- .../scenes/AlertGroupsByIntegration.tsx | 2 +- .../insights/scenes/AlertGroupsByTeam.tsx | 2 +- .../pages/insights/scenes/MTTRAverageStat.tsx | 2 +- .../insights/scenes/MTTRByIntegration.tsx | 2 +- .../src/pages/insights/scenes/MTTRByTeam.tsx | 2 +- .../insights/scenes/MTTRChangedTimeseries.tsx | 2 +- .../pages/insights/scenes/NewAlertGroups.tsx | 2 +- .../NewAlertGroupsNotificationsTable.tsx | 2 +- .../NewAlertGroupsNotificationsTimeseries.tsx | 2 +- .../scenes/NewAlertGroupsTimeseries.tsx | 2 +- .../src/pages/insights/variables.ts | 12 +++---- 12 files changed, 34 insertions(+), 34 deletions(-) diff --git a/grafana-plugin/src/dashboards/oncall_metrics_dashboard.json b/grafana-plugin/src/dashboards/oncall_metrics_dashboard.json index aa42406517..1296babbc9 100644 --- a/grafana-plugin/src/dashboards/oncall_metrics_dashboard.json +++ b/grafana-plugin/src/dashboards/oncall_metrics_dashboard.json @@ -182,7 +182,7 @@ "editorMode": "code", "excludeNullMetadata": false, "exemplar": false, - "expr": "round(delta(sum($alert_groups_total{slug=~\"$instance\", team=~\"$team\", integration=~\"$integration\", service_name=~\"$service_name\"})[$__range:])) >= 0", + "expr": "round(delta(sum($alert_groups_total{slug=~`$instance`, team=~`$team`, integration=~`$integration`, service_name=~`$service_name`})[$__range:])) >= 0", "format": "time_series", "fullMetaSearch": false, "includeNullMetadata": true, @@ -266,7 +266,7 @@ }, "editorMode": "code", "exemplar": false, - "expr": "avg_over_time((sum($alert_groups_response_time_seconds_sum{slug=~\"$instance\", team=~\"$team\", integration=~\"$integration\", service_name=~\"$service_name\"}) / sum($alert_groups_response_time_seconds_count{slug=~\"$instance\", team=~\"$team\", integration=~\"$integration\", service_name=~\"$service_name\"}))[$__range:])", + "expr": "avg_over_time((sum($alert_groups_response_time_seconds_sum{slug=~`$instance`, team=~`$team`, integration=~`$integration`, service_name=~`$service_name`}) / sum($alert_groups_response_time_seconds_count{slug=~`$instance`, team=~`$team`, integration=~`$integration`, service_name=~`$service_name`}))[$__range:])", "instant": true, "legendFormat": "__auto", "range": false, @@ -389,7 +389,7 @@ "editorMode": "code", "excludeNullMetadata": false, "exemplar": false, - "expr": "round(delta(sum by (integration) ($alert_groups_total{slug=~\"$instance\", team=~\"$team\", integration=~\"$integration\", service_name=~\"$service_name\"})[$__interval:])) >= 0", + "expr": "round(delta(sum by (integration) ($alert_groups_total{slug=~`$instance`, team=~`$team`, integration=~`$integration`, service_name=~`$service_name`})[$__interval:])) >= 0", "fullMetaSearch": false, "hide": false, "instant": false, @@ -507,7 +507,7 @@ }, "editorMode": "code", "exemplar": false, - "expr": "avg(sum($alert_groups_response_time_seconds_sum{slug=~\"$instance\", team=~\"$team\", integration=~\"$integration\", service_name=~\"$service_name\"}) / sum($alert_groups_response_time_seconds_count{slug=~\"$instance\", team=~\"$team\", integration=~\"$integration\", service_name=~\"$service_name\"}))", + "expr": "avg(sum($alert_groups_response_time_seconds_sum{slug=~`$instance`, team=~`$team`, integration=~`$integration`, service_name=~`$service_name`}) / sum($alert_groups_response_time_seconds_count{slug=~`$instance`, team=~`$team`, integration=~`$integration`, service_name=~`$service_name`}))", "instant": false, "legendFormat": "__auto", "range": true, @@ -613,7 +613,7 @@ }, "editorMode": "code", "exemplar": false, - "expr": "sort_desc(round(delta(sum by (integration)($alert_groups_total{slug=~\"$instance\", team=~\"$team\", integration=~\"$integration\", service_name=~\"$service_name\"})[$__range:])) >= 0)", + "expr": "sort_desc(round(delta(sum by (integration)($alert_groups_total{slug=~`$instance`, team=~`$team`, integration=~`$integration`, service_name=~`$service_name`})[$__range:])) >= 0)", "format": "table", "instant": true, "legendFormat": "__auto", @@ -729,7 +729,7 @@ }, "editorMode": "code", "exemplar": false, - "expr": "sort_desc(avg_over_time((sum by (integration)($alert_groups_response_time_seconds_sum{slug=~\"$instance\", team=~\"$team\", integration=~\"$integration\", service_name=~\"$service_name\"}) / sum by (integration)($alert_groups_response_time_seconds_count{slug=~\"$instance\", team=~\"$team\", integration=~\"$integration\", service_name=~\"$service_name\"}))[$__range:]))", + "expr": "sort_desc(avg_over_time((sum by (integration)($alert_groups_response_time_seconds_sum{slug=~`$instance`, team=~`$team`, integration=~`$integration`, service_name=~`$service_name`}) / sum by (integration)($alert_groups_response_time_seconds_count{slug=~`$instance`, team=~`$team`, integration=~`$integration`, service_name=~`$service_name`}))[$__range:]))", "format": "table", "instant": true, "legendFormat": "__auto", @@ -862,7 +862,7 @@ }, "editorMode": "code", "exemplar": false, - "expr": "sort_desc(round(delta(sum by (team)($alert_groups_total{slug=~\"$instance\", team=~\"$team\", integration=~\"$integration\", service_name=~\"$service_name\"})[$__range:])) >= 0)", + "expr": "sort_desc(round(delta(sum by (team)($alert_groups_total{slug=~`$instance`, team=~`$team`, integration=~`$integration`, service_name=~`$service_name`})[$__range:])) >= 0)", "format": "table", "instant": true, "legendFormat": "__auto", @@ -979,7 +979,7 @@ }, "editorMode": "code", "exemplar": false, - "expr": "sort_desc(avg_over_time((sum by(team) ($alert_groups_response_time_seconds_sum{slug=~\"$instance\", team=~\"$team\", integration=~\"$integration\", service_name=~\"$service_name\"}) / sum by(team)($alert_groups_response_time_seconds_count{slug=~\"$instance\", team=~\"$team\", integration=~\"$integration\", service_name=~\"$service_name\"}))[$__range:]))", + "expr": "sort_desc(avg_over_time((sum by(team) ($alert_groups_response_time_seconds_sum{slug=~`$instance`, team=~`$team`, integration=~`$integration`, service_name=~`$service_name`}) / sum by(team)($alert_groups_response_time_seconds_count{slug=~`$instance`, team=~`$team`, integration=~`$integration`, service_name=~`$service_name`}))[$__range:]))", "format": "table", "instant": true, "legendFormat": "__auto", @@ -1129,7 +1129,7 @@ "editorMode": "code", "excludeNullMetadata": false, "exemplar": false, - "expr": "round(delta(sum by (username)($user_was_notified_of_alert_groups_total{slug=~\"$instance\"})[$__interval:])) >= 0", + "expr": "round(delta(sum by (username)($user_was_notified_of_alert_groups_total{slug=~`$instance`})[$__interval:])) >= 0", "fullMetaSearch": false, "instant": false, "legendFormat": "__auto", @@ -1222,7 +1222,7 @@ }, "editorMode": "code", "exemplar": false, - "expr": "sort_desc(round(delta(sum by (username)($user_was_notified_of_alert_groups_total{slug=~\"$instance\"})[$__range:])) >= 0)", + "expr": "sort_desc(round(delta(sum by (username)($user_was_notified_of_alert_groups_total{slug=~`$instance`})[$__range:])) >= 0)", "format": "table", "instant": true, "legendFormat": "__auto", @@ -1430,7 +1430,7 @@ "type": "prometheus", "uid": "${datasource}" }, - "definition": "label_values(${alert_groups_total}{slug=~\"$instance\"},team)", + "definition": "label_values(${alert_groups_total}{slug=~`$instance`},team)", "hide": 0, "includeAll": true, "label": "Team", @@ -1438,7 +1438,7 @@ "name": "team", "options": [], "query": { - "query": "label_values(${alert_groups_total}{slug=~\"$instance\"},team)", + "query": "label_values(${alert_groups_total}{slug=~`$instance`},team)", "refId": "PrometheusVariableQueryEditor-VariableQuery" }, "refresh": 2, @@ -1458,7 +1458,7 @@ "type": "prometheus", "uid": "${datasource}" }, - "definition": "label_values(${alert_groups_total}{team=~\"$team\",slug=~\"$instance\"},integration)", + "definition": "label_values(${alert_groups_total}{team=~`$team`,slug=~`$instance`},integration)", "hide": 0, "includeAll": true, "label": "Integration", @@ -1466,7 +1466,7 @@ "name": "integration", "options": [], "query": { - "query": "label_values(${alert_groups_total}{team=~\"$team\",slug=~\"$instance\"},integration)", + "query": "label_values(${alert_groups_total}{team=~`$team`,slug=~`$instance`},integration)", "refId": "PrometheusVariableQueryEditor-VariableQuery" }, "refresh": 2, @@ -1486,7 +1486,7 @@ "type": "prometheus", "uid": "${datasource}" }, - "definition": "label_values(${alert_groups_total}{slug=~\"$instance\", team=~\"$team\"},service_name)", + "definition": "label_values(${alert_groups_total}{slug=~`$instance`, team=~`$team`},service_name)", "hide": 0, "includeAll": true, "label": "Service name", @@ -1495,7 +1495,7 @@ "options": [], "query": { "qryType": 1, - "query": "label_values(${alert_groups_total}{slug=~\"$instance\", team=~\"$team\"},service_name)", + "query": "label_values(${alert_groups_total}{slug=~`$instance`, team=~`$team`},service_name)", "refId": "PrometheusVariableQueryEditor-VariableQuery" }, "refresh": 2, @@ -1516,7 +1516,7 @@ }, "timezone": "browser", "title": "OnCall Insights", - "version": 3, - "revision": 3, + "version": 4, + "revision": 4, "weekStart": "" } diff --git a/grafana-plugin/src/pages/insights/scenes/AlertGroupsByIntegration.tsx b/grafana-plugin/src/pages/insights/scenes/AlertGroupsByIntegration.tsx index fdc194d540..0425a62a31 100644 --- a/grafana-plugin/src/pages/insights/scenes/AlertGroupsByIntegration.tsx +++ b/grafana-plugin/src/pages/insights/scenes/AlertGroupsByIntegration.tsx @@ -10,7 +10,7 @@ export function getAlertGroupsByIntegrationScene({ datasource, stack }: Insights { editorMode: 'code', exemplar: false, - expr: `sort_desc(round(delta(sum by (integration)($alert_groups_total{slug=~"${stack}", team=~"$team", integration=~"$integration", service_name=~"$service_name"})[$__range:])) >= 0)`, + expr: `sort_desc(round(delta(sum by (integration)($alert_groups_total{slug=~\`${stack}\`, team=~\`$team\`, integration=~\`$integration\`, service_name=~\`$service_name\`})[$__range:])) >= 0)`, format: 'table', instant: true, legendFormat: '__auto', diff --git a/grafana-plugin/src/pages/insights/scenes/AlertGroupsByTeam.tsx b/grafana-plugin/src/pages/insights/scenes/AlertGroupsByTeam.tsx index 43352671d9..b73c6a3621 100644 --- a/grafana-plugin/src/pages/insights/scenes/AlertGroupsByTeam.tsx +++ b/grafana-plugin/src/pages/insights/scenes/AlertGroupsByTeam.tsx @@ -10,7 +10,7 @@ export function getAlertGroupsByTeamScene({ datasource, stack }: InsightsConfig) { editorMode: 'code', exemplar: false, - expr: `sort_desc(round(delta(sum by (team)($alert_groups_total{slug=~"${stack}", team=~"$team", integration=~"$integration", service_name=~"$service_name"})[$__range:])) >= 0)`, + expr: `sort_desc(round(delta(sum by (team)($alert_groups_total{slug=~\`${stack}\`, team=~\`$team\`, integration=~\`$integration\`, service_name=~\`$service_name\`})[$__range:])) >= 0)`, format: 'table', instant: true, legendFormat: '__auto', diff --git a/grafana-plugin/src/pages/insights/scenes/MTTRAverageStat.tsx b/grafana-plugin/src/pages/insights/scenes/MTTRAverageStat.tsx index 5f61359bc0..e00e85678f 100644 --- a/grafana-plugin/src/pages/insights/scenes/MTTRAverageStat.tsx +++ b/grafana-plugin/src/pages/insights/scenes/MTTRAverageStat.tsx @@ -10,7 +10,7 @@ export function getMTTRAverage({ datasource, stack }: InsightsConfig) { { editorMode: 'code', exemplar: false, - expr: `avg_over_time((sum($alert_groups_response_time_seconds_sum{slug=~"${stack}", team=~"$team", integration=~"$integration", service_name=~"$service_name"}) / sum($alert_groups_response_time_seconds_count{slug=~"${stack}", team=~"$team", integration=~"$integration", service_name=~"$service_name"}))[$__range:])`, + expr: `avg_over_time((sum($alert_groups_response_time_seconds_sum{slug=~\`${stack}\`, team=~\`$team\`, integration=~\`$integration\`, service_name=~\`$service_name\`}) / sum($alert_groups_response_time_seconds_count{slug=~\`${stack}\`, team=~\`$team\`, integration=~\`$integration\`, service_name=~\`$service_name\`}))[$__range:])`, instant: true, legendFormat: '__auto', range: false, diff --git a/grafana-plugin/src/pages/insights/scenes/MTTRByIntegration.tsx b/grafana-plugin/src/pages/insights/scenes/MTTRByIntegration.tsx index aab2c74631..2e5346f6fd 100644 --- a/grafana-plugin/src/pages/insights/scenes/MTTRByIntegration.tsx +++ b/grafana-plugin/src/pages/insights/scenes/MTTRByIntegration.tsx @@ -10,7 +10,7 @@ export function getMTTRByIntegrationScene({ datasource, stack }: InsightsConfig) { editorMode: 'code', exemplar: false, - expr: `sort_desc(avg_over_time((sum by (integration)($alert_groups_response_time_seconds_sum{slug=~"${stack}", team=~"$team", integration=~"$integration", service_name=~"$service_name"}) / sum by (integration)($alert_groups_response_time_seconds_count{slug=~"${stack}", team=~"$team", integration=~"$integration", service_name=~"$service_name"}))[$__range:]))`, + expr: `sort_desc(avg_over_time((sum by (integration)($alert_groups_response_time_seconds_sum{slug=~\`${stack}\`, team=~\`$team\`, integration=~\`$integration\`, service_name=~\`$service_name\`}) / sum by (integration)($alert_groups_response_time_seconds_count{slug=~\`${stack}\`, team=~\`$team\`, integration=~\`$integration\`, service_name=~\`$service_name\`}))[$__range:]))`, format: 'table', instant: true, legendFormat: '__auto', diff --git a/grafana-plugin/src/pages/insights/scenes/MTTRByTeam.tsx b/grafana-plugin/src/pages/insights/scenes/MTTRByTeam.tsx index d86fcedbc9..90f22fde5f 100644 --- a/grafana-plugin/src/pages/insights/scenes/MTTRByTeam.tsx +++ b/grafana-plugin/src/pages/insights/scenes/MTTRByTeam.tsx @@ -10,7 +10,7 @@ export function getMTTRByTeamScene({ datasource, stack }: InsightsConfig) { { editorMode: 'code', exemplar: false, - expr: `sort_desc(avg_over_time((sum by(team) ($alert_groups_response_time_seconds_sum{slug=~"${stack}", team=~"$team", integration=~"$integration", service_name=~"$service_name"}) / sum by(team)($alert_groups_response_time_seconds_count{slug=~"${stack}", team=~"$team", integration=~"$integration", service_name=~"$service_name"}))[$__range:]))`, + expr: `sort_desc(avg_over_time((sum by(team) ($alert_groups_response_time_seconds_sum{slug=~\`${stack}\`, team=~\`$team\`, integration=~\`$integration\`, service_name=~\`$service_name\`}) / sum by(team)($alert_groups_response_time_seconds_count{slug=~\`${stack}\`, team=~\`$team\`, integration=~\`$integration\`, service_name=~\`$service_name\`}))[$__range:]))`, format: 'table', instant: true, legendFormat: '__auto', diff --git a/grafana-plugin/src/pages/insights/scenes/MTTRChangedTimeseries.tsx b/grafana-plugin/src/pages/insights/scenes/MTTRChangedTimeseries.tsx index 1614bbb663..cedc5f0545 100644 --- a/grafana-plugin/src/pages/insights/scenes/MTTRChangedTimeseries.tsx +++ b/grafana-plugin/src/pages/insights/scenes/MTTRChangedTimeseries.tsx @@ -10,7 +10,7 @@ export function getMTTRChangedTimeseriesScene({ datasource, stack }: InsightsCon { editorMode: 'code', exemplar: false, - expr: `avg(sum($alert_groups_response_time_seconds_sum{slug=~"${stack}", team=~"$team", integration=~"$integration", service_name=~"$service_name"}) / sum($alert_groups_response_time_seconds_count{slug=~"${stack}", team=~"$team", integration=~"$integration", service_name=~"$service_name"}))`, + expr: `avg(sum($alert_groups_response_time_seconds_sum{slug=~\`${stack}\`, team=~\`$team\`, integration=~\`$integration\`, service_name=~\`$service_name\`}) / sum($alert_groups_response_time_seconds_count{slug=~\`${stack}\`, team=~\`$team\`, integration=~\`$integration\`, service_name=~\`$service_name\`}))`, instant: false, legendFormat: '__auto', range: true, diff --git a/grafana-plugin/src/pages/insights/scenes/NewAlertGroups.tsx b/grafana-plugin/src/pages/insights/scenes/NewAlertGroups.tsx index ab187c2479..b044de94bb 100644 --- a/grafana-plugin/src/pages/insights/scenes/NewAlertGroups.tsx +++ b/grafana-plugin/src/pages/insights/scenes/NewAlertGroups.tsx @@ -12,7 +12,7 @@ export function getNewAlertGroupsScene({ datasource, stack }: InsightsConfig) { editorMode: 'code', excludeNullMetadata: false, exemplar: false, - expr: `round(delta(sum($alert_groups_total{slug=~"${stack}", team=~"$team", integration=~"$integration", service_name=~"$service_name"})[$__range:])) >= 0`, + expr: `round(delta(sum($alert_groups_total{slug=~\`${stack}\`, team=~\`$team\`, integration=~\`$integration\`, service_name=~\`$service_name\`})[$__range:])) >= 0`, format: 'time_series', fullMetaSearch: false, includeNullMetadata: true, diff --git a/grafana-plugin/src/pages/insights/scenes/NewAlertGroupsNotificationsTable.tsx b/grafana-plugin/src/pages/insights/scenes/NewAlertGroupsNotificationsTable.tsx index f6d9e7ba7b..48e79ce99c 100644 --- a/grafana-plugin/src/pages/insights/scenes/NewAlertGroupsNotificationsTable.tsx +++ b/grafana-plugin/src/pages/insights/scenes/NewAlertGroupsNotificationsTable.tsx @@ -10,7 +10,7 @@ export function getNewAlertGroupsNotificationsTableScene({ datasource, stack }: { editorMode: 'code', exemplar: false, - expr: `sort_desc(round(delta(sum by (username)($user_was_notified_of_alert_groups_total{slug=~"${stack}"})[$__range:])) >= 0)`, + expr: `sort_desc(round(delta(sum by (username)($user_was_notified_of_alert_groups_total{slug=~\`${stack}\`})[$__range:])) >= 0)`, format: 'table', instant: true, legendFormat: '__auto', diff --git a/grafana-plugin/src/pages/insights/scenes/NewAlertGroupsNotificationsTimeseries.tsx b/grafana-plugin/src/pages/insights/scenes/NewAlertGroupsNotificationsTimeseries.tsx index bc2ae1566b..f97b111c5e 100644 --- a/grafana-plugin/src/pages/insights/scenes/NewAlertGroupsNotificationsTimeseries.tsx +++ b/grafana-plugin/src/pages/insights/scenes/NewAlertGroupsNotificationsTimeseries.tsx @@ -13,7 +13,7 @@ export function getNewAlertGroupsNotificationsTimeseriesScene({ datasource, stac editorMode: 'code', excludeNullMetadata: false, exemplar: false, - expr: `round(delta(sum by (username)($user_was_notified_of_alert_groups_total{slug=~"${stack}"})[$__interval:])) >= 0`, + expr: `round(delta(sum by (username)($user_was_notified_of_alert_groups_total{slug=~\`${stack}\`})[$__interval:])) >= 0`, fullMetaSearch: false, instant: false, legendFormat: '__auto', diff --git a/grafana-plugin/src/pages/insights/scenes/NewAlertGroupsTimeseries.tsx b/grafana-plugin/src/pages/insights/scenes/NewAlertGroupsTimeseries.tsx index cd55670855..0f1adab94f 100644 --- a/grafana-plugin/src/pages/insights/scenes/NewAlertGroupsTimeseries.tsx +++ b/grafana-plugin/src/pages/insights/scenes/NewAlertGroupsTimeseries.tsx @@ -13,7 +13,7 @@ export function getNewAlertGroupsTimeseriesScene({ datasource, stack }: Insights editorMode: 'code', excludeNullMetadata: false, exemplar: false, - expr: `round(delta(sum by (integration)($alert_groups_total{slug=~"${stack}", team=~"$team", integration=~"$integration", service_name=~"$service_name"})[$__interval:])) >= 0`, + expr: `round(delta(sum by (integration)($alert_groups_total{slug=~\`${stack}\`, team=~\`$team\`, integration=~\`$integration\`, service_name=~\`$service_name\`})[$__interval:])) >= 0`, fullMetaSearch: false, instant: false, legendFormat: '__auto', diff --git a/grafana-plugin/src/pages/insights/variables.ts b/grafana-plugin/src/pages/insights/variables.ts index b8dbd6e2fd..9dd28021d2 100644 --- a/grafana-plugin/src/pages/insights/variables.ts +++ b/grafana-plugin/src/pages/insights/variables.ts @@ -34,9 +34,9 @@ const getVariables = ({ isOpenSource, datasource, stack }: InsightsConfig) => ({ text: ['All'], value: ['$__all'], datasource, - definition: `label_values(\${alert_groups_total}{slug=~"${stack}"},team)`, + definition: `label_values(\${alert_groups_total}{slug=~\`${stack}\`},team)`, query: { - query: `label_values(\${alert_groups_total}{slug=~"${stack}"},team)`, + query: `label_values(\${alert_groups_total}{slug=~\`${stack}\`},team)`, refId: 'PrometheusVariableQueryEditor-VariableQuery', }, refresh: 2, @@ -48,9 +48,9 @@ const getVariables = ({ isOpenSource, datasource, stack }: InsightsConfig) => ({ text: ['All'], value: ['$__all'], datasource, - definition: `label_values(\${alert_groups_total}{team=~"$team",slug=~"${stack}"},integration)`, + definition: `label_values(\${alert_groups_total}{team=~\`$team\`,slug=~\`${stack}\`},integration)`, query: { - query: `label_values(\${alert_groups_total}{team=~"$team",slug=~"${stack}"},integration)`, + query: `label_values(\${alert_groups_total}{team=~\`$team\`,slug=~\`${stack}\`},integration)`, refId: 'PrometheusVariableQueryEditor-VariableQuery', }, refresh: 2, @@ -63,9 +63,9 @@ const getVariables = ({ isOpenSource, datasource, stack }: InsightsConfig) => ({ value: ['$__all'], allValue: '($^)|(.+)', datasource, - definition: `label_values(\${alert_groups_total}{slug=~"${stack}",team=~"$team"},service_name)`, + definition: `label_values(\${alert_groups_total}{slug=~\`${stack}\`,team=~\`$team\`},service_name)`, query: { - query: `label_values(\${alert_groups_total}{slug=~"${stack}",team=~"$team"},service_name)`, + query: `label_values(\${alert_groups_total}{slug=~\`${stack}\`,team=~\`$team\`},service_name)`, refId: 'PrometheusVariableQueryEditor-VariableQuery', }, refresh: 2,