UNPKG

@grafana/alerting

Version:

Grafana Alerting Library – Build vertical integrations on top of the industry-leading alerting solution

1,169 lines (1,150 loc) • 40.6 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var jsxRuntime = require('react/jsx-runtime'); var css = require('@emotion/css'); var lodash = require('lodash'); var react = require('react'); var i18n = require('@grafana/i18n'); var ui = require('@grafana/ui'); var tinycolor2 = require('tinycolor2'); var react$1 = require('@reduxjs/toolkit/query/react'); var runtime = require('@grafana/runtime'); var data = require('@grafana/data'); function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; } var tinycolor2__default = /*#__PURE__*/_interopDefaultCompat(tinycolor2); "use strict"; const GRAFANA_ORIGIN_LABEL = "__grafana_origin"; function isPrivateLabelKey(labelKey) { return labelKey.startsWith("__") && labelKey.endsWith("__") || labelKey === GRAFANA_ORIGIN_LABEL; } const isPrivateLabel = ([key, _]) => isPrivateLabelKey(key); function findCommonLabels(labelSets) { if (!Array.isArray(labelSets) || labelSets.length === 0) { return {}; } return labelSets.reduce( (acc, labels) => { if (!labels) { throw new Error("Need parsed labels to find common labels."); } Object.keys(labels).forEach((key) => { if (acc[key] === void 0 || acc[key] !== labels[key]) { delete acc[key]; } }); Object.keys(acc).forEach((key) => { if (labels[key] === void 0) { delete acc[key]; } }); return acc; }, { ...labelSets[0] } ); } "use strict"; const AlertLabel = (props) => { const { labelKey, value, icon, color, colorBy, size = "md", onClick, ...rest } = props; const theColor = getColorFromProps({ color, colorBy, labelKey, value }); const styles = ui.useStyles2(getStyles$1, theColor, size); const ariaLabel = `${labelKey}: ${value}`; const keyless = !Boolean(labelKey); const innerLabel = react.useMemo( () => /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { direction: "row", gap: 0, alignItems: "stretch", children: [ labelKey && /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles.label, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { direction: "row", gap: 0.5, alignItems: "center", children: [ icon && /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { name: icon }), labelKey && /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles.labelText, title: labelKey.toString(), children: labelKey != null ? labelKey : "" }) ] }) }), /* @__PURE__ */ jsxRuntime.jsx("div", { className: css.cx(styles.value, keyless && styles.valueWithoutKey), title: value == null ? void 0 : value.toString(), children: value != null ? value : "-" }) ] }), [labelKey, styles.label, styles.labelText, styles.value, styles.valueWithoutKey, icon, keyless, value] ); return /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles.wrapper, "aria-label": ariaLabel, "data-testid": "label-value", ...rest, children: onClick && (labelKey || value) ? /* @__PURE__ */ jsxRuntime.jsx( "button", { type: "button", className: styles.clickable, onClick: () => onClick == null ? void 0 : onClick([value != null ? value : "", labelKey != null ? labelKey : ""]), children: innerLabel }, `${labelKey != null ? labelKey : ""}${value != null ? value : ""}` ) : innerLabel }); }; function getAccessibleTagColor(name) { if (!name) { return; } const attempts = Array.from({ length: 6 }, (_, i) => name + "-".repeat(i)); const readableAttempt = attempts.find((attempt) => { const candidate = ui.getTagColorsFromName(attempt).color; return tinycolor2__default.default.isReadable(candidate, "#000", { level: "AA", size: "small" }) || tinycolor2__default.default.isReadable(candidate, "#fff", { level: "AA", size: "small" }); }); const chosen = readableAttempt != null ? readableAttempt : name; return ui.getTagColorsFromName(chosen).color; } function getColorFromProps({ color, colorBy, labelKey, value }) { if (color) { return getAccessibleTagColor(color); } if (colorBy === "key") { return getAccessibleTagColor(labelKey); } if (colorBy === "value") { return getAccessibleTagColor(value); } if (colorBy === "both" && labelKey && value) { return getAccessibleTagColor(labelKey + value); } return; } function getReadableFontColor(bg, fallback) { if (tinycolor2__default.default.isReadable(bg, "#000", { level: "AA", size: "small" })) { return "#000"; } if (tinycolor2__default.default.isReadable(bg, "#fff", { level: "AA", size: "small" })) { return "#fff"; } if (tinycolor2__default.default.isReadable(bg, fallback, { level: "AA", size: "small" })) { return tinycolor2__default.default(fallback).toHexString(); } return tinycolor2__default.default.mostReadable(bg, ["#000", "#fff", fallback], { includeFallbackColors: true }).toHexString(); } const getStyles$1 = (theme, color, size) => { const backgroundColor = color != null ? color : theme.colors.secondary.main; const borderColor = theme.isDark ? tinycolor2__default.default(backgroundColor).lighten(5).toString() : tinycolor2__default.default(backgroundColor).darken(5).toString(); const valueBackgroundColor = theme.isDark ? tinycolor2__default.default(backgroundColor).darken(5).toString() : tinycolor2__default.default(backgroundColor).lighten(5).toString(); const labelFontColor = color ? getReadableFontColor(backgroundColor, theme.colors.text.primary) : theme.colors.text.primary; const valueFontColor = color ? getReadableFontColor(valueBackgroundColor, theme.colors.text.primary) : theme.colors.text.primary; let padding = theme.spacing(0.33, 1); switch (size) { case "sm": padding = theme.spacing(0.2, 0.6); break; case "xs": padding = theme.spacing(0, 0.5); break; default: break; } return { wrapper: css.css({ fontSize: theme.typography.bodySmall.fontSize, borderRadius: theme.shape.borderRadius(2) }), labelText: css.css({ whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", maxWidth: "300px" }), label: css.css({ display: "flex", alignItems: "center", color: labelFontColor, padding, background: backgroundColor, border: `solid 1px ${borderColor}`, borderTopLeftRadius: theme.shape.borderRadius(2), borderBottomLeftRadius: theme.shape.borderRadius(2) }), clickable: css.css({ border: "none", background: "none", outline: "none", boxShadow: "none", padding: 0, margin: 0, "&:hover": { opacity: 0.8, cursor: "pointer" } }), value: css.css({ color: valueFontColor, padding, background: valueBackgroundColor, border: `solid 1px ${borderColor}`, borderLeft: "none", borderTopRightRadius: theme.shape.borderRadius(2), borderBottomRightRadius: theme.shape.borderRadius(2), whiteSpace: "pre", overflow: "hidden", textOverflow: "ellipsis", maxWidth: "300px" }), valueWithoutKey: css.css({ borderTopLeftRadius: theme.shape.borderRadius(2), borderBottomLeftRadius: theme.shape.borderRadius(2), borderLeft: `solid 1px ${borderColor}` }) }; }; "use strict"; const AlertLabels = ({ labels, displayCommonLabels, labelSets, size, onClick, commonLabelsMode = "expand" }) => { const styles = ui.useStyles2(getStyles, size); const [showCommonLabels, setShowCommonLabels] = react.useState(false); const computedCommonLabels = react.useMemo( () => displayCommonLabels && Array.isArray(labelSets) && labelSets.length > 1 ? findCommonLabels(labelSets) : {}, [displayCommonLabels, labelSets] ); const labelsToShow = lodash.chain(labels).toPairs().reject(isPrivateLabel).reject(([key]) => showCommonLabels ? false : key in computedCommonLabels).value(); const commonLabelsCount = Object.keys(computedCommonLabels).length; const hasCommonLabels = commonLabelsCount > 0; const tooltip = i18n.t("alert-labels.button.show.tooltip", "Show common labels"); const commonLabelsTooltip = react.useMemo( () => /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { "data-testid": "common-labels-tooltip-content", role: "list", direction: "row", wrap: "wrap", gap: 1, width: 48, children: Object.entries(computedCommonLabels).map(([label, value]) => /* @__PURE__ */ jsxRuntime.jsx(AlertLabel, { size, labelKey: label, value, colorBy: "key", role: "listitem" }, label + value)) }), [computedCommonLabels, size] ); return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles.wrapper, role: "list", "aria-label": i18n.t("alerting.alert-labels.aria-label-labels", "Labels"), children: [ labelsToShow.map(([label, value]) => { return /* @__PURE__ */ jsxRuntime.jsx( AlertLabel, { size, labelKey: label, value, colorBy: "key", onClick, role: "listitem" }, label + value ); }), !showCommonLabels && hasCommonLabels && /* @__PURE__ */ jsxRuntime.jsx("div", { role: "listitem", children: commonLabelsMode === "expand" ? /* @__PURE__ */ jsxRuntime.jsx( ui.Button, { variant: "secondary", fill: "text", onClick: () => setShowCommonLabels(true), tooltip, tooltipPlacement: "top", size: "sm", children: /* @__PURE__ */ jsxRuntime.jsxs(i18n.Trans, { i18nKey: "alerting.alert-labels.common-labels-count", count: commonLabelsCount, children: [ "+", "{{count}}", " common labels" ] }) } ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Toggletip, { content: commonLabelsTooltip, closeButton: false, fitContent: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { "data-testid": "common-labels-tooltip-trigger", variant: "secondary", fill: "text", size: "sm", children: /* @__PURE__ */ jsxRuntime.jsxs(i18n.Trans, { i18nKey: "alerting.alert-labels.common-labels-count", count: commonLabelsCount, children: [ "+", "{{count}}", " common labels" ] }) }) }) }), showCommonLabels && hasCommonLabels && /* @__PURE__ */ jsxRuntime.jsx("div", { role: "listitem", children: /* @__PURE__ */ jsxRuntime.jsx( ui.Button, { variant: "secondary", fill: "text", onClick: () => setShowCommonLabels(false), tooltipPlacement: "top", size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(i18n.Trans, { i18nKey: "alert-labels.button.hide", children: "Hide common labels" }) } ) }) ] }); }; const getStyles = (theme, size) => { return { wrapper: css.css({ display: "flex", flexWrap: "wrap", alignItems: "center", gap: size === "md" ? theme.spacing() : theme.spacing(0.5) }) }; }; "use strict"; const getAPINamespace = () => runtime.config.namespace; const getAPIBaseURL = (group, version) => { const subPath = runtime.config.appSubUrl || ""; return `${subPath}/apis/${group}/${version}/namespaces/${getAPINamespace()}`; }; const getAPIReducerPath = (group, version) => `${group}/${version}`; const isWellFormed = (str) => { try { encodeURIComponent(str); return true; } catch (error) { return false; } }; const base64UrlEncode = (value) => { if (!isWellFormed(value)) { throw new Error(`Cannot encode malformed UTF-16 string with lone surrogates: ${value}`); } const bytes = new TextEncoder().encode(value); const binString = String.fromCodePoint(...bytes); const base64 = btoa(binString); return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, ""); }; "use strict"; const VERSION = "v0alpha1"; const GROUP = "notifications.alerting.grafana.app"; "use strict"; const baseUrl = getAPIBaseURL(GROUP, VERSION); const reducerPath = getAPIReducerPath(GROUP, VERSION); const api = react$1.createApi({ reducerPath, baseQuery: react$1.fetchBaseQuery({ // Set URL correctly so MSW can intercept requests // https://mswjs.io/docs/runbook#rtk-query-requests-are-not-intercepted baseUrl: new URL(baseUrl, globalThis.location.origin).href }), endpoints: () => ({}) }); "use strict"; const addTagTypes = ["API Discovery", "Receiver", "RoutingTree", "TemplateGroup", "TimeInterval"]; const injectedRtkApi = api.enhanceEndpoints({ addTagTypes }).injectEndpoints({ endpoints: (build) => ({ getApiResources: build.query({ query: () => ({ url: `/apis/notifications.alerting.grafana.app/v0alpha1/` }), providesTags: ["API Discovery"] }), listReceiver: build.query({ query: (queryArg) => ({ url: `/receivers`, params: { pretty: queryArg.pretty, allowWatchBookmarks: queryArg.allowWatchBookmarks, continue: queryArg["continue"], fieldSelector: queryArg.fieldSelector, labelSelector: queryArg.labelSelector, limit: queryArg.limit, resourceVersion: queryArg.resourceVersion, resourceVersionMatch: queryArg.resourceVersionMatch, sendInitialEvents: queryArg.sendInitialEvents, timeoutSeconds: queryArg.timeoutSeconds, watch: queryArg.watch } }), providesTags: ["Receiver"] }), createReceiver: build.mutation({ query: (queryArg) => ({ url: `/receivers`, method: "POST", body: queryArg.receiver, params: { pretty: queryArg.pretty, dryRun: queryArg.dryRun, fieldManager: queryArg.fieldManager, fieldValidation: queryArg.fieldValidation } }), invalidatesTags: ["Receiver"] }), deletecollectionReceiver: build.mutation({ query: (queryArg) => ({ url: `/receivers`, method: "DELETE", params: { pretty: queryArg.pretty, continue: queryArg["continue"], dryRun: queryArg.dryRun, fieldSelector: queryArg.fieldSelector, gracePeriodSeconds: queryArg.gracePeriodSeconds, ignoreStoreReadErrorWithClusterBreakingPotential: queryArg.ignoreStoreReadErrorWithClusterBreakingPotential, labelSelector: queryArg.labelSelector, limit: queryArg.limit, orphanDependents: queryArg.orphanDependents, propagationPolicy: queryArg.propagationPolicy, resourceVersion: queryArg.resourceVersion, resourceVersionMatch: queryArg.resourceVersionMatch, sendInitialEvents: queryArg.sendInitialEvents, timeoutSeconds: queryArg.timeoutSeconds } }), invalidatesTags: ["Receiver"] }), getReceiver: build.query({ query: (queryArg) => ({ url: `/receivers/${queryArg.name}`, params: { pretty: queryArg.pretty } }), providesTags: ["Receiver"] }), replaceReceiver: build.mutation({ query: (queryArg) => ({ url: `/receivers/${queryArg.name}`, method: "PUT", body: queryArg.receiver, params: { pretty: queryArg.pretty, dryRun: queryArg.dryRun, fieldManager: queryArg.fieldManager, fieldValidation: queryArg.fieldValidation } }), invalidatesTags: ["Receiver"] }), deleteReceiver: build.mutation({ query: (queryArg) => ({ url: `/receivers/${queryArg.name}`, method: "DELETE", params: { pretty: queryArg.pretty, dryRun: queryArg.dryRun, gracePeriodSeconds: queryArg.gracePeriodSeconds, ignoreStoreReadErrorWithClusterBreakingPotential: queryArg.ignoreStoreReadErrorWithClusterBreakingPotential, orphanDependents: queryArg.orphanDependents, propagationPolicy: queryArg.propagationPolicy } }), invalidatesTags: ["Receiver"] }), updateReceiver: build.mutation({ query: (queryArg) => ({ url: `/receivers/${queryArg.name}`, method: "PATCH", body: queryArg.patch, params: { pretty: queryArg.pretty, dryRun: queryArg.dryRun, fieldManager: queryArg.fieldManager, fieldValidation: queryArg.fieldValidation, force: queryArg.force } }), invalidatesTags: ["Receiver"] }), getReceiverStatus: build.query({ query: (queryArg) => ({ url: `/receivers/${queryArg.name}/status`, params: { pretty: queryArg.pretty } }), providesTags: ["Receiver"] }), replaceReceiverStatus: build.mutation({ query: (queryArg) => ({ url: `/receivers/${queryArg.name}/status`, method: "PUT", body: queryArg.receiver, params: { pretty: queryArg.pretty, dryRun: queryArg.dryRun, fieldManager: queryArg.fieldManager, fieldValidation: queryArg.fieldValidation } }), invalidatesTags: ["Receiver"] }), updateReceiverStatus: build.mutation({ query: (queryArg) => ({ url: `/receivers/${queryArg.name}/status`, method: "PATCH", body: queryArg.patch, params: { pretty: queryArg.pretty, dryRun: queryArg.dryRun, fieldManager: queryArg.fieldManager, fieldValidation: queryArg.fieldValidation, force: queryArg.force } }), invalidatesTags: ["Receiver"] }), listRoutingTree: build.query({ query: (queryArg) => ({ url: `/routingtrees`, params: { pretty: queryArg.pretty, allowWatchBookmarks: queryArg.allowWatchBookmarks, continue: queryArg["continue"], fieldSelector: queryArg.fieldSelector, labelSelector: queryArg.labelSelector, limit: queryArg.limit, resourceVersion: queryArg.resourceVersion, resourceVersionMatch: queryArg.resourceVersionMatch, sendInitialEvents: queryArg.sendInitialEvents, timeoutSeconds: queryArg.timeoutSeconds, watch: queryArg.watch } }), providesTags: ["RoutingTree"] }), createRoutingTree: build.mutation({ query: (queryArg) => ({ url: `/routingtrees`, method: "POST", body: queryArg.routingTree, params: { pretty: queryArg.pretty, dryRun: queryArg.dryRun, fieldManager: queryArg.fieldManager, fieldValidation: queryArg.fieldValidation } }), invalidatesTags: ["RoutingTree"] }), deletecollectionRoutingTree: build.mutation({ query: (queryArg) => ({ url: `/routingtrees`, method: "DELETE", params: { pretty: queryArg.pretty, continue: queryArg["continue"], dryRun: queryArg.dryRun, fieldSelector: queryArg.fieldSelector, gracePeriodSeconds: queryArg.gracePeriodSeconds, ignoreStoreReadErrorWithClusterBreakingPotential: queryArg.ignoreStoreReadErrorWithClusterBreakingPotential, labelSelector: queryArg.labelSelector, limit: queryArg.limit, orphanDependents: queryArg.orphanDependents, propagationPolicy: queryArg.propagationPolicy, resourceVersion: queryArg.resourceVersion, resourceVersionMatch: queryArg.resourceVersionMatch, sendInitialEvents: queryArg.sendInitialEvents, timeoutSeconds: queryArg.timeoutSeconds } }), invalidatesTags: ["RoutingTree"] }), getRoutingTree: build.query({ query: (queryArg) => ({ url: `/routingtrees/${queryArg.name}`, params: { pretty: queryArg.pretty } }), providesTags: ["RoutingTree"] }), replaceRoutingTree: build.mutation({ query: (queryArg) => ({ url: `/routingtrees/${queryArg.name}`, method: "PUT", body: queryArg.routingTree, params: { pretty: queryArg.pretty, dryRun: queryArg.dryRun, fieldManager: queryArg.fieldManager, fieldValidation: queryArg.fieldValidation } }), invalidatesTags: ["RoutingTree"] }), deleteRoutingTree: build.mutation({ query: (queryArg) => ({ url: `/routingtrees/${queryArg.name}`, method: "DELETE", params: { pretty: queryArg.pretty, dryRun: queryArg.dryRun, gracePeriodSeconds: queryArg.gracePeriodSeconds, ignoreStoreReadErrorWithClusterBreakingPotential: queryArg.ignoreStoreReadErrorWithClusterBreakingPotential, orphanDependents: queryArg.orphanDependents, propagationPolicy: queryArg.propagationPolicy } }), invalidatesTags: ["RoutingTree"] }), updateRoutingTree: build.mutation({ query: (queryArg) => ({ url: `/routingtrees/${queryArg.name}`, method: "PATCH", body: queryArg.patch, params: { pretty: queryArg.pretty, dryRun: queryArg.dryRun, fieldManager: queryArg.fieldManager, fieldValidation: queryArg.fieldValidation, force: queryArg.force } }), invalidatesTags: ["RoutingTree"] }), getRoutingTreeStatus: build.query({ query: (queryArg) => ({ url: `/routingtrees/${queryArg.name}/status`, params: { pretty: queryArg.pretty } }), providesTags: ["RoutingTree"] }), replaceRoutingTreeStatus: build.mutation({ query: (queryArg) => ({ url: `/routingtrees/${queryArg.name}/status`, method: "PUT", body: queryArg.routingTree, params: { pretty: queryArg.pretty, dryRun: queryArg.dryRun, fieldManager: queryArg.fieldManager, fieldValidation: queryArg.fieldValidation } }), invalidatesTags: ["RoutingTree"] }), updateRoutingTreeStatus: build.mutation({ query: (queryArg) => ({ url: `/routingtrees/${queryArg.name}/status`, method: "PATCH", body: queryArg.patch, params: { pretty: queryArg.pretty, dryRun: queryArg.dryRun, fieldManager: queryArg.fieldManager, fieldValidation: queryArg.fieldValidation, force: queryArg.force } }), invalidatesTags: ["RoutingTree"] }), listTemplateGroup: build.query({ query: (queryArg) => ({ url: `/templategroups`, params: { pretty: queryArg.pretty, allowWatchBookmarks: queryArg.allowWatchBookmarks, continue: queryArg["continue"], fieldSelector: queryArg.fieldSelector, labelSelector: queryArg.labelSelector, limit: queryArg.limit, resourceVersion: queryArg.resourceVersion, resourceVersionMatch: queryArg.resourceVersionMatch, sendInitialEvents: queryArg.sendInitialEvents, timeoutSeconds: queryArg.timeoutSeconds, watch: queryArg.watch } }), providesTags: ["TemplateGroup"] }), createTemplateGroup: build.mutation({ query: (queryArg) => ({ url: `/templategroups`, method: "POST", body: queryArg.templateGroup, params: { pretty: queryArg.pretty, dryRun: queryArg.dryRun, fieldManager: queryArg.fieldManager, fieldValidation: queryArg.fieldValidation } }), invalidatesTags: ["TemplateGroup"] }), deletecollectionTemplateGroup: build.mutation({ query: (queryArg) => ({ url: `/templategroups`, method: "DELETE", params: { pretty: queryArg.pretty, continue: queryArg["continue"], dryRun: queryArg.dryRun, fieldSelector: queryArg.fieldSelector, gracePeriodSeconds: queryArg.gracePeriodSeconds, ignoreStoreReadErrorWithClusterBreakingPotential: queryArg.ignoreStoreReadErrorWithClusterBreakingPotential, labelSelector: queryArg.labelSelector, limit: queryArg.limit, orphanDependents: queryArg.orphanDependents, propagationPolicy: queryArg.propagationPolicy, resourceVersion: queryArg.resourceVersion, resourceVersionMatch: queryArg.resourceVersionMatch, sendInitialEvents: queryArg.sendInitialEvents, timeoutSeconds: queryArg.timeoutSeconds } }), invalidatesTags: ["TemplateGroup"] }), getTemplateGroup: build.query({ query: (queryArg) => ({ url: `/templategroups/${queryArg.name}`, params: { pretty: queryArg.pretty } }), providesTags: ["TemplateGroup"] }), replaceTemplateGroup: build.mutation({ query: (queryArg) => ({ url: `/templategroups/${queryArg.name}`, method: "PUT", body: queryArg.templateGroup, params: { pretty: queryArg.pretty, dryRun: queryArg.dryRun, fieldManager: queryArg.fieldManager, fieldValidation: queryArg.fieldValidation } }), invalidatesTags: ["TemplateGroup"] }), deleteTemplateGroup: build.mutation({ query: (queryArg) => ({ url: `/templategroups/${queryArg.name}`, method: "DELETE", params: { pretty: queryArg.pretty, dryRun: queryArg.dryRun, gracePeriodSeconds: queryArg.gracePeriodSeconds, ignoreStoreReadErrorWithClusterBreakingPotential: queryArg.ignoreStoreReadErrorWithClusterBreakingPotential, orphanDependents: queryArg.orphanDependents, propagationPolicy: queryArg.propagationPolicy } }), invalidatesTags: ["TemplateGroup"] }), updateTemplateGroup: build.mutation({ query: (queryArg) => ({ url: `/templategroups/${queryArg.name}`, method: "PATCH", body: queryArg.patch, params: { pretty: queryArg.pretty, dryRun: queryArg.dryRun, fieldManager: queryArg.fieldManager, fieldValidation: queryArg.fieldValidation, force: queryArg.force } }), invalidatesTags: ["TemplateGroup"] }), getTemplateGroupStatus: build.query({ query: (queryArg) => ({ url: `/templategroups/${queryArg.name}/status`, params: { pretty: queryArg.pretty } }), providesTags: ["TemplateGroup"] }), replaceTemplateGroupStatus: build.mutation({ query: (queryArg) => ({ url: `/templategroups/${queryArg.name}/status`, method: "PUT", body: queryArg.templateGroup, params: { pretty: queryArg.pretty, dryRun: queryArg.dryRun, fieldManager: queryArg.fieldManager, fieldValidation: queryArg.fieldValidation } }), invalidatesTags: ["TemplateGroup"] }), updateTemplateGroupStatus: build.mutation({ query: (queryArg) => ({ url: `/templategroups/${queryArg.name}/status`, method: "PATCH", body: queryArg.patch, params: { pretty: queryArg.pretty, dryRun: queryArg.dryRun, fieldManager: queryArg.fieldManager, fieldValidation: queryArg.fieldValidation, force: queryArg.force } }), invalidatesTags: ["TemplateGroup"] }), listTimeInterval: build.query({ query: (queryArg) => ({ url: `/timeintervals`, params: { pretty: queryArg.pretty, allowWatchBookmarks: queryArg.allowWatchBookmarks, continue: queryArg["continue"], fieldSelector: queryArg.fieldSelector, labelSelector: queryArg.labelSelector, limit: queryArg.limit, resourceVersion: queryArg.resourceVersion, resourceVersionMatch: queryArg.resourceVersionMatch, sendInitialEvents: queryArg.sendInitialEvents, timeoutSeconds: queryArg.timeoutSeconds, watch: queryArg.watch } }), providesTags: ["TimeInterval"] }), createTimeInterval: build.mutation({ query: (queryArg) => ({ url: `/timeintervals`, method: "POST", body: queryArg.timeInterval, params: { pretty: queryArg.pretty, dryRun: queryArg.dryRun, fieldManager: queryArg.fieldManager, fieldValidation: queryArg.fieldValidation } }), invalidatesTags: ["TimeInterval"] }), deletecollectionTimeInterval: build.mutation({ query: (queryArg) => ({ url: `/timeintervals`, method: "DELETE", params: { pretty: queryArg.pretty, continue: queryArg["continue"], dryRun: queryArg.dryRun, fieldSelector: queryArg.fieldSelector, gracePeriodSeconds: queryArg.gracePeriodSeconds, ignoreStoreReadErrorWithClusterBreakingPotential: queryArg.ignoreStoreReadErrorWithClusterBreakingPotential, labelSelector: queryArg.labelSelector, limit: queryArg.limit, orphanDependents: queryArg.orphanDependents, propagationPolicy: queryArg.propagationPolicy, resourceVersion: queryArg.resourceVersion, resourceVersionMatch: queryArg.resourceVersionMatch, sendInitialEvents: queryArg.sendInitialEvents, timeoutSeconds: queryArg.timeoutSeconds } }), invalidatesTags: ["TimeInterval"] }), getTimeInterval: build.query({ query: (queryArg) => ({ url: `/timeintervals/${queryArg.name}`, params: { pretty: queryArg.pretty } }), providesTags: ["TimeInterval"] }), replaceTimeInterval: build.mutation({ query: (queryArg) => ({ url: `/timeintervals/${queryArg.name}`, method: "PUT", body: queryArg.timeInterval, params: { pretty: queryArg.pretty, dryRun: queryArg.dryRun, fieldManager: queryArg.fieldManager, fieldValidation: queryArg.fieldValidation } }), invalidatesTags: ["TimeInterval"] }), deleteTimeInterval: build.mutation({ query: (queryArg) => ({ url: `/timeintervals/${queryArg.name}`, method: "DELETE", params: { pretty: queryArg.pretty, dryRun: queryArg.dryRun, gracePeriodSeconds: queryArg.gracePeriodSeconds, ignoreStoreReadErrorWithClusterBreakingPotential: queryArg.ignoreStoreReadErrorWithClusterBreakingPotential, orphanDependents: queryArg.orphanDependents, propagationPolicy: queryArg.propagationPolicy } }), invalidatesTags: ["TimeInterval"] }), updateTimeInterval: build.mutation({ query: (queryArg) => ({ url: `/timeintervals/${queryArg.name}`, method: "PATCH", body: queryArg.patch, params: { pretty: queryArg.pretty, dryRun: queryArg.dryRun, fieldManager: queryArg.fieldManager, fieldValidation: queryArg.fieldValidation, force: queryArg.force } }), invalidatesTags: ["TimeInterval"] }), getTimeIntervalStatus: build.query({ query: (queryArg) => ({ url: `/timeintervals/${queryArg.name}/status`, params: { pretty: queryArg.pretty } }), providesTags: ["TimeInterval"] }), replaceTimeIntervalStatus: build.mutation({ query: (queryArg) => ({ url: `/timeintervals/${queryArg.name}/status`, method: "PUT", body: queryArg.timeInterval, params: { pretty: queryArg.pretty, dryRun: queryArg.dryRun, fieldManager: queryArg.fieldManager, fieldValidation: queryArg.fieldValidation } }), invalidatesTags: ["TimeInterval"] }), updateTimeIntervalStatus: build.mutation({ query: (queryArg) => ({ url: `/timeintervals/${queryArg.name}/status`, method: "PATCH", body: queryArg.patch, params: { pretty: queryArg.pretty, dryRun: queryArg.dryRun, fieldManager: queryArg.fieldManager, fieldValidation: queryArg.fieldValidation, force: queryArg.force } }), invalidatesTags: ["TimeInterval"] }) }), overrideExisting: false }); "use strict"; const USER_DEFINED_TREE_NAME = "user-defined"; "use strict"; function matchLabels(matchers, labels) { const matches = matchLabelsSet(matchers, labels); const details = labels.map((_label, index) => ({ labelIndex: index, match: false, matcher: null })); matchers.forEach((matcher) => { const matchingLabelIndex = labels.findIndex((label) => isLabelMatch(matcher, label)); if (matchingLabelIndex > -1) { details[matchingLabelIndex].match = true; details[matchingLabelIndex].matcher = matcher; } }); return { matches, details }; } function isLabelMatch(matcher, label) { const [labelKey, labelValue] = label; const { label: matcherLabel, type: matcherType, value: matcherValue } = matcher; if (labelKey !== matcherLabel) { return false; } const matchFunction = OperatorFunctions[matcherType]; return matchFunction(labelValue, matcherValue); } function matchLabelsSet(matchers, labels) { for (const matcher of matchers) { if (!isLabelMatchInSet(matcher, labels)) { return false; } } return true; } function isLabelMatchInSet(matcher, labels) { const { label, type, value } = matcher; let labelValue = ""; const labelForMatcher = Object.fromEntries(labels)[label]; if (labelForMatcher) { labelValue = labelForMatcher; } const matchFunction = OperatorFunctions[type]; try { return matchFunction(labelValue, value); } catch (err) { return false; } } const OperatorFunctions = { "=": (lv, mv) => lv === mv, "!=": (lv, mv) => lv !== mv, // At the time of writing, Alertmanager compiles to another (anchored) Regular Expression, // so we should also anchor our UI matches for consistency with this behaviour // https://github.com/prometheus/alertmanager/blob/fd37ce9c95898ca68be1ab4d4529517174b73c33/pkg/labels/matcher.go#L69 "=~": (lv, mv) => { const valueWithFlagsParsed = data.parseFlags(`^(?:${mv})$`); const re = new RegExp(valueWithFlagsParsed.cleaned, valueWithFlagsParsed.flags); return re.test(lv); }, "!~": (lv, mv) => { const valueWithFlagsParsed = data.parseFlags(`^(?:${mv})$`); const re = new RegExp(valueWithFlagsParsed.cleaned, valueWithFlagsParsed.flags); return !re.test(lv); } }; "use strict"; const INHERITABLE_KEYS = ["receiver", "group_by", "group_wait", "group_interval", "repeat_interval"]; function findMatchingRoutes(route, labels, matchingJourney = []) { var _a; let childMatches = []; const matchResult = matchLabels((_a = route.matchers) != null ? _a : [], labels); const currentMatchInfo = { route, matchDetails: matchResult.details, matched: matchResult.matches }; const currentMatchingJourney = [...matchingJourney, currentMatchInfo]; if (!matchResult.matches) { return []; } if (route.routes) { for (const child of route.routes) { const matchingChildren = findMatchingRoutes(child, labels, currentMatchingJourney); childMatches = childMatches.concat(matchingChildren); if (matchingChildren.length && !child.continue) { break; } } } if (childMatches.length === 0) { childMatches.push({ route, labels, matchingJourney: currentMatchingJourney }); } return childMatches; } function computeInheritedTree(parent) { var _a; return { ...parent, routes: (_a = parent.routes) == null ? void 0 : _a.map((child) => { const inheritedProperties = getInheritedProperties(parent, child); return computeInheritedTree({ ...child, ...inheritedProperties }); }) }; } function getInheritedProperties(parentRoute, childRoute, propertiesParentInherited) { const propsFromParent = lodash.pick(parentRoute, INHERITABLE_KEYS); const inheritableProperties = { ...propsFromParent, ...propertiesParentInherited }; const inherited = lodash.reduce( inheritableProperties, (inheritedProperties, parentValue, property) => { var _a; const parentHasValue = parentValue != null; const inheritableValues = [void 0, "", null]; const childIsInheriting = inheritableValues.some((value) => childRoute[property] === value); const inheritFromValue = childIsInheriting && parentHasValue; const inheritEmptyGroupByFromParent = property === "group_by" && parentHasValue && lodash.isArray(childRoute[property]) && ((_a = childRoute[property]) == null ? void 0 : _a.length) === 0; const inheritFromParent = inheritFromValue || inheritEmptyGroupByFromParent; if (inheritFromParent) { inheritedProperties[property] = parentValue; } return inheritedProperties; }, {} ); return inherited; } function addUniqueIdentifier(route) { var _a, _b; return { id: lodash.uniqueId("route-"), ...route, routes: (_b = (_a = route.routes) == null ? void 0 : _a.map(addUniqueIdentifier)) != null ? _b : [] }; } function matchInstancesToRoute(rootRoute, instances) { const matchedPolicies = /* @__PURE__ */ new Map(); const expandedTree = addUniqueIdentifier(computeInheritedTree(rootRoute)); const matchesArray = instances.flatMap((labels) => findMatchingRoutes(expandedTree, labels)); const groupedByRoute = lodash.groupBy(matchesArray, (match) => match.route.id); Object.entries(groupedByRoute).forEach(([_key, match]) => { matchedPolicies.set(match[0].route, match); }); return { expandedTree, matchedPolicies }; } function convertRoutingTreeToRoute(routingTree) { const convertRoutingTreeRoutes = (routes) => { return routes.map( (route) => ({ ...route, routes: route.routes ? convertRoutingTreeRoutes(route.routes) : [] }) ); }; const rootRoute = { ...routingTree.spec.defaults, continue: false, active_time_intervals: [], mute_time_intervals: [], matchers: [], // Root route has no matchers (catch-all) routes: convertRoutingTreeRoutes(routingTree.spec.routes) }; return rootRoute; } "use strict"; function useMatchInstancesToRouteTrees() { const { data, ...rest } = injectedRtkApi.endpoints.listRoutingTree.useQuery( {}, { refetchOnFocus: true, refetchOnReconnect: true } ); const memoizedFunction = react.useCallback( (instances) => { var _a; return matchInstancesToRouteTrees((_a = data == null ? void 0 : data.items) != null ? _a : [], instances); }, [data == null ? void 0 : data.items] ); return { matchInstancesToRouteTrees: memoizedFunction, ...rest }; } function matchInstancesToRouteTrees(trees, instances) { const treeMatches = trees.map((tree) => { const rootRoute = convertRoutingTreeToRoute(tree); return matchInstancesToRoute(rootRoute, instances); }); return instances.map((labels) => { const allMatchedRoutes = treeMatches.flatMap(({ expandedTree, matchedPolicies }, index) => { const tree = trees[index]; return Array.from(matchedPolicies.entries()).flatMap( ([route, results]) => results.filter((matchDetails) => matchDetails.labels === labels).map((matchDetails) => { var _a; return { route, routeTree: { metadata: { name: (_a = tree.metadata.name) != null ? _a : USER_DEFINED_TREE_NAME }, expandedSpec: expandedTree }, matchDetails }; }) ); }); return { labels, matchedRoutes: allMatchedRoutes }; }); } "use strict"; "use strict"; exports.AlertLabel = AlertLabel; exports.AlertLabels = AlertLabels; exports.USER_DEFINED_TREE_NAME = USER_DEFINED_TREE_NAME; exports.base64UrlEncode = base64UrlEncode; exports.computeInheritedTree = computeInheritedTree; exports.findMatchingRoutes = findMatchingRoutes; exports.getInheritedProperties = getInheritedProperties; exports.matchInstancesToRoute = matchInstancesToRoute; exports.matchInstancesToRouteTrees = matchInstancesToRouteTrees; exports.useMatchInstancesToRouteTrees = useMatchInstancesToRouteTrees; //# sourceMappingURL=index.cjs.map