mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
* 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>
69 lines
2.1 KiB
TypeScript
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 };
|