fix: column name with legend (#3200)

* fix: column name with legend

* fix: render columns with data

* fix: index

* fix: render rows

* fix: remove log

* fix: return operators for entiry metric

* fix: remove noop and rate for table metric

* fix: for request

* chore: allow count attribute to be empty

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
This commit is contained in:
Yevhen Shevchenko 2023-07-28 18:44:46 +03:00 committed by GitHub
parent a2c03243cb
commit 5469cd34fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 130 additions and 64 deletions

View File

@ -125,7 +125,7 @@ export const initialFilters: TagFilter = {
export const initialQueryBuilderFormValues: IBuilderQuery = {
dataSource: DataSource.METRICS,
queryName: createNewBuilderItemName({ existNames: [], sourceNames: alphabet }),
aggregateOperator: MetricAggregateOperator.NOOP,
aggregateOperator: MetricAggregateOperator.COUNT,
aggregateAttribute: initialAutocompleteData,
filters: { items: [], op: 'AND' },
expression: createNewBuilderItemName({

View File

@ -1,5 +1,9 @@
import { mapOfOperators, PANEL_TYPES } from 'constants/queryBuilder';
import { DataSource, StringOperators } from 'types/common/queryBuilder';
import {
DataSource,
MetricAggregateOperator,
StringOperators,
} from 'types/common/queryBuilder';
import { SelectOption } from 'types/common/select';
type GetQueryOperatorsParams = {
@ -19,6 +23,13 @@ export const getOperatorsBySourceAndPanelType = ({
(operator) => operator.value === StringOperators.NOOP,
);
}
if (panelType === PANEL_TYPES.TABLE && dataSource === DataSource.METRICS) {
operatorsByDataSource = operatorsByDataSource.filter(
(operator) =>
operator.value !== MetricAggregateOperator.NOOP &&
operator.value !== MetricAggregateOperator.RATE,
);
}
if (
dataSource !== DataSource.METRICS &&
panelType !== PANEL_TYPES.LIST &&

View File

@ -6,7 +6,6 @@ import {
} from 'constants/queryBuilder';
import { FORMULA_REGEXP } from 'constants/regExp';
import { QueryTableProps } from 'container/QueryTable/QueryTable.intefaces';
import { toCapitalize } from 'lib/toCapitalize';
import { ReactNode } from 'react';
import {
IBuilderFormula,
@ -145,7 +144,7 @@ const addOperatorFormulaColumns = (
let formulaLabel = `${formulaQuery.queryName}(${formulaQuery.expression})`;
if (formulaQuery.legend) {
formulaLabel += ` - ${formulaQuery.legend}`;
formulaLabel = formulaQuery.legend;
}
const formulaColumn: DynamicColumn = {
@ -171,18 +170,14 @@ const addOperatorFormulaColumns = (
}
if (currentQueryData.legend) {
operatorLabel += ` - ${currentQueryData.legend}`;
} else {
operatorLabel += ` - ${currentQueryData.queryName}`;
operatorLabel = currentQueryData.legend;
}
const resultValue = `${toCapitalize(operatorLabel)}`;
const operatorColumn: DynamicColumn = {
query,
field: currentQueryData.queryName,
dataIndex: currentQueryData.queryName,
title: customLabel || resultValue,
title: customLabel || operatorLabel,
data: [],
type: 'operator',
// sortable: isNumber,
@ -218,26 +213,24 @@ const getDynamicColumns: GetDynamicColumns = (queryTableData, query) => {
const dynamicColumns: DynamicColumns = [];
queryTableData.forEach((currentQuery) => {
const { series, queryName, list } = currentQuery;
const currentStagedQuery = getQueryByName(
query.builder,
currentQuery.queryName,
isFormula(currentQuery.queryName) ? 'queryFormulas' : 'queryData',
queryName,
isFormula(queryName) ? 'queryFormulas' : 'queryData',
);
if (currentQuery.list) {
currentQuery.list.forEach((listItem) => {
if (list) {
list.forEach((listItem) => {
Object.keys(listItem.data).forEach((label) => {
addListLabels(currentStagedQuery, label as ListItemKey, dynamicColumns);
});
});
}
if (currentQuery.series) {
const isValuesColumnExist = currentQuery.series.some(
(item) => item.values.length > 0,
);
const isEveryValuesExist = currentQuery.series.every(
(item) => item.values.length > 0,
);
if (series) {
const isValuesColumnExist = series.some((item) => item.values.length > 0);
const isEveryValuesExist = series.every((item) => item.values.length > 0);
if (isValuesColumnExist) {
addOperatorFormulaColumns(
@ -247,7 +240,7 @@ const getDynamicColumns: GetDynamicColumns = (queryTableData, query) => {
);
}
currentQuery.series.forEach((seria) => {
series.forEach((seria) => {
Object.keys(seria.labels).forEach((label) => {
if (label === currentQuery?.queryName) return;
@ -277,12 +270,54 @@ const fillEmptyRowCells = (
});
};
const fillData = (
seria: SeriesItem,
columns: DynamicColumns,
const findSeriaValueFromAnotherQuery = (
currentLabels: Record<string, string>,
nextQuery: QueryDataV3 | null,
): SeriesItem | null => {
if (!nextQuery || !nextQuery.series) return null;
let value = null;
const labelEntries = Object.entries(currentLabels);
nextQuery.series.forEach((seria) => {
const localLabelEntries = Object.entries(seria.labels);
if (localLabelEntries.length !== labelEntries.length) return;
const isExistLabels = localLabelEntries.find(([key, value]) =>
labelEntries.find(
([currentKey, currentValue]) =>
currentKey === key && currentValue === value,
),
);
if (isExistLabels) {
value = seria;
}
});
return value;
};
const isEqualQueriesByLabel = (
equalQueries: string[],
queryName: string,
value?: SeriesItem['values'][number],
): boolean => equalQueries.includes(queryName);
const fillDataFromSeries = (
currentQuery: QueryDataV3,
queryTableData: QueryDataV3[],
columns: DynamicColumns,
equalQueriesByLabels: string[],
// TODO: fix it
// eslint-disable-next-line sonarjs/cognitive-complexity
): void => {
const { series, queryName } = currentQuery;
const isEqualQuery = isEqualQueriesByLabel(equalQueriesByLabels, queryName);
if (!series) return;
series.forEach((seria) => {
const labelEntries = Object.entries(seria.labels);
const unusedColumnsKeys = new Set<keyof RowData>(
@ -290,12 +325,41 @@ const fillData = (
);
columns.forEach((column) => {
if (queryName === column.field && value) {
column.data.push(parseFloat(value.value).toFixed(2));
if (queryName === column.field) {
if (seria.values.length === 0) return;
column.data.push(parseFloat(seria.values[0].value).toFixed(2));
unusedColumnsKeys.delete(column.field);
return;
}
if (column.type !== 'field' && column.field !== queryName) {
const nextQueryData =
queryTableData.find((q) => q.queryName === column.field) || null;
const targetSeria = findSeriaValueFromAnotherQuery(
seria.labels,
nextQueryData,
);
if (targetSeria) {
const isEqual = isEqualQueriesByLabel(equalQueriesByLabels, column.field);
if (!isEqual) {
equalQueriesByLabels.push(column.field);
}
column.data.push(parseFloat(targetSeria.values[0].value).toFixed(2));
} else {
column.data.push('N/A');
}
unusedColumnsKeys.delete(column.field);
return;
}
if (isEqualQuery) return;
labelEntries.forEach(([key, currentValue]) => {
if (column.field === key) {
column.data.push(currentValue);
@ -305,21 +369,6 @@ const fillData = (
fillEmptyRowCells(unusedColumnsKeys, columns, column);
});
};
const fillDataFromSeria = (
seria: SeriesItem,
columns: DynamicColumns,
queryName: string,
): void => {
if (seria.values.length === 0) {
fillData(seria, columns, queryName);
return;
}
seria.values.forEach((value) => {
fillData(seria, columns, queryName, value);
});
};
@ -348,15 +397,20 @@ const fillColumnsData: FillColumnData = (queryTableData, cols) => {
const formulas = cols.filter((item) => item.type === 'formula');
const resultColumns = [...fields, ...operators, ...formulas];
queryTableData.forEach((currentQuery) => {
if (currentQuery.series) {
currentQuery.series.forEach((seria) => {
fillDataFromSeria(seria, resultColumns, currentQuery.queryName);
});
}
const equalQueriesByLabels: string[] = [];
if (currentQuery.list) {
currentQuery.list.forEach((listItem) => {
queryTableData.forEach((currentQuery) => {
const { list } = currentQuery;
fillDataFromSeries(
currentQuery,
queryTableData,
resultColumns,
equalQueriesByLabels,
);
if (list) {
list.forEach((listItem) => {
fillDataFromList(listItem, resultColumns);
});
}

View File

@ -107,7 +107,8 @@ func (a AggregateOperator) RequireAttribute(dataSource DataSource) bool {
switch dataSource {
case DataSourceMetrics:
switch a {
case AggregateOperatorNoOp:
case AggregateOperatorNoOp,
AggregateOperatorCount:
return false
default:
return true