{"version":3,"file":"4097.0dfd49f78dc93c695e30.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 { css } from '@emotion/css';\nimport React, { FormEvent } from 'react';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { Stack } from '@grafana/experimental';\nimport { Label, Tooltip, Input, Icon, useStyles2 } from '@grafana/ui';\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        <Stack gap={0.5}>\n          <span>Search by label</span>\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=\"sm\" />\n          </Tooltip>\n        </Stack>\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 { css } from '@emotion/css';\nimport { uniqueId } from 'lodash';\nimport React, { FC } from 'react';\n\nimport { AlertState, dateTimeFormat, GrafanaTheme } from '@grafana/data';\nimport { Alert, LoadingPlaceholder, useStyles } from '@grafana/ui';\nimport { StateHistoryItem, StateHistoryItemData } from 'app/types/unified-alerting';\nimport { GrafanaAlertState, PromAlertingRuleState } from 'app/types/unified-alerting-dto';\n\nimport { useManagedAlertStateHistory } from '../../hooks/useManagedAlertStateHistory';\nimport { AlertLabel } from '../AlertLabel';\nimport { DynamicTable, DynamicTableColumnProps, DynamicTableItemProps } from '../DynamicTable';\n\nimport { AlertStateTag } from './AlertStateTag';\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 { useEffect } from 'react';\nimport { useDispatch } from 'react-redux';\n\nimport { StateHistoryItem } from 'app/types/unified-alerting';\n\nimport { fetchGrafanaAnnotationsAction } from '../state/actions';\nimport { AsyncRequestState } from '../utils/redux';\n\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 { css } from '@emotion/css';\nimport React, { FC, Fragment, useState } from 'react';\nimport { useDispatch } from 'react-redux';\nimport { useLocation } from 'react-router-dom';\n\nimport { GrafanaTheme2, textUtil, urlUtil } from '@grafana/data';\nimport { config } from '@grafana/runtime';\nimport { Button, ClipboardButton, ConfirmModal, HorizontalGroup, LinkButton, useStyles2 } from '@grafana/ui';\nimport { useAppNotification } from 'app/core/copy/appNotification';\nimport { contextSrv } from 'app/core/services/context_srv';\nimport { AccessControlAction } from 'app/types';\nimport { CombinedRule, RulesSource } from 'app/types/unified-alerting';\nimport { RulerGrafanaRuleDTO, RulerRuleDTO } from 'app/types/unified-alerting-dto';\n\nimport { useIsRuleEditable } from '../../hooks/useIsRuleEditable';\nimport { useStateHistoryModal } from '../../hooks/useStateHistoryModal';\nimport { deleteRuleAction } from '../../state/actions';\nimport { getAlertmanagerByUid } from '../../utils/alertmanager';\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 { 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 notifyApp = useAppNotification();\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  const rulesSourceName = getRulesSourceName(rulesSource);\n\n  const hasExplorePermission = contextSrv.hasPermission(AccessControlAction.DataSourcesExplore);\n\n  const leftButtons: JSX.Element[] = [];\n  const rightButtons: JSX.Element[] = [];\n\n  const isFederated = isFederatedRuleGroup(group);\n  const { isEditable, isRemovable } = useIsRuleEditable(rulesSourceName, 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 { appUrl, appSubUrl } = config;\n      const baseUrl = appSubUrl !== '' ? `${appUrl}${appSubUrl}/` : config.appUrl;\n      const ruleUrl = `${encodeURIComponent(rulesSource.name)}/${encodeURIComponent(rule.name)}`;\n      return `${baseUrl}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) && hasExplorePermission && !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={textUtil.sanitizeUrl(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 && contextSrv.hasAccess(AccessControlAction.AlertingInstanceCreate, contextSrv.isEditor)) {\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            notifyApp.success('URL copied!');\n          }}\n          onClipboardError={(e) => {\n            notifyApp.error('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    );\n  }\n\n  if (isRemovable && rulerRule && !isFederated) {\n    rightButtons.push(\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\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';\n\nimport { Modal } from '@grafana/ui';\n\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 { css } from '@emotion/css';\nimport React from 'react';\n\nimport { useStyles2 } from '@grafana/ui';\n\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 React, { useMemo } from 'react';\n\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';\n\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 { css, cx } from '@emotion/css';\nimport { LanguageMap, languages as prismLanguages } from 'prismjs';\nimport React, { FC, useMemo } from 'react';\nimport { Editor } from 'slate-react';\n\nimport { GrafanaTheme } from '@grafana/data';\nimport { makeValue, SlatePrism, useStyles } from '@grafana/ui';\nimport LogqlSyntax from 'app/plugins/datasource/loki/syntax';\nimport PromqlSyntax from 'app/plugins/datasource/prometheus/promql';\nimport { RulesSource } from 'app/types/unified-alerting';\n\nimport { DataSourceType, isCloudRulesSource } from '../utils/datasource';\n\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 { css, cx } from '@emotion/css';\nimport React from 'react';\n\nimport { CombinedRule, RulesSource } from 'app/types/unified-alerting';\n\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';\n\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 { css, cx } from '@emotion/css';\nimport React, { useMemo, useState } from 'react';\n\nimport { GrafanaTheme } from '@grafana/data';\nimport { useStyles } from '@grafana/ui';\nimport { MatcherFilter } from 'app/features/alerting/unified/components/alert-groups/MatcherFilter';\nimport { AlertInstanceStateFilter } from 'app/features/alerting/unified/components/rules/AlertInstanceStateFilter';\nimport { labelsMatchMatchers, parseMatchers } from 'app/features/alerting/unified/utils/alertmanager';\nimport { sortAlerts } from 'app/features/alerting/unified/utils/misc';\nimport { SortOrder } from 'app/plugins/panel/alertlist/types';\nimport { Alert, Rule } from 'app/types/unified-alerting';\nimport { GrafanaAlertState } from 'app/types/unified-alerting-dto';\n\nimport { isAlertingRule } from '../../utils/rules';\nimport { DetailsField } from '../DetailsField';\n\nimport { AlertInstancesTable } from './AlertInstancesTable';\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 React, { FC } from 'react';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { Icon, Tooltip, useStyles2 } from '@grafana/ui';\nimport { Rule } from 'app/types/unified-alerting';\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 React, { FC, useMemo } from 'react';\n\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';\n\nimport { isAlertingRule, isRecordingRule, getFirstActiveAt } from '../../utils/rules';\n\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 { useMemo, useRef } from 'react';\n\nimport {\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';\n\nimport {\n  getAllRulesSources,\n  getRulesSourceByName,\n  isCloudRulesSource,\n  isGrafanaRulesSource,\n} from '../utils/datasource';\nimport { isAlertingRule, isAlertingRulerRule, isRecordingRulerRule } from '../utils/rules';\n\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\n          cache.current[rulesSourceName] = { promRules, rulerRules, result };\n          return result;\n        })\n        .flat(),\n    [promRulesResponses, rulerRulesResponses, rulesSources]\n  );\n}\n\n// merge all groups in case of grafana managed, essentially treating namespaces (folders) as groups\nexport function flattenGrafanaManagedRules(namespaces: CombinedRuleNamespace[]) {\n  return namespaces.map((namespace) => {\n    const newNamespace: CombinedRuleNamespace = {\n      ...namespace,\n      groups: [],\n    };\n\n    // add default group with ungrouped rules\n    newNamespace.groups.push({\n      name: 'default',\n      rules: sortRulesByName(namespace.groups.flatMap((group) => group.rules)),\n    });\n\n    return newNamespace;\n  });\n}\n\nexport function sortRulesByName(rules: CombinedRule[]) {\n  return rules.sort((a, b) => a.name.localeCompare(b.name));\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.slice(1, -1);\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 { useEffect } from 'react';\nimport { useDispatch } from 'react-redux';\n\nimport { FolderDTO } from 'app/types';\n\nimport { fetchFolderIfNotFetchedAction } from '../state/actions';\nimport { initialAsyncRequestState } from '../utils/redux';\n\nimport { useUnifiedAlertingSelector } from './useUnifiedAlertingSelector';\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 { RulerRuleDTO } from 'app/types/unified-alerting-dto';\n\nimport { getRulesPermissions } from '../utils/access-control';\nimport { isGrafanaRulerRule } from '../utils/rules';\n\nimport { useFolder } from './useFolder';\nimport { useUnifiedAlertingSelector } from './useUnifiedAlertingSelector';\n\ninterface ResultBag {\n  isEditable?: boolean;\n  isRemovable?: boolean;\n  loading: boolean;\n}\n\nexport function useIsRuleEditable(rulesSourceName: string, rule?: RulerRuleDTO): ResultBag {\n  const dataSources = useUnifiedAlertingSelector((state) => state.dataSources);\n  const folderUID = rule && isGrafanaRulerRule(rule) ? rule.grafana_alert.namespace_uid : undefined;\n\n  const rulePermission = getRulesPermissions(rulesSourceName);\n  const hasEditPermission = contextSrv.hasPermission(rulePermission.update);\n  const hasRemovePermission = contextSrv.hasPermission(rulePermission.delete);\n\n  const { folder, loading } = useFolder(folderUID);\n\n  if (!rule) {\n    return { isEditable: false, isRemovable: false, loading: false };\n  }\n\n  // Grafana rules can be edited if user can edit the folder they're in\n  // When RBAC is disabled access to a folder is the only requirement for managing rules\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: hasEditPermission && folder?.canSave,\n      isRemovable: hasRemovePermission && 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  const isRulerAvailable = Boolean(dataSources[rulesSourceName]?.result?.rulerConfig);\n  return {\n    isEditable: hasEditPermission && contextSrv.isEditor && isRulerAvailable,\n    isRemovable: hasRemovePermission && contextSrv.isEditor && isRulerAvailable,\n    loading: dataSources[rulesSourceName]?.loading,\n  };\n}\n"],"names":["MatcherFilter","className","onFilterChange","defaultQueryString","queryString","styles","useStyles2","getStyles","searchIcon","Icon","name","Label","Stack","gap","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","notifyApp","useAppNotification","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","rulesSourceName","getRulesSourceName","hasExplorePermission","contextSrv","AccessControlAction","leftButtons","rightButtons","isFederated","isFederatedRuleGroup","isEditable","isRemovable","useIsRuleEditable","returnTo","pathname","search","isViewMode","endsWith","deleteRule","identifier","ruleId","deleteRuleAction","navigateTo","undefined","buildShareUrl","isCloudRulesSource","appUrl","appSubUrl","config","encodeURIComponent","window","href","split","LinkButton","button","variant","createExploreLink","query","annotations","Annotation","textUtil","dashboardUID","panelId","makeRuleBasedSilenceLink","Fragment","Button","onClick","createViewLink","sourceName","editURL","urlUtil","ClipboardButton","onClipboardCopy","success","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","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","flat","flattenGrafanaManagedRules","newNamespace","flatMap","sort","a","b","localeCompare","combinedRule","checkQuery","JSON","stringify","hashQuery","slice","replace","join","useFolder","folderRequests","folders","fetchFolderIfNotFetchedAction","request","initialAsyncRequestState","folder","folderUID","namespace_uid","rulePermission","getRulesPermissions","hasEditPermission","update","hasRemovePermission","delete","canSave","isRulerAvailable","Boolean","rulerConfig"],"sourceRoot":""}