{"version":3,"file":"4282.0cedc4c919aff84ce58c.js","mappings":"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","sources":["webpack://grafana/./public/app/features/alerting/unified/components/alert-groups/MatcherFilter.tsx","webpack://grafana/./public/app/features/alerting/unified/components/rules/StateHistory.tsx","webpack://grafana/./public/app/features/alerting/unified/hooks/useManagedAlertStateHistory.ts","webpack://grafana/./public/app/features/alerting/unified/components/rules/RuleDetailsActionButtons.tsx","webpack://grafana/./public/app/features/alerting/unified/hooks/useStateHistoryModal.tsx","webpack://grafana/./public/app/features/alerting/unified/components/rules/RuleDetailsAnnotations.tsx","webpack://grafana/./public/app/features/alerting/unified/components/rules/RuleDetailsDataSources.tsx","webpack://grafana/./public/app/features/alerting/unified/components/Expression.tsx","webpack://grafana/./public/app/features/alerting/unified/components/rules/RuleDetailsExpression.tsx","webpack://grafana/./public/app/features/alerting/unified/components/rules/AlertInstanceStateFilter.tsx","webpack://grafana/./public/app/features/alerting/unified/components/rules/RuleDetailsMatchingInstances.tsx","webpack://grafana/./public/app/features/alerting/unified/components/rules/RuleHealth.tsx","webpack://grafana/./public/app/features/alerting/unified/components/rules/RuleState.tsx","webpack://grafana/./public/app/features/alerting/unified/hooks/useCombinedRuleNamespaces.ts","webpack://grafana/./public/app/features/alerting/unified/hooks/useFolder.ts","webpack://grafana/./public/app/features/alerting/unified/hooks/useIsRuleEditable.ts"],"sourcesContent":["import React, { FormEvent } from 'react';\nimport { Label, Tooltip, Input, Icon, useStyles2 } from '@grafana/ui';\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { css } from '@emotion/css';\n\ninterface Props {\n className?: string;\n queryString?: string;\n defaultQueryString?: string;\n onFilterChange: (filterString: string) => void;\n}\n\nexport const MatcherFilter = ({ className, onFilterChange, defaultQueryString, queryString }: Props) => {\n const styles = useStyles2(getStyles);\n const handleSearchChange = (e: FormEvent<HTMLInputElement>) => {\n const target = e.target as HTMLInputElement;\n onFilterChange(target.value);\n };\n const searchIcon = <Icon name={'search'} />;\n return (\n <div className={className}>\n <Label>\n <Tooltip\n content={\n <div>\n Filter alerts using label querying, ex:\n <pre>{`{severity=\"critical\", instance=~\"cluster-us-.+\"}`}</pre>\n </div>\n }\n >\n <Icon className={styles.icon} name=\"info-circle\" size=\"xs\" />\n </Tooltip>\n Search by label\n </Label>\n <Input\n placeholder=\"Search\"\n defaultValue={defaultQueryString}\n value={queryString}\n onChange={handleSearchChange}\n data-testid=\"search-query-input\"\n prefix={searchIcon}\n className={styles.inputWidth}\n />\n </div>\n );\n};\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n icon: css`\n margin-right: ${theme.spacing(0.5)};\n `,\n inputWidth: css`\n width: 340px;\n flex-grow: 0;\n `,\n});\n","import React, { FC } from 'react';\nimport { uniqueId } from 'lodash';\nimport { AlertState, dateTimeFormat, GrafanaTheme } from '@grafana/data';\nimport { Alert, LoadingPlaceholder, useStyles } from '@grafana/ui';\nimport { css } from '@emotion/css';\nimport { StateHistoryItem, StateHistoryItemData } from 'app/types/unified-alerting';\nimport { DynamicTable, DynamicTableColumnProps, DynamicTableItemProps } from '../DynamicTable';\nimport { AlertStateTag } from './AlertStateTag';\nimport { useManagedAlertStateHistory } from '../../hooks/useManagedAlertStateHistory';\nimport { AlertLabel } from '../AlertLabel';\nimport { GrafanaAlertState, PromAlertingRuleState } from 'app/types/unified-alerting-dto';\n\ntype StateHistoryRowItem = {\n id: string;\n state: PromAlertingRuleState | GrafanaAlertState | AlertState;\n text?: string;\n data?: StateHistoryItemData;\n timestamp?: number;\n};\n\ntype StateHistoryRow = DynamicTableItemProps<StateHistoryRowItem>;\n\ninterface RuleStateHistoryProps {\n alertId: string;\n}\n\nconst StateHistory: FC<RuleStateHistoryProps> = ({ alertId }) => {\n const { loading, error, result = [] } = useManagedAlertStateHistory(alertId);\n\n if (loading && !error) {\n return <LoadingPlaceholder text={'Loading history...'} />;\n }\n\n if (error && !loading) {\n return <Alert title={'Failed to fetch alert state history'}>{error.message}</Alert>;\n }\n\n const columns: Array<DynamicTableColumnProps<StateHistoryRowItem>> = [\n { id: 'state', label: 'State', size: 'max-content', renderCell: renderStateCell },\n { id: 'value', label: '', size: 'auto', renderCell: renderValueCell },\n { id: 'timestamp', label: 'Time', size: 'max-content', renderCell: renderTimestampCell },\n ];\n\n const items: StateHistoryRow[] = result\n .reduce((acc: StateHistoryRowItem[], item, index) => {\n acc.push({\n id: String(item.id),\n state: item.newState,\n text: item.text,\n data: item.data,\n timestamp: item.updated,\n });\n\n // if the preceding state is not the same, create a separate state entry – this likely means the state was reset\n if (!hasMatchingPrecedingState(index, result)) {\n acc.push({ id: uniqueId(), state: item.prevState });\n }\n\n return acc;\n }, [])\n .map((historyItem) => ({\n id: historyItem.id,\n data: historyItem,\n }));\n\n return <DynamicTable cols={columns} items={items} />;\n};\n\nfunction renderValueCell(item: StateHistoryRow) {\n const matches = item.data.data?.evalMatches ?? [];\n\n return (\n <>\n {item.data.text}\n <LabelsWrapper>\n {matches.map((match) => (\n <AlertLabel key={match.metric} labelKey={match.metric} value={String(match.value)} />\n ))}\n </LabelsWrapper>\n </>\n );\n}\n\nfunction renderStateCell(item: StateHistoryRow) {\n return <AlertStateTag state={item.data.state} />;\n}\n\nfunction renderTimestampCell(item: StateHistoryRow) {\n return (\n <div className={TimestampStyle}>{item.data.timestamp && <span>{dateTimeFormat(item.data.timestamp)}</span>}</div>\n );\n}\n\nconst LabelsWrapper: FC<{}> = ({ children }) => {\n const { wrapper } = useStyles(getStyles);\n return <div className={wrapper}>{children}</div>;\n};\n\nconst TimestampStyle = css`\n display: flex;\n align-items: flex-end;\n flex-direction: column;\n`;\n\nconst getStyles = (theme: GrafanaTheme) => ({\n wrapper: css`\n & > * {\n margin-right: ${theme.spacing.xs};\n }\n `,\n});\n\n// this function will figure out if a given historyItem has a preceding historyItem where the states match - in other words\n// the newState of the previous historyItem is the same as the prevState of the current historyItem\nfunction hasMatchingPrecedingState(index: number, items: StateHistoryItem[]): boolean {\n const currentHistoryItem = items[index];\n const previousHistoryItem = items[index + 1];\n\n if (!previousHistoryItem) {\n return false;\n }\n\n return previousHistoryItem.newState === currentHistoryItem.prevState;\n}\n\nexport { StateHistory };\n","import { StateHistoryItem } from 'app/types/unified-alerting';\nimport { useEffect } from 'react';\nimport { useDispatch } from 'react-redux';\nimport { fetchGrafanaAnnotationsAction } from '../state/actions';\nimport { AsyncRequestState } from '../utils/redux';\nimport { useUnifiedAlertingSelector } from './useUnifiedAlertingSelector';\n\nexport function useManagedAlertStateHistory(alertId: string) {\n const dispatch = useDispatch();\n const history = useUnifiedAlertingSelector<AsyncRequestState<StateHistoryItem[]>>(\n (state) => state.managedAlertStateHistory\n );\n\n useEffect(() => {\n dispatch(fetchGrafanaAnnotationsAction(alertId));\n }, [dispatch, alertId]);\n\n return history;\n}\n","import React, { FC, Fragment, useState } from 'react';\nimport { useDispatch } from 'react-redux';\nimport { useLocation } from 'react-router-dom';\nimport { css } from '@emotion/css';\nimport { AppEvents, GrafanaTheme2, urlUtil } from '@grafana/data';\nimport { config } from '@grafana/runtime';\nimport { Button, ConfirmModal, ClipboardButton, HorizontalGroup, LinkButton, useStyles2 } from '@grafana/ui';\nimport { contextSrv } from 'app/core/services/context_srv';\nimport { appEvents } from 'app/core/core';\nimport { useIsRuleEditable } from '../../hooks/useIsRuleEditable';\nimport { Annotation } from '../../utils/constants';\nimport { getRulesSourceName, isCloudRulesSource, isGrafanaRulesSource } from '../../utils/datasource';\nimport { createExploreLink, createViewLink, makeRuleBasedSilenceLink } from '../../utils/misc';\nimport * as ruleId from '../../utils/rule-id';\nimport { deleteRuleAction } from '../../state/actions';\nimport { CombinedRule, RulesSource } from 'app/types/unified-alerting';\nimport { getAlertmanagerByUid } from '../../utils/alertmanager';\nimport { useStateHistoryModal } from '../../hooks/useStateHistoryModal';\nimport { RulerGrafanaRuleDTO, RulerRuleDTO } from 'app/types/unified-alerting-dto';\nimport { isFederatedRuleGroup } from '../../utils/rules';\n\ninterface Props {\n rule: CombinedRule;\n rulesSource: RulesSource;\n}\n\nexport const RuleDetailsActionButtons: FC<Props> = ({ rule, rulesSource }) => {\n const dispatch = useDispatch();\n const location = useLocation();\n const style = useStyles2(getStyles);\n const { namespace, group, rulerRule } = rule;\n const [ruleToDelete, setRuleToDelete] = useState<CombinedRule>();\n const alertId = isGrafanaRulerRule(rule.rulerRule) ? rule.rulerRule.grafana_alert.id ?? '' : '';\n const { StateHistoryModal, showStateHistoryModal } = useStateHistoryModal(alertId);\n\n const alertmanagerSourceName = isGrafanaRulesSource(rulesSource)\n ? rulesSource\n : getAlertmanagerByUid(rulesSource.jsonData.alertmanagerUid)?.name;\n\n const leftButtons: JSX.Element[] = [];\n const rightButtons: JSX.Element[] = [];\n\n const isFederated = isFederatedRuleGroup(group);\n const { isEditable } = useIsRuleEditable(getRulesSourceName(rulesSource), rulerRule);\n const returnTo = location.pathname + location.search;\n const isViewMode = inViewMode(location.pathname);\n\n const deleteRule = () => {\n if (ruleToDelete && ruleToDelete.rulerRule) {\n const identifier = ruleId.fromRulerRule(\n getRulesSourceName(ruleToDelete.namespace.rulesSource),\n ruleToDelete.namespace.name,\n ruleToDelete.group.name,\n ruleToDelete.rulerRule\n );\n\n dispatch(deleteRuleAction(identifier, { navigateTo: isViewMode ? '/alerting/list' : undefined }));\n setRuleToDelete(undefined);\n }\n };\n\n const buildShareUrl = () => {\n if (isCloudRulesSource(rulesSource)) {\n const ruleUrl = `${encodeURIComponent(rulesSource.name)}/${encodeURIComponent(rule.name)}`;\n return `${config.appUrl}${config.appSubUrl}/alerting/${ruleUrl}/find`;\n }\n\n return window.location.href.split('?')[0];\n };\n\n // explore does not support grafana rule queries atm\n // neither do \"federated rules\"\n if (isCloudRulesSource(rulesSource) && contextSrv.isEditor && !isFederated) {\n leftButtons.push(\n <LinkButton\n className={style.button}\n size=\"xs\"\n key=\"explore\"\n variant=\"primary\"\n icon=\"chart-line\"\n target=\"__blank\"\n href={createExploreLink(rulesSource.name, rule.query)}\n >\n See graph\n </LinkButton>\n );\n }\n if (rule.annotations[Annotation.runbookURL]) {\n leftButtons.push(\n <LinkButton\n className={style.button}\n size=\"xs\"\n key=\"runbook\"\n variant=\"primary\"\n icon=\"book\"\n target=\"__blank\"\n href={rule.annotations[Annotation.runbookURL]}\n >\n View runbook\n </LinkButton>\n );\n }\n if (rule.annotations[Annotation.dashboardUID]) {\n const dashboardUID = rule.annotations[Annotation.dashboardUID];\n if (dashboardUID) {\n leftButtons.push(\n <LinkButton\n className={style.button}\n size=\"xs\"\n key=\"dashboard\"\n variant=\"primary\"\n icon=\"apps\"\n target=\"__blank\"\n href={`d/${encodeURIComponent(dashboardUID)}`}\n >\n Go to dashboard\n </LinkButton>\n );\n const panelId = rule.annotations[Annotation.panelID];\n if (panelId) {\n leftButtons.push(\n <LinkButton\n className={style.button}\n size=\"xs\"\n key=\"panel\"\n variant=\"primary\"\n icon=\"apps\"\n target=\"__blank\"\n href={`d/${encodeURIComponent(dashboardUID)}?viewPanel=${encodeURIComponent(panelId)}`}\n >\n Go to panel\n </LinkButton>\n );\n }\n }\n }\n\n if (alertmanagerSourceName) {\n leftButtons.push(\n <LinkButton\n className={style.button}\n size=\"xs\"\n key=\"silence\"\n icon=\"bell-slash\"\n target=\"__blank\"\n href={makeRuleBasedSilenceLink(alertmanagerSourceName, rule)}\n >\n Silence\n </LinkButton>\n );\n }\n\n if (alertId) {\n leftButtons.push(\n <Fragment key=\"history\">\n <Button className={style.button} size=\"xs\" icon=\"history\" onClick={() => showStateHistoryModal()}>\n Show state history\n </Button>\n {StateHistoryModal}\n </Fragment>\n );\n }\n\n if (!isViewMode) {\n rightButtons.push(\n <LinkButton\n className={style.button}\n size=\"xs\"\n key=\"view\"\n variant=\"secondary\"\n icon=\"eye\"\n href={createViewLink(rulesSource, rule, returnTo)}\n >\n View\n </LinkButton>\n );\n }\n\n if (isEditable && rulerRule && !isFederated) {\n const sourceName = getRulesSourceName(rulesSource);\n const identifier = ruleId.fromRulerRule(sourceName, namespace.name, group.name, rulerRule);\n\n const editURL = urlUtil.renderUrl(\n `${config.appSubUrl}/alerting/${encodeURIComponent(ruleId.stringifyIdentifier(identifier))}/edit`,\n {\n returnTo,\n }\n );\n\n if (isViewMode) {\n rightButtons.push(\n <ClipboardButton\n key=\"copy\"\n onClipboardCopy={() => {\n appEvents.emit(AppEvents.alertSuccess, ['URL copied!']);\n }}\n onClipboardError={(e) => {\n appEvents.emit(AppEvents.alertError, ['Error while copying URL', e.text]);\n }}\n className={style.button}\n size=\"sm\"\n getText={buildShareUrl}\n >\n Copy link to rule\n </ClipboardButton>\n );\n }\n\n rightButtons.push(\n <LinkButton className={style.button} size=\"xs\" key=\"edit\" variant=\"secondary\" icon=\"pen\" href={editURL}>\n Edit\n </LinkButton>,\n <Button\n className={style.button}\n size=\"xs\"\n type=\"button\"\n key=\"delete\"\n variant=\"secondary\"\n icon=\"trash-alt\"\n onClick={() => setRuleToDelete(rule)}\n >\n Delete\n </Button>\n );\n }\n if (leftButtons.length || rightButtons.length) {\n return (\n <>\n <div className={style.wrapper}>\n <HorizontalGroup width=\"auto\">{leftButtons.length ? leftButtons : <div />}</HorizontalGroup>\n <HorizontalGroup width=\"auto\">{rightButtons.length ? rightButtons : <div />}</HorizontalGroup>\n </div>\n {!!ruleToDelete && (\n <ConfirmModal\n isOpen={true}\n title=\"Delete rule\"\n body=\"Deleting this rule will permanently remove it from your alert rule list. Are you sure you want to delete this rule?\"\n confirmText=\"Yes, delete\"\n icon=\"exclamation-triangle\"\n onConfirm={deleteRule}\n onDismiss={() => setRuleToDelete(undefined)}\n />\n )}\n </>\n );\n }\n\n return null;\n};\n\nfunction inViewMode(pathname: string): boolean {\n return pathname.endsWith('/view');\n}\n\nexport const getStyles = (theme: GrafanaTheme2) => ({\n wrapper: css`\n padding: ${theme.spacing(2)} 0;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n flex-wrap: wrap;\n border-bottom: solid 1px ${theme.colors.border.medium};\n `,\n button: css`\n height: 24px;\n margin-top: ${theme.spacing(1)};\n font-size: ${theme.typography.size.sm};\n `,\n});\n\nfunction isGrafanaRulerRule(rule?: RulerRuleDTO): rule is RulerGrafanaRuleDTO {\n if (!rule) {\n return false;\n }\n return (rule as RulerGrafanaRuleDTO).grafana_alert != null;\n}\n","import React, { useMemo, useState } from 'react';\nimport { Modal } from '@grafana/ui';\nimport { StateHistory } from '../components/rules/StateHistory';\n\nfunction useStateHistoryModal(alertId: string) {\n const [showModal, setShowModal] = useState<boolean>(false);\n\n const StateHistoryModal = useMemo(\n () => (\n <Modal\n isOpen={showModal}\n onDismiss={() => setShowModal(false)}\n closeOnBackdropClick={true}\n closeOnEscape={true}\n title=\"State history\"\n >\n <StateHistory alertId={alertId} />\n </Modal>\n ),\n [alertId, showModal]\n );\n\n return {\n StateHistoryModal,\n showStateHistoryModal: () => setShowModal(true),\n hideStateHistoryModal: () => setShowModal(false),\n };\n}\n\nexport { useStateHistoryModal };\n","import React from 'react';\nimport { css } from '@emotion/css';\nimport { useStyles2 } from '@grafana/ui';\nimport { AnnotationDetailsField } from '../AnnotationDetailsField';\n\ntype Props = {\n annotations: Array<[string, string]>;\n};\n\nexport function RuleDetailsAnnotations(props: Props): JSX.Element | null {\n const { annotations } = props;\n const styles = useStyles2(getStyles);\n\n if (annotations.length === 0) {\n return null;\n }\n\n return (\n <div className={styles.annotations}>\n {annotations.map(([key, value]) => (\n <AnnotationDetailsField key={key} annotationKey={key} value={value} />\n ))}\n </div>\n );\n}\n\nconst getStyles = () => ({\n annotations: css`\n margin-top: 46px;\n `,\n});\n","import { css } from '@emotion/css';\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { getDataSourceSrv } from '@grafana/runtime';\nimport { useStyles2 } from '@grafana/ui';\nimport { ExpressionDatasourceUID } from 'app/features/expressions/ExpressionDatasource';\nimport { CombinedRule, RulesSource } from 'app/types/unified-alerting';\nimport React, { useMemo } from 'react';\nimport { isCloudRulesSource } from '../../utils/datasource';\nimport { isGrafanaRulerRule } from '../../utils/rules';\nimport { DetailsField } from '../DetailsField';\n\ntype Props = {\n rule: CombinedRule;\n rulesSource: RulesSource;\n};\n\nexport function RuleDetailsDataSources(props: Props): JSX.Element | null {\n const { rulesSource, rule } = props;\n const styles = useStyles2(getStyles);\n\n const dataSources: Array<{ name: string; icon?: string }> = useMemo(() => {\n if (isCloudRulesSource(rulesSource)) {\n return [{ name: rulesSource.name, icon: rulesSource.meta.info.logos.small }];\n }\n\n if (isGrafanaRulerRule(rule.rulerRule)) {\n const { data } = rule.rulerRule.grafana_alert;\n const unique = data.reduce((dataSources, query) => {\n const ds = getDataSourceSrv().getInstanceSettings(query.datasourceUid);\n\n if (!ds || ds.uid === ExpressionDatasourceUID) {\n return dataSources;\n }\n\n dataSources[ds.name] = { name: ds.name, icon: ds.meta.info.logos.small };\n return dataSources;\n }, {} as Record<string, { name: string; icon?: string }>);\n\n return Object.values(unique);\n }\n\n return [];\n }, [rule, rulesSource]);\n\n if (dataSources.length === 0) {\n return null;\n }\n\n return (\n <DetailsField label=\"Data source\">\n {dataSources.map(({ name, icon }, index) => (\n <div key={name}>\n {icon && (\n <>\n <img alt={`${name} datasource logo`} className={styles.dataSourceIcon} src={icon} />{' '}\n </>\n )}\n {name}\n </div>\n ))}\n </DetailsField>\n );\n}\n\nfunction getStyles(theme: GrafanaTheme2) {\n const size = theme.spacing(2);\n\n return {\n dataSourceIcon: css`\n width: ${size};\n height: ${size};\n `,\n };\n}\n","import { Editor } from '@grafana/slate-react';\nimport React, { FC, useMemo } from 'react';\nimport PromqlSyntax from 'app/plugins/datasource/prometheus/promql';\nimport LogqlSyntax from 'app/plugins/datasource/loki/syntax';\nimport { LanguageMap, languages as prismLanguages } from 'prismjs';\nimport { makeValue, SlatePrism, useStyles } from '@grafana/ui';\nimport { css, cx } from '@emotion/css';\nimport { GrafanaTheme } from '@grafana/data';\nimport { RulesSource } from 'app/types/unified-alerting';\nimport { DataSourceType, isCloudRulesSource } from '../utils/datasource';\nimport { Well } from './Well';\n\ninterface Props {\n expression: string;\n rulesSource: RulesSource;\n}\n\nexport const HighlightedQuery: FC<{ language: 'promql' | 'logql'; expr: string }> = ({ language, expr }) => {\n const plugins = useMemo(\n () => [\n SlatePrism(\n {\n onlyIn: (node: any) => node.type === 'code_block',\n getSyntax: () => language,\n },\n { ...(prismLanguages as LanguageMap), [language]: language === 'logql' ? LogqlSyntax : PromqlSyntax }\n ),\n ],\n [language]\n );\n\n const slateValue = useMemo(() => makeValue(expr), [expr]);\n\n return <Editor plugins={plugins} value={slateValue} readOnly={true} />;\n};\n\nexport const Expression: FC<Props> = ({ expression: query, rulesSource }) => {\n const styles = useStyles(getStyles);\n\n return (\n <Well className={cx(styles.well, 'slate-query-field')}>\n {isCloudRulesSource(rulesSource) ? (\n <HighlightedQuery expr={query} language={rulesSource.type === DataSourceType.Loki ? 'logql' : 'promql'} />\n ) : (\n query\n )}\n </Well>\n );\n};\n\nexport const getStyles = (theme: GrafanaTheme) => ({\n well: css`\n font-family: ${theme.typography.fontFamily.monospace};\n `,\n});\n","import React from 'react';\nimport { css, cx } from '@emotion/css';\nimport { CombinedRule, RulesSource } from 'app/types/unified-alerting';\nimport { isCloudRulesSource } from '../../utils/datasource';\nimport { DetailsField } from '../DetailsField';\nimport { Expression } from '../Expression';\n\ntype Props = {\n rule: CombinedRule;\n rulesSource: RulesSource;\n annotations: Array<[string, string]>;\n};\n\nexport function RuleDetailsExpression(props: Props): JSX.Element | null {\n const { annotations, rulesSource, rule } = props;\n const styles = getStyles();\n\n if (!isCloudRulesSource(rulesSource)) {\n return null;\n }\n\n return (\n <DetailsField label=\"Expression\" horizontal={true} className={cx({ [styles.exprRow]: !!annotations.length })}>\n <Expression expression={rule.query} rulesSource={rulesSource} />\n </DetailsField>\n );\n}\n\nconst getStyles = () => ({\n exprRow: css`\n margin-bottom: 46px;\n `,\n});\n","import React from 'react';\nimport { RadioButtonGroup, Label } from '@grafana/ui';\nimport { GrafanaAlertState } from 'app/types/unified-alerting-dto';\n\ninterface Props {\n className?: string;\n stateFilter?: GrafanaAlertState;\n onStateFilterChange: (value: GrafanaAlertState | undefined) => void;\n}\n\nexport const AlertInstanceStateFilter = ({ className, onStateFilterChange, stateFilter }: Props) => {\n const stateOptions = Object.values(GrafanaAlertState).map((value) => ({\n label: value,\n value,\n }));\n\n return (\n <div className={className}>\n <Label>State</Label>\n <RadioButtonGroup\n options={stateOptions}\n value={stateFilter}\n onChange={onStateFilterChange}\n onClick={(v) => {\n if (v === stateFilter) {\n onStateFilterChange(undefined);\n }\n }}\n />\n </div>\n );\n};\n","import { Alert, Rule } from 'app/types/unified-alerting';\nimport React, { useMemo, useState } from 'react';\nimport { isAlertingRule } from '../../utils/rules';\nimport { DetailsField } from '../DetailsField';\nimport { AlertInstancesTable } from './AlertInstancesTable';\nimport { SortOrder } from 'app/plugins/panel/alertlist/types';\nimport { GrafanaAlertState } from 'app/types/unified-alerting-dto';\nimport { GrafanaTheme } from '@grafana/data';\nimport { useStyles } from '@grafana/ui';\nimport { css, cx } from '@emotion/css';\nimport { labelsMatchMatchers, parseMatchers } from 'app/features/alerting/unified/utils/alertmanager';\nimport { sortAlerts } from 'app/features/alerting/unified/utils/misc';\nimport { MatcherFilter } from 'app/features/alerting/unified/components/alert-groups/MatcherFilter';\nimport { AlertInstanceStateFilter } from 'app/features/alerting/unified/components/rules/AlertInstanceStateFilter';\n\ntype Props = {\n promRule?: Rule;\n};\n\nexport function RuleDetailsMatchingInstances(props: Props): JSX.Element | null {\n const { promRule } = props;\n\n const [queryString, setQueryString] = useState<string>();\n const [alertState, setAlertState] = useState<GrafanaAlertState>();\n\n // This key is used to force a rerender on the inputs when the filters are cleared\n const [filterKey] = useState<number>(Math.floor(Math.random() * 100));\n const queryStringKey = `queryString-${filterKey}`;\n\n const styles = useStyles(getStyles);\n\n const alerts = useMemo(\n (): Alert[] =>\n isAlertingRule(promRule) && promRule.alerts?.length\n ? filterAlerts(queryString, alertState, sortAlerts(SortOrder.Importance, promRule.alerts))\n : [],\n [promRule, alertState, queryString]\n );\n\n if (!isAlertingRule(promRule)) {\n return null;\n }\n\n return (\n <DetailsField label=\"Matching instances\" horizontal={true}>\n <div className={cx(styles.flexRow, styles.spaceBetween)}>\n <div className={styles.flexRow}>\n <MatcherFilter\n className={styles.rowChild}\n key={queryStringKey}\n defaultQueryString={queryString}\n onFilterChange={(value) => setQueryString(value)}\n />\n <AlertInstanceStateFilter\n className={styles.rowChild}\n stateFilter={alertState}\n onStateFilterChange={setAlertState}\n />\n </div>\n </div>\n\n <AlertInstancesTable instances={alerts} />\n </DetailsField>\n );\n}\n\nfunction filterAlerts(\n alertInstanceLabel: string | undefined,\n alertInstanceState: GrafanaAlertState | undefined,\n alerts: Alert[]\n): Alert[] {\n let filteredAlerts = [...alerts];\n if (alertInstanceLabel) {\n const matchers = parseMatchers(alertInstanceLabel || '');\n filteredAlerts = filteredAlerts.filter(({ labels }) => labelsMatchMatchers(labels, matchers));\n }\n if (alertInstanceState) {\n filteredAlerts = filteredAlerts.filter((alert) => {\n return alert.state === alertInstanceState;\n });\n }\n\n return filteredAlerts;\n}\n\nconst getStyles = (theme: GrafanaTheme) => {\n return {\n flexRow: css`\n display: flex;\n flex-direction: row;\n align-items: flex-end;\n width: 100%;\n flex-wrap: wrap;\n margin-bottom: ${theme.spacing.sm};\n `,\n spaceBetween: css`\n justify-content: space-between;\n `,\n rowChild: css`\n margin-right: ${theme.spacing.sm};\n `,\n };\n};\n","import { css } from '@emotion/css';\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { Icon, Tooltip, useStyles2 } from '@grafana/ui';\nimport { Rule } from 'app/types/unified-alerting';\nimport React, { FC } from 'react';\n\ninterface Prom {\n rule: Rule;\n}\n\nexport const RuleHealth: FC<Prom> = ({ rule }) => {\n const style = useStyles2(getStyle);\n if (rule.health === 'err' || rule.health === 'error') {\n return (\n <Tooltip theme=\"error\" content={rule.lastError || 'No error message provided.'}>\n <div className={style.warn}>\n <Icon name=\"exclamation-triangle\" />\n <span>error</span>\n </div>\n </Tooltip>\n );\n }\n return <>{rule.health}</>;\n};\n\nconst getStyle = (theme: GrafanaTheme2) => ({\n warn: css`\n display: inline-flex;\n flex-direction: row;\n color: ${theme.colors.warning.text};\n & > * + * {\n margin-left: ${theme.spacing(1)};\n }\n `,\n});\n","import { css } from '@emotion/css';\nimport { GrafanaTheme2, intervalToAbbreviatedDurationString } from '@grafana/data';\nimport { HorizontalGroup, Spinner, useStyles2 } from '@grafana/ui';\nimport { CombinedRule } from 'app/types/unified-alerting';\nimport { PromAlertingRuleState } from 'app/types/unified-alerting-dto';\nimport React, { FC, useMemo } from 'react';\nimport { isAlertingRule, isRecordingRule, getFirstActiveAt } from '../../utils/rules';\nimport { AlertStateTag } from './AlertStateTag';\n\ninterface Props {\n rule: CombinedRule;\n isDeleting: boolean;\n isCreating: boolean;\n}\n\nexport const RuleState: FC<Props> = ({ rule, isDeleting, isCreating }) => {\n const style = useStyles2(getStyle);\n const { promRule } = rule;\n\n // return how long the rule has been in it's firing state, if any\n const forTime = useMemo(() => {\n if (\n promRule &&\n isAlertingRule(promRule) &&\n promRule.alerts?.length &&\n promRule.state !== PromAlertingRuleState.Inactive\n ) {\n // find earliest alert\n const firstActiveAt = getFirstActiveAt(promRule);\n\n // calculate time elapsed from earliest alert\n if (firstActiveAt) {\n return (\n <span title={String(firstActiveAt)} className={style.for}>\n for{' '}\n {intervalToAbbreviatedDurationString(\n {\n start: firstActiveAt,\n end: new Date(),\n },\n false\n )}\n </span>\n );\n }\n }\n return null;\n }, [promRule, style]);\n\n if (isDeleting) {\n return (\n <HorizontalGroup align=\"flex-start\">\n <Spinner />\n deleting\n </HorizontalGroup>\n );\n } else if (isCreating) {\n return (\n <HorizontalGroup align=\"flex-start\">\n {' '}\n <Spinner />\n creating\n </HorizontalGroup>\n );\n } else if (promRule && isAlertingRule(promRule)) {\n return (\n <HorizontalGroup align=\"flex-start\">\n <AlertStateTag state={promRule.state} />\n {forTime}\n </HorizontalGroup>\n );\n } else if (promRule && isRecordingRule(promRule)) {\n return <>Recording rule</>;\n }\n return <>n/a</>;\n};\n\nconst getStyle = (theme: GrafanaTheme2) => ({\n for: css`\n font-size: ${theme.typography.bodySmall.fontSize};\n color: ${theme.colors.text.secondary};\n white-space: nowrap;\n padding-top: 2px;\n `,\n});\n","import {\n CombinedRule,\n CombinedRuleGroup,\n CombinedRuleNamespace,\n Rule,\n RuleGroup,\n RuleNamespace,\n RulesSource,\n} from 'app/types/unified-alerting';\nimport { RulerRuleDTO, RulerRuleGroupDTO, RulerRulesConfigDTO } from 'app/types/unified-alerting-dto';\nimport { useMemo, useRef } from 'react';\nimport {\n getAllRulesSources,\n getRulesSourceByName,\n isCloudRulesSource,\n isGrafanaRulesSource,\n} from '../utils/datasource';\nimport { isAlertingRule, isAlertingRulerRule, isRecordingRulerRule } from '../utils/rules';\nimport { useUnifiedAlertingSelector } from './useUnifiedAlertingSelector';\n\ninterface CacheValue {\n promRules?: RuleNamespace[];\n rulerRules?: RulerRulesConfigDTO | null;\n result: CombinedRuleNamespace[];\n}\n\n// this little monster combines prometheus rules and ruler rules to produce a unified data structure\n// can limit to a single rules source\nexport function useCombinedRuleNamespaces(rulesSourceName?: string): CombinedRuleNamespace[] {\n const promRulesResponses = useUnifiedAlertingSelector((state) => state.promRules);\n const rulerRulesResponses = useUnifiedAlertingSelector((state) => state.rulerRules);\n\n // cache results per rules source, so we only recalculate those for which results have actually changed\n const cache = useRef<Record<string, CacheValue>>({});\n\n const rulesSources = useMemo((): RulesSource[] => {\n if (rulesSourceName) {\n const rulesSource = getRulesSourceByName(rulesSourceName);\n if (!rulesSource) {\n throw new Error(`Unknown rules source: ${rulesSourceName}`);\n }\n return [rulesSource];\n }\n return getAllRulesSources();\n }, [rulesSourceName]);\n\n return useMemo(\n () =>\n rulesSources\n .map((rulesSource): CombinedRuleNamespace[] => {\n const rulesSourceName = isCloudRulesSource(rulesSource) ? rulesSource.name : rulesSource;\n const promRules = promRulesResponses[rulesSourceName]?.result;\n const rulerRules = rulerRulesResponses[rulesSourceName]?.result;\n\n const cached = cache.current[rulesSourceName];\n if (cached && cached.promRules === promRules && cached.rulerRules === rulerRules) {\n return cached.result;\n }\n const namespaces: Record<string, CombinedRuleNamespace> = {};\n\n // first get all the ruler rules in\n Object.entries(rulerRules || {}).forEach(([namespaceName, groups]) => {\n const namespace: CombinedRuleNamespace = {\n rulesSource,\n name: namespaceName,\n groups: [],\n };\n namespaces[namespaceName] = namespace;\n addRulerGroupsToCombinedNamespace(namespace, groups);\n });\n\n // then correlate with prometheus rules\n promRules?.forEach(({ name: namespaceName, groups }) => {\n const ns = (namespaces[namespaceName] = namespaces[namespaceName] || {\n rulesSource,\n name: namespaceName,\n groups: [],\n });\n\n addPromGroupsToCombinedNamespace(ns, groups);\n });\n\n const result = Object.values(namespaces);\n if (isGrafanaRulesSource(rulesSource)) {\n // merge all groups in case of grafana managed, essentially treating namespaces (folders) as gorups\n result.forEach((namespace) => {\n namespace.groups = [\n {\n name: 'default',\n rules: namespace.groups.flatMap((g) => g.rules).sort((a, b) => a.name.localeCompare(b.name)),\n },\n ];\n });\n }\n cache.current[rulesSourceName] = { promRules, rulerRules, result };\n return result;\n })\n .flat(),\n [promRulesResponses, rulerRulesResponses, rulesSources]\n );\n}\n\nfunction addRulerGroupsToCombinedNamespace(namespace: CombinedRuleNamespace, groups: RulerRuleGroupDTO[]): void {\n namespace.groups = groups.map((group) => {\n const combinedGroup: CombinedRuleGroup = {\n name: group.name,\n interval: group.interval,\n source_tenants: group.source_tenants,\n rules: [],\n };\n combinedGroup.rules = group.rules.map((rule) => rulerRuleToCombinedRule(rule, namespace, combinedGroup));\n return combinedGroup;\n });\n}\n\nfunction addPromGroupsToCombinedNamespace(namespace: CombinedRuleNamespace, groups: RuleGroup[]): void {\n groups.forEach((group) => {\n let combinedGroup = namespace.groups.find((g) => g.name === group.name);\n if (!combinedGroup) {\n combinedGroup = {\n name: group.name,\n rules: [],\n };\n namespace.groups.push(combinedGroup);\n }\n\n (group.rules ?? []).forEach((rule) => {\n const existingRule = getExistingRuleInGroup(rule, combinedGroup!, namespace.rulesSource);\n if (existingRule) {\n existingRule.promRule = rule;\n } else {\n combinedGroup!.rules.push(promRuleToCombinedRule(rule, namespace, combinedGroup!));\n }\n });\n });\n}\n\nfunction promRuleToCombinedRule(rule: Rule, namespace: CombinedRuleNamespace, group: CombinedRuleGroup): CombinedRule {\n return {\n name: rule.name,\n query: rule.query,\n labels: rule.labels || {},\n annotations: isAlertingRule(rule) ? rule.annotations || {} : {},\n promRule: rule,\n namespace: namespace,\n group,\n };\n}\n\nfunction rulerRuleToCombinedRule(\n rule: RulerRuleDTO,\n namespace: CombinedRuleNamespace,\n group: CombinedRuleGroup\n): CombinedRule {\n return isAlertingRulerRule(rule)\n ? {\n name: rule.alert,\n query: rule.expr,\n labels: rule.labels || {},\n annotations: rule.annotations || {},\n rulerRule: rule,\n namespace,\n group,\n }\n : isRecordingRulerRule(rule)\n ? {\n name: rule.record,\n query: rule.expr,\n labels: rule.labels || {},\n annotations: {},\n rulerRule: rule,\n namespace,\n group,\n }\n : {\n name: rule.grafana_alert.title,\n query: '',\n labels: rule.labels || {},\n annotations: rule.annotations || {},\n rulerRule: rule,\n namespace,\n group,\n };\n}\n\n// find existing rule in group that matches the given prom rule\nfunction getExistingRuleInGroup(\n rule: Rule,\n group: CombinedRuleGroup,\n rulesSource: RulesSource\n): CombinedRule | undefined {\n if (isGrafanaRulesSource(rulesSource)) {\n // assume grafana groups have only the one rule. check name anyway because paranoid\n return group!.rules.find((existingRule) => existingRule.name === rule.name);\n }\n return (\n // try finding a rule that matches name, labels, annotations and query\n group!.rules.find(\n (existingRule) => !existingRule.promRule && isCombinedRuleEqualToPromRule(existingRule, rule, true)\n ) ??\n // if that fails, try finding a rule that only matches name, labels and annotations.\n // loki & prom can sometimes modify the query so it doesnt match, eg `2 > 1` becomes `1`\n group!.rules.find(\n (existingRule) => !existingRule.promRule && isCombinedRuleEqualToPromRule(existingRule, rule, false)\n )\n );\n}\n\nfunction isCombinedRuleEqualToPromRule(combinedRule: CombinedRule, rule: Rule, checkQuery = true): boolean {\n if (combinedRule.name === rule.name) {\n return (\n JSON.stringify([\n checkQuery ? hashQuery(combinedRule.query) : '',\n combinedRule.labels,\n combinedRule.annotations,\n ]) ===\n JSON.stringify([\n checkQuery ? hashQuery(rule.query) : '',\n rule.labels || {},\n isAlertingRule(rule) ? rule.annotations || {} : {},\n ])\n );\n }\n return false;\n}\n\n// there can be slight differences in how prom & ruler render a query, this will hash them accounting for the differences\nfunction hashQuery(query: string) {\n // one of them might be wrapped in parens\n if (query.length > 1 && query[0] === '(' && query[query.length - 1] === ')') {\n query = query.substr(1, query.length - 2);\n }\n // whitespace could be added or removed\n query = query.replace(/\\s|\\n/g, '');\n // labels matchers can be reordered, so sort the enitre string, esentially comparing just the character counts\n return query.split('').sort().join('');\n}\n","import { FolderDTO } from 'app/types';\nimport { useDispatch } from 'react-redux';\nimport { useUnifiedAlertingSelector } from './useUnifiedAlertingSelector';\nimport { useEffect } from 'react';\nimport { fetchFolderIfNotFetchedAction } from '../state/actions';\nimport { initialAsyncRequestState } from '../utils/redux';\n\ninterface ReturnBag {\n folder?: FolderDTO;\n loading: boolean;\n}\n\nexport function useFolder(uid?: string): ReturnBag {\n const dispatch = useDispatch();\n const folderRequests = useUnifiedAlertingSelector((state) => state.folders);\n useEffect(() => {\n if (uid) {\n dispatch(fetchFolderIfNotFetchedAction(uid));\n }\n }, [dispatch, uid]);\n\n if (uid) {\n const request = folderRequests[uid] || initialAsyncRequestState;\n return {\n folder: request.result,\n loading: request.loading,\n };\n }\n return {\n loading: false,\n };\n}\n","import { contextSrv } from 'app/core/services/context_srv';\nimport { isGrafanaRulerRule } from '../utils/rules';\nimport { RulerRuleDTO } from 'app/types/unified-alerting-dto';\nimport { useFolder } from './useFolder';\nimport { useUnifiedAlertingSelector } from './useUnifiedAlertingSelector';\nimport { useDispatch } from 'react-redux';\nimport { useEffect } from 'react';\nimport { checkIfLotexSupportsEditingRulesAction } from '../state/actions';\nimport { GRAFANA_RULES_SOURCE_NAME } from '../utils/datasource';\n\ninterface ResultBag {\n isEditable?: boolean;\n loading: boolean;\n}\n\nexport function useIsRuleEditable(rulesSourceName: string, rule?: RulerRuleDTO): ResultBag {\n const checkEditingRequests = useUnifiedAlertingSelector((state) => state.lotexSupportsRuleEditing);\n const dispatch = useDispatch();\n const folderUID = rule && isGrafanaRulerRule(rule) ? rule.grafana_alert.namespace_uid : undefined;\n\n const { folder, loading } = useFolder(folderUID);\n\n useEffect(() => {\n if (checkEditingRequests[rulesSourceName] === undefined && rulesSourceName !== GRAFANA_RULES_SOURCE_NAME) {\n dispatch(checkIfLotexSupportsEditingRulesAction(rulesSourceName));\n }\n }, [rulesSourceName, checkEditingRequests, dispatch]);\n\n if (!rule) {\n return { isEditable: false, loading: false };\n }\n\n // grafana rules can be edited if user can edit the folder they're in\n if (isGrafanaRulerRule(rule)) {\n if (!folderUID) {\n throw new Error(\n `Rule ${rule.grafana_alert.title} does not have a folder uid, cannot determine if it is editable.`\n );\n }\n return {\n isEditable: folder?.canSave,\n loading,\n };\n }\n\n // prom rules are only editable by users with Editor role and only if rules source supports editing\n return {\n isEditable: contextSrv.isEditor && !!checkEditingRequests[rulesSourceName]?.result,\n loading: !!checkEditingRequests[rulesSourceName]?.loading,\n };\n}\n"],"names":["MatcherFilter","className","onFilterChange","defaultQueryString","queryString","styles","useStyles2","getStyles","searchIcon","Icon","name","Label","Tooltip","content","icon","size","Input","placeholder","defaultValue","value","onChange","e","target","prefix","inputWidth","theme","css","spacing","StateHistory","alertId","loading","error","result","dispatch","useDispatch","history","useUnifiedAlertingSelector","state","managedAlertStateHistory","useEffect","fetchGrafanaAnnotationsAction","useManagedAlertStateHistory","LoadingPlaceholder","text","Alert","title","message","columns","id","label","renderCell","renderStateCell","renderValueCell","renderTimestampCell","items","reduce","acc","item","index","push","String","newState","data","timestamp","updated","currentHistoryItem","previousHistoryItem","prevState","hasMatchingPrecedingState","uniqueId","map","historyItem","DynamicTable","cols","matches","evalMatches","LabelsWrapper","match","AlertLabel","labelKey","metric","AlertStateTag","TimestampStyle","dateTimeFormat","children","wrapper","useStyles","xs","RuleDetailsActionButtons","rule","rulesSource","location","useLocation","style","namespace","group","rulerRule","ruleToDelete","setRuleToDelete","useState","grafana_alert","isGrafanaRulerRule","StateHistoryModal","showStateHistoryModal","showModal","setShowModal","useMemo","Modal","isOpen","onDismiss","closeOnBackdropClick","closeOnEscape","hideStateHistoryModal","useStateHistoryModal","alertmanagerSourceName","isGrafanaRulesSource","getAlertmanagerByUid","jsonData","alertmanagerUid","leftButtons","rightButtons","isFederated","isFederatedRuleGroup","isEditable","useIsRuleEditable","getRulesSourceName","returnTo","pathname","search","isViewMode","endsWith","deleteRule","identifier","ruleId","deleteRuleAction","navigateTo","undefined","buildShareUrl","isCloudRulesSource","ruleUrl","encodeURIComponent","config","window","href","split","contextSrv","LinkButton","button","variant","createExploreLink","query","annotations","Annotation","dashboardUID","panelId","makeRuleBasedSilenceLink","Fragment","Button","onClick","createViewLink","sourceName","editURL","urlUtil","ClipboardButton","onClipboardCopy","appEvents","AppEvents","onClipboardError","getText","type","length","HorizontalGroup","width","ConfirmModal","body","confirmText","onConfirm","colors","border","medium","typography","sm","RuleDetailsAnnotations","props","key","annotationKey","RuleDetailsDataSources","dataSources","meta","info","logos","small","unique","ds","getDataSourceSrv","getInstanceSettings","datasourceUid","uid","ExpressionDatasourceUID","Object","values","alt","dataSourceIcon","src","HighlightedQuery","language","expr","plugins","SlatePrism","onlyIn","node","getSyntax","prismLanguages","LogqlSyntax","PromqlSyntax","slateValue","makeValue","readOnly","Expression","expression","Well","cx","well","DataSourceType","fontFamily","monospace","RuleDetailsExpression","DetailsField","horizontal","exprRow","AlertInstanceStateFilter","onStateFilterChange","stateFilter","stateOptions","GrafanaAlertState","RadioButtonGroup","options","v","RuleDetailsMatchingInstances","promRule","setQueryString","alertState","setAlertState","filterKey","Math","floor","random","queryStringKey","alerts","isAlertingRule","alertInstanceLabel","alertInstanceState","filteredAlerts","matchers","parseMatchers","filter","labels","labelsMatchMatchers","alert","filterAlerts","sortAlerts","SortOrder","flexRow","spaceBetween","rowChild","AlertInstancesTable","instances","RuleHealth","getStyle","health","lastError","warn","warning","RuleState","isDeleting","isCreating","forTime","PromAlertingRuleState","firstActiveAt","getFirstActiveAt","for","intervalToAbbreviatedDurationString","start","end","Date","align","Spinner","isRecordingRule","bodySmall","fontSize","secondary","useCombinedRuleNamespaces","rulesSourceName","promRulesResponses","promRules","rulerRulesResponses","rulerRules","cache","useRef","rulesSources","getRulesSourceByName","Error","getAllRulesSources","cached","current","namespaces","entries","forEach","namespaceName","groups","combinedGroup","interval","source_tenants","rules","isAlertingRulerRule","isRecordingRulerRule","record","rulerRuleToCombinedRule","addRulerGroupsToCombinedNamespace","find","g","existingRule","isCombinedRuleEqualToPromRule","getExistingRuleInGroup","promRuleToCombinedRule","addPromGroupsToCombinedNamespace","flatMap","sort","a","b","localeCompare","flat","combinedRule","checkQuery","JSON","stringify","hashQuery","substr","replace","join","useFolder","folderRequests","folders","fetchFolderIfNotFetchedAction","request","initialAsyncRequestState","folder","checkEditingRequests","lotexSupportsRuleEditing","folderUID","namespace_uid","GRAFANA_RULES_SOURCE_NAME","checkIfLotexSupportsEditingRulesAction","canSave"],"sourceRoot":""}