{"version":3,"file":"7409.24316c87d08c1053c46a.js","mappings":"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","sources":["webpack://grafana/./public/app/features/alerting/unified/hooks/useManagedAlertStateHistory.ts","webpack://grafana/./public/app/features/alerting/unified/components/rules/state-history/StateHistory.tsx"],"sourcesContent":["import { useEffect } from 'react';\n\nimport { useDispatch } from 'app/types';\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>(\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 { groupBy } from 'lodash';\nimport React, { FormEvent, useCallback, useState } from 'react';\n\nimport { AlertState, dateTimeFormat, GrafanaTheme2 } from '@grafana/data';\nimport { Alert, Field, Icon, Input, Label, LoadingPlaceholder, Tooltip, useStyles2, Stack } from '@grafana/ui';\nimport { StateHistoryItem, StateHistoryItemData } from 'app/types/unified-alerting';\nimport { GrafanaAlertStateWithReason, PromAlertingRuleState } from 'app/types/unified-alerting-dto';\n\nimport { useManagedAlertStateHistory } from '../../../hooks/useManagedAlertStateHistory';\nimport { AlertLabel } from '../../AlertLabel';\nimport { DynamicTable, DynamicTableColumnProps, DynamicTableItemProps } from '../../DynamicTable';\nimport { AlertStateTag } from '../AlertStateTag';\n\ntype StateHistoryRowItem = {\n id: string;\n state: PromAlertingRuleState | GrafanaAlertStateWithReason | AlertState;\n text?: string;\n data?: StateHistoryItemData;\n timestamp?: number;\n stringifiedLabels: string;\n};\n\ntype StateHistoryMap = Record;\n\ntype StateHistoryRow = DynamicTableItemProps;\n\ninterface Props {\n alertId: string;\n}\n\nconst StateHistory = ({ alertId }: Props) => {\n const [textFilter, setTextFilter] = useState('');\n const handleTextFilter = useCallback((event: FormEvent) => {\n setTextFilter(event.currentTarget.value);\n }, []);\n\n const { loading, error, result = [] } = useManagedAlertStateHistory(alertId);\n\n const styles = useStyles2(getStyles);\n\n if (loading && !error) {\n return ;\n }\n\n if (error && !loading) {\n return {error.message};\n }\n\n const columns: Array> = [\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 // group the state history list by unique set of labels\n const tables = Object.entries(groupStateByLabels(result))\n // sort and filter each table\n .sort()\n .filter(([groupKey]) => matchKey(groupKey, textFilter))\n .map(([groupKey, items]) => {\n const tableItems: StateHistoryRow[] = items.map((historyItem) => ({\n id: historyItem.id,\n data: historyItem,\n }));\n\n return (\n
\n
\n \n {groupKey}\n \n
\n \n
\n );\n });\n\n return (\n
\n
\n }\n >\n \n \n \n \n }\n >\n } onChange={handleTextFilter} placeholder=\"Search\" />\n \n \n {tables}\n \n );\n};\n\n// group state history by labels\nexport function groupStateByLabels(\n history: Array>\n): StateHistoryMap {\n const items: StateHistoryRowItem[] = history.map((item) => {\n // let's grab the last matching set of `{}` since the alert name could also contain { or }\n const LABELS_REGEX = /{.*?}/g;\n const stringifiedLabels = item.text.match(LABELS_REGEX)?.at(-1) ?? '';\n\n return {\n id: String(item.id),\n state: item.newState,\n // let's omit the labels for each entry since it's just added noise to each state history item\n text: item.text.replace(stringifiedLabels, ''),\n data: item.data,\n timestamp: item.updated,\n stringifiedLabels,\n };\n });\n\n // we have to group our state history items by their unique combination of tags since we want to display a DynamicTable for each alert instance\n // (effectively unique combination of labels)\n return groupBy(items, (item) => item.stringifiedLabels);\n}\n\n// match a string either by exact text match or with regular expression when in the form of \"//\"\nexport function matchKey(groupKey: string, textFilter: string) {\n // if the text filter is empty we show all matches\n if (textFilter === '') {\n return true;\n }\n\n const isRegExp = textFilter.startsWith('/') && textFilter.endsWith('/');\n\n // not a regular expression, use normal text matching\n if (!isRegExp) {\n return groupKey.includes(textFilter);\n }\n\n // regular expression, try parsing and applying\n // when we fail to parse the text as a regular expression, we return no match\n try {\n return new RegExp(textFilter.slice(1, -1)).test(groupKey);\n } catch (err) {\n return false;\n }\n}\n\nfunction renderValueCell(item: StateHistoryRow) {\n const matches = item.data.data?.evalMatches ?? [];\n\n return (\n <>\n {item.data.text}\n \n {matches.map((match) => (\n \n ))}\n \n \n );\n}\n\nfunction renderStateCell(item: StateHistoryRow) {\n return ;\n}\n\nfunction renderTimestampCell(item: StateHistoryRow) {\n return (\n
{item.data.timestamp && {dateTimeFormat(item.data.timestamp)}}
\n );\n}\n\nconst LabelsWrapper = ({ children }: React.PropsWithChildren<{}>) => {\n const { wrapper } = useStyles2(getStyles);\n return
{children}
;\n};\n\nconst TimestampStyle = css`\n display: flex;\n align-items: flex-end;\n flex-direction: column;\n`;\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n wrapper: css`\n & > * {\n margin-right: ${theme.spacing(1)};\n }\n `,\n tableGroupKey: css`\n margin-top: ${theme.spacing(2)};\n margin-bottom: ${theme.spacing(2)};\n `,\n goupKeyText: css({\n overflowX: 'auto',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n display: 'block',\n }),\n});\n\nexport default StateHistory;\n"],"names":["useManagedAlertStateHistory","alertId","dispatch","history","useUnifiedAlertingSelector","state","StateHistory","textFilter","setTextFilter","handleTextFilter","event","loading","error","result","styles","getStyles","LoadingPlaceholder","Alert","columns","renderStateCell","renderValueCell","renderTimestampCell","tables","groupStateByLabels","groupKey","matchKey","items","tableItems","historyItem","DynamicTable","Field","Label","Stack","Tooltip","Icon","Input","item","LABELS_REGEX","stringifiedLabels","matches","LabelsWrapper","match","AlertLabel","AlertStateTag","TimestampStyle","children","wrapper","theme"],"sourceRoot":""}