gitlab-org--gitlab-foss/app/assets/javascripts/monitoring/stores/getters.js

174 lines
4.9 KiB
JavaScript

import { NOT_IN_DB_PREFIX } from '../constants';
import {
addPrefixToCustomVariableParams,
addDashboardMetaDataToLink,
normalizeCustomDashboardPath,
} from './utils';
const metricsIdsInPanel = (panel) =>
panel.metrics
.filter((metric) => metric.metricId && metric.result)
.map((metric) => metric.metricId);
/**
* Returns a reference to the currently selected dashboard
* from the list of dashboards.
*
* @param {Object} state
*/
export const selectedDashboard = (state, getters) => {
const { allDashboards } = state;
return (
allDashboards.find((d) => d.path === getters.fullDashboardPath) ||
allDashboards.find((d) => d.default) ||
null
);
};
/**
* Get all state for metric in the dashboard or a group. The
* states are not repeated so the dashboard or group can show
* a global state.
*
* @param {Object} state
* @returns {Function} A function that returns an array of
* states in all the metric in the dashboard or group.
*/
export const getMetricStates = (state) => (groupKey) => {
let groups = state.dashboard.panelGroups;
if (groupKey) {
groups = groups.filter((group) => group.key === groupKey);
}
const metricStates = groups.reduce((acc, group) => {
group.panels.forEach((panel) => {
panel.metrics.forEach((metric) => {
if (metric.state) {
acc.push(metric.state);
}
});
});
return acc;
}, []);
// Deduplicate and sort array
return Array.from(new Set(metricStates)).sort();
};
/**
* Getter to obtain the list of metric ids that have data
*
* Useful to understand which parts of the dashboard should
* be displayed. It is a Vuex Method-Style Access getter.
*
* @param {Object} state
* @returns {Function} A function that returns an array of
* metrics in the dashboard that contain results, optionally
* filtered by group key.
*/
export const metricsWithData = (state) => (groupKey) => {
let groups = state.dashboard.panelGroups;
if (groupKey) {
groups = groups.filter((group) => group.key === groupKey);
}
const res = [];
groups.forEach((group) => {
group.panels.forEach((panel) => {
res.push(...metricsIdsInPanel(panel));
});
});
return res;
};
/**
* Metrics loaded from project-defined dashboards do not have a metric_id.
* This getter checks which metrics are stored in the db (have a metric id)
* This is hopefully a temporary solution until BE processes metrics before passing to FE
*
* Related:
* https://gitlab.com/gitlab-org/gitlab/-/issues/28241
* https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27447
*/
export const metricsSavedToDb = (state) => {
const metricIds = [];
state.dashboard.panelGroups.forEach(({ panels }) => {
panels.forEach(({ metrics }) => {
const metricIdsInDb = metrics
.filter(({ metricId }) => !metricId.startsWith(NOT_IN_DB_PREFIX))
.map(({ metricId }) => metricId);
metricIds.push(...metricIdsInDb);
});
});
return metricIds;
};
/**
* Filter environments by names.
*
* This is used in the environments dropdown with searchable input.
*
* @param {Object} state
* @returns {Array} List of environments
*/
export const filteredEnvironments = (state) =>
state.environments.filter((env) =>
env.name.toLowerCase().includes((state.environmentsSearchTerm || '').trim().toLowerCase()),
);
/**
* User-defined links from the yml file can have other
* dashboard-related metadata baked into it. This method
* returns modified links which will get rendered in the
* metrics dashboard
*
* @param {Object} state
* @returns {Array} modified array of links
*/
export const linksWithMetadata = (state) => {
const metadata = {
timeRange: state.timeRange,
};
return state.links?.map(addDashboardMetaDataToLink(metadata));
};
/**
* Maps a variables array to an object for replacement in
* prometheus queries.
*
* This method outputs an object in the below format
*
* {
* variables[key1]=value1,
* variables[key2]=value2,
* }
*
* This is done so that the backend can identify the custom
* user-defined variables coming through the URL and differentiate
* from other variables used for Prometheus API endpoint.
*
* @param {Object} state - State containing variables provided by the user
* @returns {Array} The custom variables object to be send to the API
* in the format of {variables[key1]=value1, variables[key2]=value2}
*/
export const getCustomVariablesParams = (state) =>
state.variables.reduce((acc, variable) => {
const { name, value } = variable;
if (value !== null) {
acc[addPrefixToCustomVariableParams(name)] = value;
}
return acc;
}, {});
/**
* For a given custom dashboard file name, this method
* returns the full file path.
*
* @param {Object} state
* @returns {String} full dashboard path
*/
export const fullDashboardPath = (state) =>
normalizeCustomDashboardPath(state.currentDashboard, state.customDashboardBasePath);