Files
grafana/public/app/features/alerting/unified/components/expressions/util.ts
Sofia Papagiannaki d1dab5828d Alerting: Update rule API to address folders by UID (#74600)
* Change ruler API to expect the folder UID as namespace

* Update example requests

* Fix tests

* Update swagger

* Modify FIle field in /api/prometheus/grafana/api/v1/rules

* Fix ruler export

* Modify folder in responses to be formatted as <parent UID>/<title>

* Add alerting test with nested folders

* Apply suggestion from code review

* Alerting: use folder UID instead of title in rule API (#77166)

Co-authored-by: Sonia Aguilar <soniaaguilarpeiron@gmail.com>

* Drop a few more latent uses of namespace_id

* move getNamespaceKey to models package

* switch GetAlertRulesForScheduling to use folder table

* update GetAlertRulesForScheduling to return folder titles in format `parent_uid/title`.

* fi tests

* add tests for GetAlertRulesForScheduling when parent uid

* fix integration tests after merge

* fix test after merge

* change format of the namespace to JSON array

this is needed for forward compatibility, when we migrate to full paths

* update EF code to decode nested folder

---------

Co-authored-by: Yuri Tseretyan <yuriy.tseretyan@grafana.com>
Co-authored-by: Virginia Cepeda <virginia.cepeda@grafana.com>
Co-authored-by: Sonia Aguilar <soniaaguilarpeiron@gmail.com>
Co-authored-by: Alex Weaver <weaver.alex.d@gmail.com>
Co-authored-by: Gilles De Mey <gilles.de.mey@gmail.com>
2024-01-17 11:07:39 +02:00

69 lines
2.1 KiB
TypeScript

import { DataFrame, Labels, roundDecimals } from '@grafana/data';
import { CombinedRuleNamespace } from 'app/types/unified-alerting';
import { isCloudRulesSource } from '../../utils/datasource';
/**
* ⚠️ `frame.fields` could be an empty array ⚠️
*
* TypeScript will NOT complain about it when accessing items via index signatures.
* Make sure to check for empty array or use optional chaining!
*
* see https://github.com/Microsoft/TypeScript/issues/13778
*/
const getSeriesName = (frame: DataFrame): string | undefined => {
const firstField = frame.fields[0];
const displayNameFromDS = firstField?.config?.displayNameFromDS;
return displayNameFromDS ?? frame.name ?? firstField?.labels?.__name__;
};
const getSeriesValue = (frame: DataFrame) => {
const value = frame.fields[0]?.values[0];
if (Number.isFinite(value)) {
return roundDecimals(value, 5);
}
return value;
};
const getSeriesLabels = (frame: DataFrame): Record<string, string> => {
const firstField = frame.fields[0];
return firstField?.labels ?? {};
};
const formatLabels = (labels: Labels): string => {
return Object.entries(labels)
.map(([key, value]) => key + '=' + value)
.join(', ');
};
/**
* After https://github.com/grafana/grafana/pull/74600,
* Grafana folder names will be returned from the API as a combination of the folder name and parent UID in a format of JSON array,
* where first element is parent UID and the second element is Title.
*/
const decodeGrafanaNamespace = (namespace: CombinedRuleNamespace): string => {
const namespaceName = namespace.name;
if (isCloudRulesSource(namespace.rulesSource)) {
return namespaceName;
}
try {
return JSON.parse(namespaceName).at(-1) ?? namespaceName;
} catch {
return namespaceName;
}
};
const isEmptySeries = (series: DataFrame[]): boolean => {
const isEmpty = series.every((serie) => serie.fields.every((field) => field.values.every((value) => value == null)));
return isEmpty;
};
export { decodeGrafanaNamespace, formatLabels, getSeriesLabels, getSeriesName, getSeriesValue, isEmptySeries };