feat: update qb elements based on panel type

This commit is contained in:
Yunus M 2025-06-07 12:45:01 +05:30 committed by SagarRajput-7
parent e9bed072e4
commit 35c49c45da
5 changed files with 143 additions and 63 deletions

View File

@ -68,7 +68,6 @@ export const QueryBuilderV2 = memo(function QueryBuilderV2({
queryComponents={queryComponents} queryComponents={queryComponents}
version={version} version={version}
isAvailableToDisable={false} isAvailableToDisable={false}
showSpanScopeSelector={initialDataSource === DataSource.TRACES}
queryVariant={config?.queryVariant || 'dropdown'} queryVariant={config?.queryVariant || 'dropdown'}
showOnlyWhereClause={showOnlyWhereClause} showOnlyWhereClause={showOnlyWhereClause}
/> />

View File

@ -7,20 +7,20 @@ import SpaceAggregationOptions from 'container/QueryBuilder/components/SpaceAggr
import { GroupByFilter, OperatorsSelect } from 'container/QueryBuilder/filters'; import { GroupByFilter, OperatorsSelect } from 'container/QueryBuilder/filters';
import { useQueryOperations } from 'hooks/queryBuilder/useQueryBuilderOperations'; import { useQueryOperations } from 'hooks/queryBuilder/useQueryBuilderOperations';
import { Info } from 'lucide-react'; import { Info } from 'lucide-react';
import { memo, useCallback } from 'react'; import { memo, useCallback, useMemo } from 'react';
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData'; import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
const MetricsAggregateSection = memo(function MetricsAggregateSection({ const MetricsAggregateSection = memo(function MetricsAggregateSection({
query, query,
index, index,
version, version,
panelType,
}: { }: {
query: IBuilderQuery; query: IBuilderQuery;
index: number; index: number;
version: string; version: string;
panelType: PANEL_TYPES | null;
}): JSX.Element { }): JSX.Element {
const panelType = PANEL_TYPES.LIST; // hardcoded for now
const { const {
operators, operators,
spaceAggregationOptions, spaceAggregationOptions,
@ -33,8 +33,6 @@ const MetricsAggregateSection = memo(function MetricsAggregateSection({
entityVersion: version, entityVersion: version,
}); });
// console.log('operators', cloneDeep(operators));
const handleChangeGroupByKeys = useCallback( const handleChangeGroupByKeys = useCallback(
(value: IBuilderQuery['groupBy']) => { (value: IBuilderQuery['groupBy']) => {
handleChangeQueryData('groupBy', value); handleChangeQueryData('groupBy', value);
@ -42,6 +40,15 @@ const MetricsAggregateSection = memo(function MetricsAggregateSection({
[handleChangeQueryData], [handleChangeQueryData],
); );
const showAggregationInterval = useMemo(() => {
// eslint-disable-next-line sonarjs/prefer-single-boolean-return
if (panelType === PANEL_TYPES.VALUE) {
return false;
}
return true;
}, [panelType]);
const disableOperatorSelector = const disableOperatorSelector =
!query?.aggregateAttribute.key || query?.aggregateAttribute.key === ''; !query?.aggregateAttribute.key || query?.aggregateAttribute.key === '';
@ -71,19 +78,21 @@ const MetricsAggregateSection = memo(function MetricsAggregateSection({
</div> </div>
</div> </div>
<div className="metrics-aggregation-section-content-item"> {showAggregationInterval && (
<div className="metrics-aggregation-section-content-item-label"> <div className="metrics-aggregation-section-content-item">
aggregated every <div className="metrics-aggregation-section-content-item-label">
</div> aggregated every
</div>
<div className="metrics-aggregation-section-content-item-value"> <div className="metrics-aggregation-section-content-item-value">
<InputWithLabel <InputWithLabel
label="Seconds" label="Seconds"
placeholder="Enter a number" placeholder="Enter a number"
labelAfter labelAfter
/> />
</div>
</div> </div>
</div> )}
</div> </div>
</div> </div>

View File

@ -2,12 +2,13 @@ import './QueryAddOns.styles.scss';
import { Button, Radio, RadioChangeEvent } from 'antd'; import { Button, Radio, RadioChangeEvent } from 'antd';
import InputWithLabel from 'components/InputWithLabel/InputWithLabel'; import InputWithLabel from 'components/InputWithLabel/InputWithLabel';
import { PANEL_TYPES } from 'constants/queryBuilder';
import { GroupByFilter } from 'container/QueryBuilder/filters/GroupByFilter/GroupByFilter'; import { GroupByFilter } from 'container/QueryBuilder/filters/GroupByFilter/GroupByFilter';
import { OrderByFilter } from 'container/QueryBuilder/filters/OrderByFilter/OrderByFilter'; import { OrderByFilter } from 'container/QueryBuilder/filters/OrderByFilter/OrderByFilter';
import { ReduceToFilter } from 'container/QueryBuilder/filters/ReduceToFilter/ReduceToFilter'; import { ReduceToFilter } from 'container/QueryBuilder/filters/ReduceToFilter/ReduceToFilter';
import { useQueryOperations } from 'hooks/queryBuilder/useQueryBuilderOperations'; import { useQueryOperations } from 'hooks/queryBuilder/useQueryBuilderOperations';
import { BarChart2, ScrollText, X } from 'lucide-react'; import { BarChart2, ScrollText, X } from 'lucide-react';
import { useCallback, useState } from 'react'; import { useCallback, useEffect, useState } from 'react';
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData'; import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
import { DataSource } from 'types/common/queryBuilder'; import { DataSource } from 'types/common/queryBuilder';
@ -19,37 +20,46 @@ interface AddOn {
key: string; key: string;
} }
const ADD_ONS: Record<string, AddOn> = { const ADD_ONS_KEYS = {
GROUP_BY: { GROUP_BY: 'group_by',
HAVING: 'having',
ORDER_BY: 'order_by',
LIMIT: 'limit',
LEGEND_FORMAT: 'legend_format',
};
const ADD_ONS = [
{
icon: <BarChart2 size={14} />, icon: <BarChart2 size={14} />,
label: 'Group By', label: 'Group By',
key: 'group_by', key: 'group_by',
}, },
HAVING: { {
icon: <ScrollText size={14} />, icon: <ScrollText size={14} />,
label: 'Having', label: 'Having',
key: 'having', key: 'having',
}, },
ORDER_BY: { {
icon: <ScrollText size={14} />, icon: <ScrollText size={14} />,
label: 'Order By', label: 'Order By',
key: 'order_by', key: 'order_by',
}, },
LIMIT: { {
icon: <ScrollText size={14} />, icon: <ScrollText size={14} />,
label: 'Limit', label: 'Limit',
key: 'limit', key: 'limit',
}, },
LEGEND_FORMAT: { {
icon: <ScrollText size={14} />, icon: <ScrollText size={14} />,
label: 'Legend format', label: 'Legend format',
key: 'legend_format', key: 'legend_format',
}, },
REDUCE_TO: { ];
icon: <ScrollText size={14} />,
label: 'Reduce to', const REDUCE_TO = {
key: 'reduce_to', icon: <ScrollText size={14} />,
}, label: 'Reduce to',
key: 'reduce_to',
}; };
function QueryAddOns({ function QueryAddOns({
@ -57,12 +67,16 @@ function QueryAddOns({
version, version,
isListViewPanel, isListViewPanel,
showReduceTo, showReduceTo,
panelType,
}: { }: {
query: IBuilderQuery; query: IBuilderQuery;
version: string; version: string;
isListViewPanel: boolean; isListViewPanel: boolean;
showReduceTo: boolean; showReduceTo: boolean;
panelType: PANEL_TYPES | null;
}): JSX.Element { }): JSX.Element {
const [addOns, setAddOns] = useState<AddOn[]>(ADD_ONS);
const [selectedViews, setSelectedViews] = useState<AddOn[]>([]); const [selectedViews, setSelectedViews] = useState<AddOn[]>([]);
const { handleChangeQueryData } = useQueryOperations({ const { handleChangeQueryData } = useQueryOperations({
@ -71,6 +85,24 @@ function QueryAddOns({
entityVersion: '', entityVersion: '',
}); });
useEffect(() => {
if (panelType === PANEL_TYPES.VALUE) {
// Filter out all add-ons except legend format
setAddOns((prevAddOns) =>
prevAddOns.filter((addOn) => addOn.key === ADD_ONS_KEYS.LEGEND_FORMAT),
);
} else {
setAddOns(Object.values(ADD_ONS));
}
// add reduce to if showReduceTo is true
if (showReduceTo) {
setAddOns((prevAddOns) => [...prevAddOns, REDUCE_TO]);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [panelType]);
const handleOptionClick = (e: RadioChangeEvent): void => { const handleOptionClick = (e: RadioChangeEvent): void => {
if (selectedViews.find((view) => view.key === e.target.value.key)) { if (selectedViews.find((view) => view.key === e.target.value.key)) {
setSelectedViews( setSelectedViews(
@ -222,24 +254,22 @@ function QueryAddOns({
onChange={handleOptionClick} onChange={handleOptionClick}
value={selectedViews} value={selectedViews}
> >
{Object.values(ADD_ONS) {addOns.map((addOn) => (
.filter((addOn) => addOn.key !== 'reduce_to' || showReduceTo) <Radio.Button
.map((addOn) => ( key={addOn.label}
<Radio.Button className={
key={addOn.label} selectedViews.find((view) => view.key === addOn.key)
className={ ? 'selected-view tab'
selectedViews.find((view) => view.key === addOn.key) : 'tab'
? 'selected-view tab' }
: 'tab' value={addOn}
} >
value={addOn} <div className="add-on-tab-title">
> {addOn.icon}
<div className="add-on-tab-title"> {addOn.label}
{addOn.icon} </div>
{addOn.label} </Radio.Button>
</div> ))}
</Radio.Button>
))}
</Radio.Group> </Radio.Group>
</div> </div>
</div> </div>

View File

@ -1,29 +1,57 @@
import './QueryAggregation.styles.scss'; import './QueryAggregation.styles.scss';
import InputWithLabel from 'components/InputWithLabel/InputWithLabel'; import InputWithLabel from 'components/InputWithLabel/InputWithLabel';
import { PANEL_TYPES } from 'constants/queryBuilder';
import { useMemo } from 'react';
import { DataSource } from 'types/common/queryBuilder';
import QueryAggregationSelect from './QueryAggregationSelect'; import QueryAggregationSelect from './QueryAggregationSelect';
function QueryAggregationOptions(): JSX.Element { function QueryAggregationOptions({
dataSource,
panelType,
}: {
dataSource: DataSource;
panelType?: string;
}): JSX.Element {
const showAggregationInterval = useMemo(() => {
// eslint-disable-next-line sonarjs/prefer-single-boolean-return
if (panelType === PANEL_TYPES.VALUE) {
return false;
}
if (dataSource === DataSource.TRACES || dataSource === DataSource.LOGS) {
return !(panelType === PANEL_TYPES.TABLE || panelType === PANEL_TYPES.PIE);
}
return true;
}, [dataSource, panelType]);
return ( return (
<div className="query-aggregation-container"> <div className="query-aggregation-container">
<QueryAggregationSelect /> <QueryAggregationSelect />
<div className="query-aggregation-interval"> {showAggregationInterval && (
<div className="query-aggregation-interval-label">every</div> <div className="query-aggregation-interval">
<div className="query-aggregation-interval-input-container"> <div className="query-aggregation-interval-label">every</div>
<InputWithLabel <div className="query-aggregation-interval-input-container">
initialValue="60" <InputWithLabel
label="Seconds" initialValue="60"
placeholder="60" label="Seconds"
type="number" placeholder="60"
labelAfter type="number"
onClose={(): void => {}} labelAfter
/> onClose={(): void => {}}
/>
</div>
</div> </div>
</div> )}
</div> </div>
); );
} }
QueryAggregationOptions.defaultProps = {
panelType: null,
};
export default QueryAggregationOptions; export default QueryAggregationOptions;

View File

@ -24,7 +24,6 @@ export const QueryV2 = memo(function QueryV2({
filterConfigs, filterConfigs,
isListViewPanel = false, isListViewPanel = false,
version, version,
showSpanScopeSelector = false,
showOnlyWhereClause = false, showOnlyWhereClause = false,
}: QueryProps): JSX.Element { }: QueryProps): JSX.Element {
const { cloneQuery, panelType } = useQueryBuilder(); const { cloneQuery, panelType } = useQueryBuilder();
@ -68,6 +67,10 @@ export const QueryV2 = memo(function QueryV2({
[dataSource, panelType], [dataSource, panelType],
); );
const showSpanScopeSelector = useMemo(() => dataSource === DataSource.TRACES, [
dataSource,
]);
return ( return (
<div className={cx('query-v2', { 'where-clause-view': showOnlyWhereClause })}> <div className={cx('query-v2', { 'where-clause-view': showOnlyWhereClause })}>
<div className="qb-content-section"> <div className="qb-content-section">
@ -147,10 +150,20 @@ export const QueryV2 = memo(function QueryV2({
</div> </div>
</div> </div>
{!showOnlyWhereClause && <QueryAggregation />} {!showOnlyWhereClause && (
<QueryAggregation
dataSource={dataSource}
panelType={panelType || undefined}
/>
)}
{!showOnlyWhereClause && dataSource === DataSource.METRICS && ( {!showOnlyWhereClause && dataSource === DataSource.METRICS && (
<MetricsAggregateSection query={query} index={0} version="v4" /> <MetricsAggregateSection
panelType={panelType}
query={query}
index={0}
version="v4"
/>
)} )}
{!showOnlyWhereClause && ( {!showOnlyWhereClause && (
@ -159,6 +172,7 @@ export const QueryV2 = memo(function QueryV2({
version="v3" version="v3"
isListViewPanel={false} isListViewPanel={false}
showReduceTo={showReduceTo} showReduceTo={showReduceTo}
panelType={panelType}
/> />
)} )}
</div> </div>