fix: table column names with attribute and legend (#3142)

Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
This commit is contained in:
Yevhen Shevchenko 2023-07-17 15:46:41 +03:00 committed by GitHub
parent c68b611ad9
commit 6efa1011aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -4,8 +4,13 @@ import { FORMULA_REGEXP } from 'constants/regExp';
import { QueryTableProps } from 'container/QueryTable/QueryTable.intefaces'; import { QueryTableProps } from 'container/QueryTable/QueryTable.intefaces';
import { toCapitalize } from 'lib/toCapitalize'; import { toCapitalize } from 'lib/toCapitalize';
import { ReactNode } from 'react'; import { ReactNode } from 'react';
import { IBuilderQuery, Query } from 'types/api/queryBuilder/queryBuilderData'; import {
IBuilderFormula,
IBuilderQuery,
Query,
} from 'types/api/queryBuilder/queryBuilderData';
import { ListItem, QueryDataV3, SeriesItem } from 'types/api/widgets/getQuery'; import { ListItem, QueryDataV3, SeriesItem } from 'types/api/widgets/getQuery';
import { QueryBuilderData } from 'types/common/queryBuilder';
import { v4 as uuid } from 'uuid'; import { v4 as uuid } from 'uuid';
type CreateTableDataFromQueryParams = Pick< type CreateTableDataFromQueryParams = Pick<
@ -21,8 +26,10 @@ export type RowData = {
type DynamicColumn = { type DynamicColumn = {
key: keyof RowData; key: keyof RowData;
title: string;
sourceLabel: string;
data: (string | number)[]; data: (string | number)[];
type: 'field' | 'operator'; type: 'field' | 'operator' | 'formula';
// sortable: boolean; // sortable: boolean;
}; };
@ -39,7 +46,6 @@ type CreateTableDataFromQuery = (
type FillColumnData = ( type FillColumnData = (
queryTableData: QueryDataV3[], queryTableData: QueryDataV3[],
dynamicColumns: DynamicColumns, dynamicColumns: DynamicColumns,
query: Query,
) => { filledDynamicColumns: DynamicColumns; rowsLength: number }; ) => { filledDynamicColumns: DynamicColumns; rowsLength: number };
type GetDynamicColumns = ( type GetDynamicColumns = (
@ -54,43 +60,37 @@ type SeriesItemLabels = SeriesItem['labels'];
const isFormula = (queryName: string): boolean => const isFormula = (queryName: string): boolean =>
FORMULA_REGEXP.test(queryName); FORMULA_REGEXP.test(queryName);
const isColumnExist = ( const isValueExist = (
columnName: string, field: keyof DynamicColumn,
value: string,
columns: DynamicColumns, columns: DynamicColumns,
): boolean => { ): boolean => {
const columnKeys = columns.map((item) => item.key); const existColumns = columns.find((item) => item[field] === value);
return columnKeys.includes(columnName); return !!existColumns;
}; };
const prepareColumnTitle = (title: string): string => { const getQueryByName = <T extends keyof QueryBuilderData>(
const haveUnderscore = title.includes('_'); builder: QueryBuilderData,
if (haveUnderscore) {
return title
.split('_')
.map((str) => toCapitalize(str))
.join(' ');
}
return toCapitalize(title);
};
const getQueryOperator = (
queryData: IBuilderQuery[],
currentQueryName: string, currentQueryName: string,
): string => { type: T,
const builderQuery = queryData.find((q) => q.queryName === currentQueryName); ): (T extends 'queryData' ? IBuilderQuery : IBuilderFormula) | null => {
const queryArray = builder[type];
return builderQuery ? builderQuery.aggregateOperator : ''; const currentQuery =
queryArray.find((q) => q.queryName === currentQueryName) || null;
if (!currentQuery) return null;
return currentQuery as T extends 'queryData' ? IBuilderQuery : IBuilderFormula;
}; };
const createLabels = <T extends ListItemData | SeriesItemLabels>( const createLabels = <T extends ListItemData | SeriesItemLabels>(
labels: T, // labels: T,
label: keyof T, label: keyof T,
dynamicColumns: DynamicColumns, dynamicColumns: DynamicColumns,
): void => { ): void => {
if (isColumnExist(label as string, dynamicColumns)) return; if (isValueExist('key', label as string, dynamicColumns)) return;
// const labelValue = labels[label]; // const labelValue = labels[label];
@ -98,6 +98,8 @@ const createLabels = <T extends ListItemData | SeriesItemLabels>(
const fieldObj: DynamicColumn = { const fieldObj: DynamicColumn = {
key: label as string, key: label as string,
title: label as string,
sourceLabel: label as string,
data: [], data: [],
type: 'field', type: 'field',
// sortable: isNumber, // sortable: isNumber,
@ -106,6 +108,68 @@ const createLabels = <T extends ListItemData | SeriesItemLabels>(
dynamicColumns.push(fieldObj); dynamicColumns.push(fieldObj);
}; };
const appendOperatorFormulaColumns = (
builder: QueryBuilderData,
currentQueryName: string,
dynamicColumns: DynamicColumns,
): void => {
const currentFormula = getQueryByName(
builder,
currentQueryName,
'queryFormulas',
);
if (currentFormula) {
let formulaLabel = `${currentFormula.queryName}(${currentFormula.expression})`;
if (currentFormula.legend) {
formulaLabel += ` - ${currentFormula.legend}`;
}
const formulaColumn: DynamicColumn = {
key: currentQueryName,
title: formulaLabel,
sourceLabel: formulaLabel,
data: [],
type: 'formula',
// sortable: isNumber,
};
dynamicColumns.push(formulaColumn);
}
const currentQueryData = getQueryByName(
builder,
currentQueryName,
'queryData',
);
if (!currentQueryData) return;
let operatorLabel = `${currentQueryData.aggregateOperator}`;
if (currentQueryData.aggregateAttribute.key) {
operatorLabel += `(${currentQueryData.aggregateAttribute.key})`;
}
if (currentQueryData.legend) {
operatorLabel += ` - ${currentQueryData.legend}`;
} else {
operatorLabel += ` - ${currentQueryData.queryName}`;
}
const resultValue = `${toCapitalize(operatorLabel)}`;
const operatorColumn: DynamicColumn = {
key: currentQueryName,
title: resultValue,
sourceLabel: resultValue,
data: [],
type: 'operator',
// sortable: isNumber,
};
dynamicColumns.push(operatorColumn);
};
const getDynamicColumns: GetDynamicColumns = (queryTableData, query) => { const getDynamicColumns: GetDynamicColumns = (queryTableData, query) => {
const dynamicColumns: DynamicColumns = []; const dynamicColumns: DynamicColumns = [];
@ -113,49 +177,52 @@ const getDynamicColumns: GetDynamicColumns = (queryTableData, query) => {
if (currentQuery.list) { if (currentQuery.list) {
currentQuery.list.forEach((listItem) => { currentQuery.list.forEach((listItem) => {
Object.keys(listItem.data).forEach((label) => { Object.keys(listItem.data).forEach((label) => {
createLabels<ListItemData>( createLabels<ListItemData>(label as ListItemKey, dynamicColumns);
listItem.data,
label as ListItemKey,
dynamicColumns,
);
}); });
}); });
} }
if (currentQuery.series) { if (currentQuery.series) {
if (!isColumnExist('timestamp', dynamicColumns)) { if (!isValueExist('key', 'timestamp', dynamicColumns)) {
dynamicColumns.push({ dynamicColumns.push({
key: 'timestamp', key: 'timestamp',
title: 'Timestamp',
sourceLabel: 'Timestamp',
data: [], data: [],
type: 'field', type: 'field',
// sortable: true, // sortable: true,
}); });
} }
currentQuery.series.forEach((seria) => { appendOperatorFormulaColumns(
Object.keys(seria.labels).forEach((label) => { query.builder,
createLabels<SeriesItemLabels>(seria.labels, label, dynamicColumns);
});
});
const operator = getQueryOperator(
query.builder.queryData,
currentQuery.queryName, currentQuery.queryName,
dynamicColumns,
); );
if (operator === '' || isColumnExist(operator, dynamicColumns)) return; currentQuery.series.forEach((seria) => {
Object.keys(seria.labels).forEach((label) => {
const operatorColumn: DynamicColumn = { createLabels<SeriesItemLabels>(label, dynamicColumns);
key: operator, });
data: [], });
type: 'operator',
// sortable: true,
};
dynamicColumns.push(operatorColumn);
} }
}); });
return dynamicColumns; return dynamicColumns.map((item) => {
if (isFormula(item.key as string)) {
return item;
}
const sameValues = dynamicColumns.filter(
(column) => column.sourceLabel === item.sourceLabel,
);
if (sameValues.length > 1) {
return { ...item, title: `${item.title} - ${item.key}` };
}
return item;
});
}; };
const fillEmptyRowCells = ( const fillEmptyRowCells = (
@ -179,7 +246,6 @@ const fillDataFromSeria = (
seria: SeriesItem, seria: SeriesItem,
columns: DynamicColumns, columns: DynamicColumns,
queryName: string, queryName: string,
operator: string,
): void => { ): void => {
const labelEntries = Object.entries(seria.labels); const labelEntries = Object.entries(seria.labels);
@ -195,13 +261,7 @@ const fillDataFromSeria = (
return; return;
} }
if (isFormula(queryName) && queryName === column.key) { if (queryName === column.key) {
column.data.push(parseFloat(value.value).toFixed(2));
unusedColumnsKeys.delete(column.key);
return;
}
if (!isFormula(queryName) && operator === column.key) {
column.data.push(parseFloat(value.value).toFixed(2)); column.data.push(parseFloat(value.value).toFixed(2));
unusedColumnsKeys.delete(column.key); unusedColumnsKeys.delete(column.key);
return; return;
@ -238,25 +298,16 @@ const fillDataFromList = (
}); });
}; };
const fillColumnsData: FillColumnData = (queryTableData, cols, query) => { const fillColumnsData: FillColumnData = (queryTableData, cols) => {
const fields = cols.filter((item) => item.type === 'field'); const fields = cols.filter((item) => item.type === 'field');
const operators = cols.filter((item) => item.type === 'operator'); const operators = cols.filter((item) => item.type === 'operator');
const resultColumns = [...fields, ...operators]; const formulas = cols.filter((item) => item.type === 'formula');
const resultColumns = [...fields, ...operators, ...formulas];
queryTableData.forEach((currentQuery) => { queryTableData.forEach((currentQuery) => {
if (currentQuery.series) { if (currentQuery.series) {
currentQuery.series.forEach((seria) => { currentQuery.series.forEach((seria) => {
const currentOperator = getQueryOperator( fillDataFromSeria(seria, resultColumns, currentQuery.queryName);
query.builder.queryData,
currentQuery.queryName,
);
fillDataFromSeria(
seria,
resultColumns,
currentQuery.queryName,
currentOperator,
);
}); });
} }
@ -303,7 +354,7 @@ const generateTableColumns = (
const column: ColumnType<RowData> = { const column: ColumnType<RowData> = {
dataIndex: item.key, dataIndex: item.key,
key: item.key, key: item.key,
title: prepareColumnTitle(item.key as string), title: item.title,
// sorter: item.sortable // sorter: item.sortable
// ? (a: RowData, b: RowData): number => // ? (a: RowData, b: RowData): number =>
// (a[item.key] as number) - (b[item.key] as number) // (a[item.key] as number) - (b[item.key] as number)
@ -326,7 +377,6 @@ export const createTableColumnsFromQuery: CreateTableDataFromQuery = ({
const { filledDynamicColumns, rowsLength } = fillColumnsData( const { filledDynamicColumns, rowsLength } = fillColumnsData(
queryTableData, queryTableData,
dynamicColumns, dynamicColumns,
query,
); );
const dataSource = generateData(filledDynamicColumns, rowsLength); const dataSource = generateData(filledDynamicColumns, rowsLength);