mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-08 16:18:59 +08:00
[Refactor]: Added tag and datatype in options for query builder (#3555)
Co-authored-by: Vishal Sharma <makeavish786@gmail.com> Co-authored-by: Palash Gupta <palashgdev@gmail.com>
This commit is contained in:
parent
581bd07b35
commit
6b2f03d43f
@ -25,7 +25,9 @@ import { ExtendedSelectOption } from 'types/common/select';
|
||||
import { popupContainer } from 'utils/selectPopupContainer';
|
||||
import { transformToUpperCase } from 'utils/transformToUpperCase';
|
||||
|
||||
import { removePrefix } from '../GroupByFilter/utils';
|
||||
import { selectStyle } from '../QueryBuilderSearch/config';
|
||||
import OptionRenderer from '../QueryBuilderSearch/OptionRenderer';
|
||||
// ** Types
|
||||
import { AgregatorFilterProps } from './AggregatorFilter.intefaces';
|
||||
|
||||
@ -64,11 +66,23 @@ export const AggregatorFilter = memo(function AggregatorFilter({
|
||||
onSuccess: (data) => {
|
||||
const options: ExtendedSelectOption[] =
|
||||
data?.payload?.attributeKeys?.map(({ id: _, ...item }) => ({
|
||||
label: transformStringWithPrefix({
|
||||
label: (
|
||||
<OptionRenderer
|
||||
label={transformStringWithPrefix({
|
||||
str: item.key,
|
||||
prefix: item.type || '',
|
||||
condition: !item.isColumn,
|
||||
})}
|
||||
value={removePrefix(
|
||||
transformStringWithPrefix({
|
||||
str: item.key,
|
||||
prefix: item.type || '',
|
||||
condition: !item.isColumn,
|
||||
}),
|
||||
)}
|
||||
dataType={item.dataType}
|
||||
/>
|
||||
),
|
||||
value: `${item.key}${selectValueDivider}${createIdFromObjectFields(
|
||||
item,
|
||||
baseAutoCompleteIdKeysOrder,
|
||||
@ -165,18 +179,19 @@ export const AggregatorFilter = memo(function AggregatorFilter({
|
||||
[getAttributesData, handleChangeCustomValue, onChange],
|
||||
);
|
||||
|
||||
const value = transformStringWithPrefix({
|
||||
const value = removePrefix(
|
||||
transformStringWithPrefix({
|
||||
str: query.aggregateAttribute.key,
|
||||
prefix: query.aggregateAttribute.type || '',
|
||||
condition: !query.aggregateAttribute.isColumn,
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
return (
|
||||
<AutoComplete
|
||||
getPopupContainer={popupContainer}
|
||||
placeholder={placeholder}
|
||||
style={selectStyle}
|
||||
showArrow={false}
|
||||
filterOption={false}
|
||||
onSearch={handleSearchText}
|
||||
notFoundContent={isFetching ? <Spin size="small" /> : null}
|
||||
|
@ -14,14 +14,16 @@ import { chooseAutocompleteFromCustomValue } from 'lib/newQueryBuilder/chooseAut
|
||||
// ** Helpers
|
||||
import { transformStringWithPrefix } from 'lib/query/transformStringWithPrefix';
|
||||
import { isEqual, uniqWith } from 'lodash-es';
|
||||
import { memo, useCallback, useEffect, useState } from 'react';
|
||||
import { memo, ReactNode, useCallback, useEffect, useState } from 'react';
|
||||
import { useQueryClient } from 'react-query';
|
||||
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import { SelectOption } from 'types/common/select';
|
||||
import { popupContainer } from 'utils/selectPopupContainer';
|
||||
|
||||
import { selectStyle } from '../QueryBuilderSearch/config';
|
||||
import OptionRenderer from '../QueryBuilderSearch/OptionRenderer';
|
||||
import { GroupByFilterProps } from './GroupByFilter.interfaces';
|
||||
import { removePrefix } from './utils';
|
||||
|
||||
export const GroupByFilter = memo(function GroupByFilter({
|
||||
query,
|
||||
@ -30,9 +32,9 @@ export const GroupByFilter = memo(function GroupByFilter({
|
||||
}: GroupByFilterProps): JSX.Element {
|
||||
const queryClient = useQueryClient();
|
||||
const [searchText, setSearchText] = useState<string>('');
|
||||
const [optionsData, setOptionsData] = useState<SelectOption<string, string>[]>(
|
||||
[],
|
||||
);
|
||||
const [optionsData, setOptionsData] = useState<
|
||||
SelectOption<string, ReactNode>[]
|
||||
>([]);
|
||||
const [localValues, setLocalValues] = useState<SelectOption<string, string>[]>(
|
||||
[],
|
||||
);
|
||||
@ -61,13 +63,26 @@ export const GroupByFilter = memo(function GroupByFilter({
|
||||
(attrKey) => !keys.includes(attrKey.key),
|
||||
) || [];
|
||||
|
||||
const options: SelectOption<string, string>[] =
|
||||
const options: SelectOption<string, ReactNode>[] =
|
||||
filteredOptions.map((item) => ({
|
||||
label: transformStringWithPrefix({
|
||||
label: (
|
||||
<OptionRenderer
|
||||
key={item.key}
|
||||
label={transformStringWithPrefix({
|
||||
str: item.key,
|
||||
prefix: item.type || '',
|
||||
condition: !item.isColumn,
|
||||
})}
|
||||
value={removePrefix(
|
||||
transformStringWithPrefix({
|
||||
str: item.key,
|
||||
prefix: item.type || '',
|
||||
condition: !item.isColumn,
|
||||
}),
|
||||
)}
|
||||
dataType={item.dataType || ''}
|
||||
/>
|
||||
),
|
||||
value: `${transformStringWithPrefix({
|
||||
str: item.key,
|
||||
prefix: item.type || '',
|
||||
@ -152,11 +167,13 @@ export const GroupByFilter = memo(function GroupByFilter({
|
||||
useEffect(() => {
|
||||
const currentValues: SelectOption<string, string>[] = query.groupBy.map(
|
||||
(item) => ({
|
||||
label: `${transformStringWithPrefix({
|
||||
label: `${removePrefix(
|
||||
transformStringWithPrefix({
|
||||
str: item.key,
|
||||
prefix: item.type || '',
|
||||
condition: !item.isColumn,
|
||||
})}`,
|
||||
}),
|
||||
)}`,
|
||||
value: `${transformStringWithPrefix({
|
||||
str: item.key,
|
||||
prefix: item.type || '',
|
||||
@ -176,7 +193,6 @@ export const GroupByFilter = memo(function GroupByFilter({
|
||||
onSearch={handleSearchKeys}
|
||||
showSearch
|
||||
disabled={disabled}
|
||||
showArrow={false}
|
||||
filterOption={false}
|
||||
onBlur={handleBlur}
|
||||
onFocus={handleFocus}
|
||||
|
@ -0,0 +1,14 @@
|
||||
import { MetricsType } from 'container/MetricsApplication/constant';
|
||||
|
||||
export function removePrefix(str: string): string {
|
||||
const tagPrefix = `${MetricsType.Tag}_`;
|
||||
const resourcePrefix = `${MetricsType.Resource}_`;
|
||||
|
||||
if (str.startsWith(tagPrefix)) {
|
||||
return str.slice(tagPrefix.length);
|
||||
}
|
||||
if (str.startsWith(resourcePrefix)) {
|
||||
return str.slice(resourcePrefix.length);
|
||||
}
|
||||
return str;
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
import {
|
||||
SelectOptionContainer,
|
||||
TagContainer,
|
||||
TagLabel,
|
||||
TagValue,
|
||||
} from './style';
|
||||
import { getOptionType } from './utils';
|
||||
|
||||
function OptionRenderer({
|
||||
label,
|
||||
value,
|
||||
dataType,
|
||||
}: OptionRendererProps): JSX.Element {
|
||||
const optionType = getOptionType(label);
|
||||
|
||||
return (
|
||||
<span>
|
||||
{optionType ? (
|
||||
<SelectOptionContainer>
|
||||
<div>{value}</div>
|
||||
<div>
|
||||
<TagContainer>
|
||||
<TagLabel>Type: </TagLabel>
|
||||
<TagValue>{optionType}</TagValue>
|
||||
</TagContainer>
|
||||
<TagContainer>
|
||||
<TagLabel>Data type: </TagLabel>
|
||||
<TagValue>{dataType}</TagValue>
|
||||
</TagContainer>
|
||||
</div>
|
||||
</SelectOptionContainer>
|
||||
) : (
|
||||
<span>{label}</span>
|
||||
)}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
interface OptionRendererProps {
|
||||
label: string;
|
||||
value: string;
|
||||
dataType: string;
|
||||
}
|
||||
|
||||
export default OptionRenderer;
|
@ -28,6 +28,7 @@ import { v4 as uuid } from 'uuid';
|
||||
|
||||
import { selectStyle } from './config';
|
||||
import { PLACEHOLDER } from './constant';
|
||||
import OptionRenderer from './OptionRenderer';
|
||||
import { StyledCheckOutlined, TypographyText } from './style';
|
||||
import {
|
||||
getOperatorValue,
|
||||
@ -205,7 +206,11 @@ function QueryBuilderSearch({
|
||||
>
|
||||
{options.map((option) => (
|
||||
<Select.Option key={option.label} value={option.value}>
|
||||
{option.label}
|
||||
<OptionRenderer
|
||||
label={option.label}
|
||||
value={option.value}
|
||||
dataType={option.dataType || ''}
|
||||
/>
|
||||
{option.selected && <StyledCheckOutlined />}
|
||||
</Select.Option>
|
||||
))}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { CheckOutlined } from '@ant-design/icons';
|
||||
import { Typography } from 'antd';
|
||||
import { Tag, Typography } from 'antd';
|
||||
import styled from 'styled-components';
|
||||
|
||||
export const TypographyText = styled(Typography.Text)<{
|
||||
@ -15,3 +15,27 @@ export const TypographyText = styled(Typography.Text)<{
|
||||
export const StyledCheckOutlined = styled(CheckOutlined)`
|
||||
float: right;
|
||||
`;
|
||||
|
||||
export const SelectOptionContainer = styled.div`
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
`;
|
||||
|
||||
export const TagContainer = styled(Tag)`
|
||||
&&& {
|
||||
border-radius: 0.25rem;
|
||||
padding: 0.063rem 0.5rem;
|
||||
font-weight: 600;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.25rem;
|
||||
}
|
||||
`;
|
||||
|
||||
export const TagLabel = styled.span`
|
||||
font-weight: 400;
|
||||
`;
|
||||
|
||||
export const TagValue = styled.span`
|
||||
text-transform: capitalize;
|
||||
`;
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { OPERATORS } from 'constants/queryBuilder';
|
||||
import { MetricsType } from 'container/MetricsApplication/constant';
|
||||
import { parse } from 'papaparse';
|
||||
|
||||
import { orderByValueDelimiter } from '../OrderByFilter/utils';
|
||||
@ -140,3 +141,15 @@ export function getRemoveOrderFromValue(tag: string): string {
|
||||
}
|
||||
return tag;
|
||||
}
|
||||
|
||||
export function getOptionType(label: string): MetricsType | undefined {
|
||||
let optionType;
|
||||
|
||||
if (label.startsWith('tag_')) {
|
||||
optionType = MetricsType.Tag;
|
||||
} else if (label.startsWith('resource_')) {
|
||||
optionType = MetricsType.Resource;
|
||||
}
|
||||
|
||||
return optionType;
|
||||
}
|
||||
|
@ -14,4 +14,5 @@ export type Option = {
|
||||
value: string;
|
||||
label: string;
|
||||
selected?: boolean;
|
||||
dataType?: string;
|
||||
};
|
||||
|
@ -43,6 +43,7 @@ export const useOptions = (
|
||||
items?.map((item) => ({
|
||||
label: `${getLabel(item)}`,
|
||||
value: item.key,
|
||||
dataType: item.dataType,
|
||||
})),
|
||||
[getLabel],
|
||||
);
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
export type SelectOption<Value, Label extends unknown = string> = {
|
||||
value: Value;
|
||||
label: Label;
|
||||
@ -6,7 +8,7 @@ export type SelectOption<Value, Label extends unknown = string> = {
|
||||
export type ExtendedSelectOption = {
|
||||
disabled?: boolean;
|
||||
key: string;
|
||||
label: string;
|
||||
label: ReactNode;
|
||||
title?: string;
|
||||
value: string;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user