feat: enable users to query meter specific data in alerts

This commit is contained in:
Yunus M 2025-09-20 16:34:20 +05:30
parent c41ae00433
commit 8d9a865751
8 changed files with 66 additions and 8 deletions

View File

@ -398,7 +398,7 @@
} }
.qb-search-container { .qb-search-container {
.metrics-select-container { .metrics-container {
margin-bottom: 12px; margin-bottom: 12px;
} }
} }

View File

@ -22,6 +22,8 @@ export const QueryBuilderV2 = memo(function QueryBuilderV2({
showOnlyWhereClause = false, showOnlyWhereClause = false,
showTraceOperator = false, showTraceOperator = false,
version, version,
onSignalSourceChange,
signalSourceChangeEnabled = false,
}: QueryBuilderProps): JSX.Element { }: QueryBuilderProps): JSX.Element {
const { const {
currentQuery, currentQuery,
@ -175,6 +177,8 @@ export const QueryBuilderV2 = memo(function QueryBuilderV2({
queryVariant={config?.queryVariant || 'dropdown'} queryVariant={config?.queryVariant || 'dropdown'}
showOnlyWhereClause={showOnlyWhereClause} showOnlyWhereClause={showOnlyWhereClause}
isListViewPanel={isListViewPanel} isListViewPanel={isListViewPanel}
onSignalSourceChange={onSignalSourceChange || ((): void => {})}
signalSourceChangeEnabled={signalSourceChangeEnabled}
/> />
) : ( ) : (
currentQuery.builder.queryData.map((query, index) => ( currentQuery.builder.queryData.map((query, index) => (
@ -194,6 +198,8 @@ export const QueryBuilderV2 = memo(function QueryBuilderV2({
showOnlyWhereClause={showOnlyWhereClause} showOnlyWhereClause={showOnlyWhereClause}
isListViewPanel={isListViewPanel} isListViewPanel={isListViewPanel}
signalSource={config?.signalSource || ''} signalSource={config?.signalSource || ''}
onSignalSourceChange={onSignalSourceChange || ((): void => {})}
signalSourceChangeEnabled={signalSourceChangeEnabled}
/> />
)) ))
)} )}

View File

@ -1,5 +1,10 @@
.metrics-select-container { .metrics-source-select-container {
margin-bottom: 8px; margin-bottom: 8px;
display: flex;
flex-direction: row;
align-items: flex-start;
gap: 8px;
width: 100%;
.ant-select-selector { .ant-select-selector {
width: 100%; width: 100%;
@ -42,7 +47,7 @@
} }
.lightMode { .lightMode {
.metrics-select-container { .metrics-source-select-container {
.ant-select-selector { .ant-select-selector {
border: 1px solid var(--bg-vanilla-300) !important; border: 1px solid var(--bg-vanilla-300) !important;
background: var(--bg-vanilla-100); background: var(--bg-vanilla-100);

View File

@ -1,20 +1,31 @@
import './MetricsSelect.styles.scss'; import './MetricsSelect.styles.scss';
import { Select } from 'antd';
import { AggregatorFilter } from 'container/QueryBuilder/filters'; import { AggregatorFilter } from 'container/QueryBuilder/filters';
import { useQueryOperations } from 'hooks/queryBuilder/useQueryBuilderOperations'; import { useQueryOperations } from 'hooks/queryBuilder/useQueryBuilderOperations';
import { memo } from 'react'; import { memo, useState } from 'react';
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData'; import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
import { SelectOption } from 'types/common/select';
export const SOURCE_OPTIONS: SelectOption<string, string>[] = [
{ value: 'metrics', label: 'Metrics' },
{ value: 'meter', label: 'Meter' },
];
export const MetricsSelect = memo(function MetricsSelect({ export const MetricsSelect = memo(function MetricsSelect({
query, query,
index, index,
version, version,
signalSource, signalSource,
onSignalSourceChange,
signalSourceChangeEnabled = false,
}: { }: {
query: IBuilderQuery; query: IBuilderQuery;
index: number; index: number;
version: string; version: string;
signalSource: 'meter' | ''; signalSource: 'meter' | '';
onSignalSourceChange: (value: string) => void;
signalSourceChangeEnabled: boolean;
}): JSX.Element { }): JSX.Element {
const { handleChangeAggregatorAttribute } = useQueryOperations({ const { handleChangeAggregatorAttribute } = useQueryOperations({
index, index,
@ -22,8 +33,25 @@ export const MetricsSelect = memo(function MetricsSelect({
entityVersion: version, entityVersion: version,
}); });
const [source, setSource] = useState<string>(
signalSource === 'meter' ? 'meter' : 'metrics',
);
const handleSignalSourceChange = (value: string): void => {
setSource(value);
onSignalSourceChange(value);
};
return ( return (
<div className="metrics-select-container"> <div className="metrics-source-select-container">
<Select
className="source-selector"
placeholder="Source"
options={SOURCE_OPTIONS}
value={source}
onChange={handleSignalSourceChange}
disabled={!signalSourceChangeEnabled}
/>
<AggregatorFilter <AggregatorFilter
onChange={handleChangeAggregatorAttribute} onChange={handleChangeAggregatorAttribute}
query={query} query={query}

View File

@ -33,7 +33,13 @@ export const QueryV2 = memo(function QueryV2({
showOnlyWhereClause = false, showOnlyWhereClause = false,
signalSource = '', signalSource = '',
isMultiQueryAllowed = false, isMultiQueryAllowed = false,
}: QueryProps & { ref: React.RefObject<HTMLDivElement> }): JSX.Element { onSignalSourceChange,
signalSourceChangeEnabled = false,
}: QueryProps & {
ref: React.RefObject<HTMLDivElement>;
onSignalSourceChange: (value: string) => void;
signalSourceChangeEnabled: boolean;
}): JSX.Element {
const { cloneQuery, panelType } = useQueryBuilder(); const { cloneQuery, panelType } = useQueryBuilder();
const showFunctions = query?.functions?.length > 0; const showFunctions = query?.functions?.length > 0;
@ -207,12 +213,14 @@ export const QueryV2 = memo(function QueryV2({
<div className="qb-elements-container"> <div className="qb-elements-container">
<div className="qb-search-container"> <div className="qb-search-container">
{dataSource === DataSource.METRICS && ( {dataSource === DataSource.METRICS && (
<div className="metrics-select-container"> <div className="metrics-container">
<MetricsSelect <MetricsSelect
query={query} query={query}
index={index} index={index}
version={ENTITY_VERSION_V5} version={ENTITY_VERSION_V5}
signalSource={signalSource as 'meter' | ''} signalSource={signalSource as 'meter' | ''}
onSignalSourceChange={onSignalSourceChange}
signalSourceChangeEnabled={signalSourceChangeEnabled}
/> />
</div> </div>
)} )}

View File

@ -36,6 +36,7 @@ function QuerySection({
// init namespace for translations // init namespace for translations
const { t } = useTranslation('alerts'); const { t } = useTranslation('alerts');
const [currentTab, setCurrentTab] = useState(queryCategory); const [currentTab, setCurrentTab] = useState(queryCategory);
const [signalSource, setSignalSource] = useState<string>('metrics');
const handleQueryCategoryChange = (queryType: string): void => { const handleQueryCategoryChange = (queryType: string): void => {
setQueryCategory(queryType as EQueryType); setQueryCategory(queryType as EQueryType);
@ -48,12 +49,17 @@ function QuerySection({
const isDarkMode = useIsDarkMode(); const isDarkMode = useIsDarkMode();
const handleSignalSourceChange = (value: string): void => {
setSignalSource(value);
};
const renderMetricUI = (): JSX.Element => ( const renderMetricUI = (): JSX.Element => (
<QueryBuilderV2 <QueryBuilderV2
panelType={panelType} panelType={panelType}
config={{ config={{
queryVariant: 'static', queryVariant: 'static',
initialDataSource: ALERTS_DATA_SOURCE_MAP[alertType], initialDataSource: ALERTS_DATA_SOURCE_MAP[alertType],
signalSource: signalSource === 'meter' ? 'meter' : '',
}} }}
showTraceOperator={alertType === AlertTypes.TRACES_BASED_ALERT} showTraceOperator={alertType === AlertTypes.TRACES_BASED_ALERT}
showFunctions={ showFunctions={
@ -62,6 +68,9 @@ function QuerySection({
alertType === AlertTypes.LOGS_BASED_ALERT alertType === AlertTypes.LOGS_BASED_ALERT
} }
version={alertDef.version || 'v3'} version={alertDef.version || 'v3'}
onSignalSourceChange={handleSignalSourceChange}
key={signalSource}
signalSourceChangeEnabled
/> />
); );

View File

@ -119,7 +119,7 @@ function BreakDown(): JSX.Element {
type="info" type="info"
showIcon showIcon
message="Billing is calculated in UTC. To match your meter data with billing, select full-day ranges in UTC time (00:00 23:59 UTC). message="Billing is calculated in UTC. To match your meter data with billing, select full-day ranges in UTC time (00:00 23:59 UTC).
For example, if youre in IST, for the billing of Jan 1, select your time range as Jan 1, 5:30 AM Jan 2, 5:29 AM IST." For example, if youre in PST, for the billing of Jan 2, select your time range as Jan 1, 5:00 PM Jan 2, 4:59 PM PST." // to PT timezone (PST)
/> />
{isCloudUser && ( {isCloudUser && (
<Alert <Alert

View File

@ -35,6 +35,8 @@ export type QueryBuilderProps = {
showTraceOperator?: boolean; showTraceOperator?: boolean;
version: string; version: string;
onChangeTraceView?: (view: TraceView) => void; onChangeTraceView?: (view: TraceView) => void;
onSignalSourceChange?: (value: string) => void;
signalSourceChangeEnabled?: boolean;
}; };
export enum TraceView { export enum TraceView {