feat: update logs, metrics and traces qb

This commit is contained in:
Yunus M 2025-05-26 03:28:56 +05:30 committed by SagarRajput-7
parent 44eb60fef9
commit 255fe1b70a
32 changed files with 627 additions and 278 deletions

View File

@ -1,171 +1,79 @@
import './LogsQB.styles.scss';
import { Button, Dropdown } from 'antd';
import { ENTITY_VERSION_V4 } from 'constants/app';
import QBEntityOptions from 'container/QueryBuilder/components/QBEntityOptions/QBEntityOptions';
import { QueryBuilderProps } from 'container/QueryBuilder/QueryBuilder.interfaces';
import { Formula } from 'container/QueryBuilder/components/Formula/Formula';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { useQueryOperations } from 'hooks/queryBuilder/useQueryBuilderOperations';
import { Copy, Ellipsis, Plus, Sigma, Trash } from 'lucide-react';
import { memo, useCallback, useState } from 'react';
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
import { memo } from 'react';
import { DataSource } from 'types/common/queryBuilder';
import QueryAddOns from '../QueryAddOns/QueryAddOns';
import QueryAggregation from '../QueryAggregation/QueryAggregation';
import QuerySearch from '../QuerySearch/QuerySearch';
import { Formula } from 'container/QueryBuilder/components/Formula/Formula';
import { QueryBuilderV2Props } from '../QueryBuilderV2';
import QueryFooter from '../QueryV2/QueryFooter/QueryFooter';
import { QueryV2 } from '../QueryV2/QueryV2';
export const LogsQB = memo(function LogsQB({
query,
filterConfigs,
}: {
query: IBuilderQuery;
filterConfigs: QueryBuilderProps['filterConfigs'];
}): JSX.Element {
const showFunctions = query?.functions?.length > 0;
}: QueryBuilderV2Props): JSX.Element {
const version = ENTITY_VERSION_V4;
const {
currentQuery,
cloneQuery,
addNewFormula,
addNewBuilderQuery,
} = useQueryBuilder();
const [isCollapsed, setIsCollapsed] = useState(false);
console.log('isCollapsed', isCollapsed);
const isListViewPanel = false;
const index = 0;
const {
isMetricsDataSource,
handleChangeQueryData,
handleDeleteQuery,
handleQueryFunctionsUpdates,
} = useQueryOperations({
index,
query,
filterConfigs,
isListViewPanel,
entityVersion: version,
});
const handleToggleDisableQuery = useCallback(() => {
handleChangeQueryData('disabled', !query.disabled);
}, [handleChangeQueryData, query]);
const handleToggleCollapsQuery = (): void => {
setIsCollapsed(!isCollapsed);
};
const { currentQuery, addNewFormula, addNewBuilderQuery } = useQueryBuilder();
return (
<div className="logs-qb">
<div className="qb-content-container">
<div className="qb-content-section">
<div className="qb-header-container">
<div className="query-actions-container">
<div className="query-actions-left-container">
<QBEntityOptions
isMetricsDataSource={isMetricsDataSource}
showFunctions={
(version && version === ENTITY_VERSION_V4) ||
query.dataSource === DataSource.LOGS ||
showFunctions ||
false
}
isCollapsed={isCollapsed}
entityType="query"
entityData={query}
onToggleVisibility={handleToggleDisableQuery}
onDelete={handleDeleteQuery}
onCloneQuery={cloneQuery}
onCollapseEntity={handleToggleCollapsQuery}
query={query}
onQueryFunctionsUpdates={handleQueryFunctionsUpdates}
showDeleteButton={currentQuery.builder.queryData.length > 1}
isListViewPanel={isListViewPanel}
index={index}
/>
</div>
{currentQuery.builder.queryData.map((query, index) => (
<QueryV2
key={query.queryName}
index={index}
query={query}
filterConfigs={filterConfigs}
version={version}
isAvailableToDisable={false}
queryVariant="static"
source={DataSource.LOGS}
/>
))}
<Dropdown
className="query-actions-dropdown"
menu={{
items: [
{
label: 'Clone',
key: 'clone-query',
icon: <Copy size={14} />,
},
{
label: 'Delete',
key: 'delete-query',
icon: <Trash size={14} />,
},
],
}}
placement="bottomRight"
>
<Ellipsis size={16} />
</Dropdown>
</div>
{currentQuery.builder.queryFormulas.length > 0 && (
<div className="qb-formulas-container">
{currentQuery.builder.queryFormulas.map((formula, index) => {
const query =
currentQuery.builder.queryData[index] ||
currentQuery.builder.queryData[0];
return (
<div key={formula.queryName} className="qb-formula">
<Formula
filterConfigs={filterConfigs}
query={query}
formula={formula}
index={index}
isAdditionalFilterEnable={false}
/>
</div>
);
})}
</div>
)}
<div className="qb-elements-container">
<QuerySearch />
<QueryAggregation source={DataSource.LOGS} />
<QueryAddOns query={query} version="v3" isListViewPanel={false} />
</div>
</div>
<div className="qb-formulas-container">
{currentQuery.builder.queryFormulas.map((formula, index) => {
const query =
currentQuery.builder.queryData[index] ||
currentQuery.builder.queryData[0];
return (
<div key={formula.queryName} className="qb-formula">
<Formula
filterConfigs={filterConfigs}
query={query}
formula={formula}
index={index}
isAdditionalFilterEnable={isMetricsDataSource}
/>
</div>
);
})}
</div>
<div className="qb-footer">
<div className="qb-footer-container">
<div className="qb-add-new-query">
<Button
className="add-new-query-button periscope-btn secondary"
type="text"
icon={<Plus size={16} />}
onClick={addNewBuilderQuery}
/>
</div>
<div className="qb-add-formula">
<Button
className="add-formula-button periscope-btn secondary"
icon={<Sigma size={16} />}
onClick={addNewFormula}
>
Add Formula
</Button>
</div>
</div>
</div>
<QueryFooter
addNewBuilderQuery={addNewBuilderQuery}
addNewFormula={addNewFormula}
/>
</div>
<div className="query-names-section" />
<div className="query-names-section">
{currentQuery.builder.queryData.map((query) => (
<div key={query.queryName} className="query-name">
{query.queryName}
</div>
))}
{currentQuery.builder.queryFormulas.map((formula) => (
<div key={formula.queryName} className="formula-name">
{formula.queryName}
</div>
))}
</div>
</div>
);
});

View File

@ -1,5 +1,19 @@
.metrics-qb {
display: flex;
flex-direction: column;
flex-direction: row;
gap: 8px;
border-bottom: 1px solid var(--Slate-400, #1d212d);
.query-v2 {
.qb-entity-options {
.options {
.query-name {
&::before {
height: 306px !important;
}
}
}
}
}
}

View File

@ -1,19 +1,87 @@
import './MetricsQB.styles.scss';
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
import { ENTITY_VERSION_V4 } from 'constants/app';
import { Formula } from 'container/QueryBuilder/components/Formula/Formula';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { useQueryOperations } from 'hooks/queryBuilder/useQueryBuilderOperations';
import { DataSource } from 'types/common/queryBuilder';
import QueryAddOns from '../QueryAddOns/QueryAddOns';
import QuerySearch from '../QuerySearch/QuerySearch';
import MetricsAggregateSection from './MerticsAggregateSection/MetricsAggregateSection';
import { MetricsSelect } from './MetricsSelect/MetricsSelect';
import { QueryBuilderV2Props } from '../QueryBuilderV2';
import QueryFooter from '../QueryV2/QueryFooter/QueryFooter';
import { QueryV2 } from '../QueryV2/QueryV2';
function MetricsQB({ filterConfigs }: QueryBuilderV2Props): JSX.Element {
const version = ENTITY_VERSION_V4;
const { currentQuery, addNewFormula, addNewBuilderQuery } = useQueryBuilder();
const { isMetricsDataSource } = useQueryOperations({
index: 0,
query: currentQuery.builder.queryData[0],
filterConfigs,
isListViewPanel: false,
entityVersion: version,
});
console.log('isMetricsDataSource', isMetricsDataSource);
function MetricsQB({ query }: { query: IBuilderQuery }): JSX.Element {
return (
<div className="metrics-qb">
<MetricsSelect query={query} index={0} version="v4" />
<QuerySearch />
<MetricsAggregateSection query={query} index={0} version="v4" />
<QueryAddOns query={query} version="v3" isListViewPanel={false} />
<div className="qb-content-container">
{currentQuery.builder.queryData.map((query, index) => (
<QueryV2
key={query.queryName}
index={index}
query={query}
filterConfigs={filterConfigs}
version={version}
isAvailableToDisable={false}
queryVariant="static"
source={DataSource.METRICS}
/>
))}
{currentQuery.builder.queryFormulas.length > 0 && (
<div className="qb-formulas-container">
{currentQuery.builder.queryFormulas.map((formula, index) => {
const query =
currentQuery.builder.queryData[index] ||
currentQuery.builder.queryData[0];
return (
<div key={formula.queryName} className="qb-formula">
<Formula
filterConfigs={filterConfigs}
query={query}
formula={formula}
index={index}
isAdditionalFilterEnable={false} // TODO: Need to enable this
/>
</div>
);
})}
</div>
)}
<QueryFooter
addNewBuilderQuery={addNewBuilderQuery}
addNewFormula={addNewFormula}
/>
</div>
<div className="query-names-section">
{currentQuery.builder.queryData.map((query) => (
<div key={query.queryName} className="query-name">
{query.queryName}
</div>
))}
{currentQuery.builder.queryFormulas.map((formula) => (
<div key={formula.queryName} className="formula-name">
{formula.queryName}
</div>
))}
</div>
</div>
);
}

View File

@ -59,7 +59,8 @@
.code-mirror-where-clause,
.query-aggregation-container,
.query-add-ons {
.query-add-ons,
.metrics-aggregation-section-content {
position: relative;
&::before {
@ -98,9 +99,58 @@
gap: 8px;
width: 44px;
padding-left: 8px;
padding: 8px;
border-left: 1px solid var(--bg-slate-400);
.query-name {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 10px;
padding: 4px;
border-radius: 0px 2px 2px 0px;
border-radius: 2px;
border: 1px solid rgba(242, 71, 105, 0.2);
background: rgba(242, 71, 105, 0.1);
color: var(--Sakura-400, #f56c87);
font-family: 'Space Mono';
font-size: 12px;
font-style: normal;
font-weight: 400;
line-height: 16px; /* 128.571% */
text-transform: uppercase;
}
.formula-name {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 10px;
padding: 4px;
border-radius: 0px 2px 2px 0px;
border-radius: 2px;
border: 1px solid rgba(173, 127, 88, 0.2);
background: rgba(173, 127, 88, 0.1);
color: var(--Sienna-500, #ad7f58);
font-family: 'Space Mono';
font-size: 12px;
font-style: normal;
font-weight: 400;
line-height: 16px; /* 128.571% */
text-transform: uppercase;
}
}
.qb-formulas-container {
@ -159,6 +209,12 @@
border-bottom-left-radius: 0px !important;
border-bottom-right-radius: 0px !important;
font-family: 'Space Mono';
font-size: 12px;
font-style: normal;
font-weight: 400;
line-height: 16px; /* 128.571% */
resize: none;
}
@ -222,7 +278,7 @@
gap: 8px;
.options {
.query-name.sync-btn {
.query-name {
border-radius: 0px 2px 2px 0px !important;
border: 1px solid rgba(242, 71, 105, 0.2) !important;
background: rgba(242, 71, 105, 0.1) !important;
@ -256,11 +312,10 @@
}
.formula-name {
border-radius: 0px 2px 2px 0px !important;
border: 1px solid rgba(242, 71, 105, 0.2) !important;
background: rgba(242, 71, 105, 0.1) !important;
border-radius: 0px 2px 2px 0px;
border: 1px solid rgba(173, 127, 88, 0.2);
background: rgba(173, 127, 88, 0.1);
color: var(--Sakura-400, #f56c87) !important;
font-family: 'Space Mono';
font-size: 14px;
font-style: normal;
@ -270,7 +325,7 @@
&::before {
content: '';
height: 80px;
height: 65px;
content: '';
position: absolute;
left: 0;
@ -289,4 +344,37 @@
}
}
}
.qb-search-container {
.metrics-select-container {
margin-bottom: 12px;
}
}
.qb-search-filter-container {
display: flex;
flex-direction: row;
align-items: center;
gap: 8px;
.ant-select {
height: auto;
}
.ant-select-selector {
border-radius: 2px;
border: 1px solid var(--Slate-400, #1d212d) !important;
background: var(--Ink-300, #16181d) !important;
height: 34px !important;
box-sizing: border-box !important;
}
.ant-select-arrow {
color: var(--bg-vanilla-400) !important;
}
}
.query-actions-dropdown {
cursor: pointer;
}
}

View File

@ -1,9 +1,8 @@
import './QueryBuilderV2.styles.scss';
import { OPERATORS } from 'constants/queryBuilder';
import { OPERATORS, PANEL_TYPES } from 'constants/queryBuilder';
import { QueryBuilderProps } from 'container/QueryBuilder/QueryBuilder.interfaces';
import { useMemo } from 'react';
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
import { memo, useMemo } from 'react';
import { DataSource } from 'types/common/queryBuilder';
import { LogsQB } from './Logs/LogsQB';
@ -11,14 +10,20 @@ import MetricsQB from './Metrics/MetricsQB';
import { QueryBuilderV2Provider } from './QueryBuilderV2Context';
import TracesQB from './Traces/TracesQB';
type QueryBuilderV2Props = {
export type QueryBuilderV2Props = {
source: DataSource;
query: IBuilderQuery;
panelType: PANEL_TYPES;
filterConfigs: QueryBuilderProps['filterConfigs'];
isListViewPanel: boolean;
version: string;
};
function QueryBuilderV2Main({
const QueryBuilderV2Main = memo(function QueryBuilderV2Main({
source,
query,
panelType,
filterConfigs,
isListViewPanel,
version,
}: QueryBuilderV2Props): JSX.Element {
const isMetricsDataSource = source === DataSource.METRICS;
const isLogsDataSource = source === DataSource.LOGS;
@ -53,28 +58,49 @@ function QueryBuilderV2Main({
return (
<div className="query-builder-v2">
{isMetricsDataSource ? <MetricsQB query={query} /> : null}
{isLogsDataSource ? (
<LogsQB
query={query}
filterConfigs={
query.dataSource === DataSource.TRACES
? listViewTracesFilterConfigs
: listViewLogFilterConfigs
}
{isMetricsDataSource ? (
<MetricsQB
source={DataSource.METRICS}
filterConfigs={filterConfigs}
panelType={panelType}
version={version}
isListViewPanel={isListViewPanel}
/>
) : null}
{isLogsDataSource ? (
<LogsQB
source={DataSource.LOGS}
filterConfigs={listViewLogFilterConfigs}
panelType={panelType}
version={version}
isListViewPanel={isListViewPanel}
/>
) : null}
{isTracesDataSource ? (
<TracesQB
source={DataSource.TRACES}
filterConfigs={listViewTracesFilterConfigs}
panelType={panelType}
version={version}
isListViewPanel={isListViewPanel}
/>
) : null}
{isTracesDataSource ? <TracesQB query={query} /> : null}
</div>
);
}
});
function QueryBuilderV2(props: QueryBuilderV2Props): JSX.Element {
const { source, query } = props;
const { source, panelType, filterConfigs, isListViewPanel, version } = props;
return (
<QueryBuilderV2Provider>
<QueryBuilderV2Main source={source} query={query} />
<QueryBuilderV2Main
source={source}
panelType={panelType}
filterConfigs={filterConfigs}
isListViewPanel={isListViewPanel}
version={version}
/>
</QueryBuilderV2Provider>
);
}

View File

@ -7,7 +7,7 @@
.metrics-time-aggregation-section {
display: flex;
flex-direction: column;
gap: 4px;
gap: 12px;
.metrics-time-aggregation-section-title {
display: flex;

View File

@ -1,3 +1,4 @@
/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable sonarjs/cognitive-complexity */
import {
autocompletion,

View File

@ -122,20 +122,25 @@ function QueryAddOns({
)}
{selectedViews.find((view) => view.key === 'having') && (
<div className="add-on-content">
<HavingFilter
onClose={(): void => {
setSelectedViews(
selectedViews.filter((view) => view.key !== 'having'),
);
}}
/>
<div className="periscope-input-with-label">
<div className="label">Having</div>
<div className="input">
<HavingFilter
onClose={(): void => {
setSelectedViews(
selectedViews.filter((view) => view.key !== 'having'),
);
}}
/>
</div>
</div>
</div>
)}
{selectedViews.find((view) => view.key === 'limit') && (
<div className="add-on-content">
<InputWithLabel
label="Limit"
placeholder="Select a field"
label="LIMIT"
placeholder="Enter limit"
onClose={(): void => {
setSelectedViews(selectedViews.filter((view) => view.key !== 'limit'));
}}
@ -165,7 +170,7 @@ function QueryAddOns({
{selectedViews.find((view) => view.key === 'legend_format') && (
<div className="add-on-content">
<InputWithLabel
label="Legend format"
label="LEGEND FORMAT"
placeholder="Write legend format"
onClose={(): void => {
setSelectedViews(

View File

@ -33,7 +33,7 @@ import { useQuery } from 'react-query';
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
import { TracesAggregatorOperator } from 'types/common/queryBuilder';
import { useQueryBuilderV2Context } from '../QueryBuilderV2Context';
import { useQueryBuilderV2Context } from '../../QueryBuilderV2Context';
const chipDecoration = Decoration.mark({
class: 'chip-decorator',

View File

@ -0,0 +1,35 @@
import { Button } from 'antd';
import { Plus, Sigma } from 'lucide-react';
export default function QueryFooter({
addNewBuilderQuery,
addNewFormula,
}: {
addNewBuilderQuery: () => void;
addNewFormula: () => void;
}): JSX.Element {
return (
<div className="qb-footer">
<div className="qb-footer-container">
<div className="qb-add-new-query">
<Button
className="add-new-query-button periscope-btn secondary"
type="text"
icon={<Plus size={16} />}
onClick={addNewBuilderQuery}
/>
</div>
<div className="qb-add-formula">
<Button
className="add-formula-button periscope-btn secondary"
icon={<Sigma size={16} />}
onClick={addNewFormula}
>
Add Formula
</Button>
</div>
</div>
</div>
);
}

View File

@ -0,0 +1,143 @@
import { Dropdown } from 'antd';
import { ENTITY_VERSION_V4 } from 'constants/app';
import QBEntityOptions from 'container/QueryBuilder/components/QBEntityOptions/QBEntityOptions';
import { QueryProps } from 'container/QueryBuilder/components/Query/Query.interfaces';
import SpanScopeSelector from 'container/QueryBuilder/filters/QueryBuilderSearchV2/SpanScopeSelector';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { useQueryOperations } from 'hooks/queryBuilder/useQueryBuilderOperations';
import { Copy, Ellipsis, Trash } from 'lucide-react';
import { memo, useCallback, useState } from 'react';
import { DataSource } from 'types/common/queryBuilder';
import MetricsAggregateSection from './MerticsAggregateSection/MetricsAggregateSection';
import { MetricsSelect } from './MetricsSelect/MetricsSelect';
import QueryAddOns from './QueryAddOns/QueryAddOns';
import QueryAggregation from './QueryAggregation/QueryAggregation';
import QuerySearch from './QuerySearch/QuerySearch';
export const QueryV2 = memo(function QueryV2({
index,
query,
filterConfigs,
isListViewPanel = false,
version,
showSpanScopeSelector = false,
source,
}: QueryProps & { source: DataSource }): JSX.Element {
const { cloneQuery } = useQueryBuilder();
const showFunctions = query?.functions?.length > 0;
const [isCollapsed, setIsCollapsed] = useState(false);
const {
handleChangeQueryData,
handleDeleteQuery,
handleQueryFunctionsUpdates,
} = useQueryOperations({
index,
query,
filterConfigs,
isListViewPanel,
entityVersion: version,
});
const handleToggleDisableQuery = useCallback(() => {
handleChangeQueryData('disabled', !query.disabled);
}, [handleChangeQueryData, query]);
const handleToggleCollapsQuery = (): void => {
setIsCollapsed(!isCollapsed);
};
const handleCloneEntity = (): void => {
cloneQuery('query', query);
};
return (
<div className="query-v2">
<div className="qb-content-section">
<div className="qb-header-container">
<div className="query-actions-container">
<div className="query-actions-left-container">
<QBEntityOptions
isMetricsDataSource={source === DataSource.METRICS}
showFunctions={
(version && version === ENTITY_VERSION_V4) ||
query.dataSource === DataSource.LOGS ||
showFunctions ||
false
}
isCollapsed={isCollapsed}
entityType="query"
entityData={query}
onToggleVisibility={handleToggleDisableQuery}
onDelete={handleDeleteQuery}
onCloneQuery={cloneQuery}
onCollapseEntity={handleToggleCollapsQuery}
query={query}
onQueryFunctionsUpdates={handleQueryFunctionsUpdates}
showDeleteButton={false}
showCloneOption={false}
isListViewPanel={isListViewPanel}
index={index}
/>
</div>
<Dropdown
className="query-actions-dropdown"
menu={{
items: [
{
label: 'Clone',
key: 'clone-query',
icon: <Copy size={14} />,
onClick: handleCloneEntity,
},
{
label: 'Delete',
key: 'delete-query',
icon: <Trash size={14} />,
onClick: handleDeleteQuery,
},
],
}}
placement="bottomRight"
>
<Ellipsis size={16} />
</Dropdown>
</div>
</div>
<div className="qb-elements-container">
<div className="qb-search-container">
{source === DataSource.METRICS && (
<div className="metrics-select-container">
<MetricsSelect query={query} index={0} version="v4" />
</div>
)}
<div className="qb-search-filter-container">
<QuerySearch />
{showSpanScopeSelector && (
<>
<div className="traces-search-filter-in">in</div>
<SpanScopeSelector queryName={query.queryName} />
</>
)}
</div>
</div>
<QueryAggregation source={source} />
{source === DataSource.METRICS && (
<MetricsAggregateSection query={query} index={0} version="v4" />
)}
<QueryAddOns query={query} version="v3" isListViewPanel={false} />
</div>
</div>
</div>
);
});

View File

@ -1,28 +1,5 @@
.traces-qb {
display: flex;
flex-direction: column;
flex-direction: row;
gap: 8px;
.traces-search-filter-container {
display: flex;
flex-direction: row;
align-items: center;
gap: 8px;
.ant-select {
height: auto;
}
.ant-select-selector {
border-radius: 2px;
border: 1px solid var(--Slate-400, #1d212d) !important;
background: var(--Ink-300, #16181d) !important;
height: 34px !important;
box-sizing: border-box !important;
}
.ant-select-arrow {
color: var(--bg-vanilla-400) !important;
}
}
}

View File

@ -1,23 +1,86 @@
import './TracesQB.styles.scss';
import SpanScopeSelector from 'container/QueryBuilder/filters/QueryBuilderSearchV2/SpanScopeSelector';
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
import { ENTITY_VERSION_V4 } from 'constants/app';
import { Formula } from 'container/QueryBuilder/components/Formula';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { useQueryOperations } from 'hooks/queryBuilder/useQueryBuilderOperations';
import { DataSource } from 'types/common/queryBuilder';
import QueryAddOns from '../QueryAddOns/QueryAddOns';
import QueryAggregation from '../QueryAggregation/QueryAggregation';
import QuerySearch from '../QuerySearch/QuerySearch';
import { QueryBuilderV2Props } from '../QueryBuilderV2';
import QueryFooter from '../QueryV2/QueryFooter/QueryFooter';
import { QueryV2 } from '../QueryV2/QueryV2';
function TracesQB({ filterConfigs }: QueryBuilderV2Props): JSX.Element {
const version = ENTITY_VERSION_V4;
const { currentQuery, addNewFormula, addNewBuilderQuery } = useQueryBuilder();
const { isMetricsDataSource } = useQueryOperations({
index: 0,
query: currentQuery.builder.queryData[0],
filterConfigs,
isListViewPanel: false,
entityVersion: version,
});
function TracesQB({ query }: { query: IBuilderQuery }): JSX.Element {
return (
<div className="traces-qb">
<div className="traces-search-filter-container">
<QuerySearch />
<div className="traces-search-filter-in">in</div>
<SpanScopeSelector queryName={query.queryName} />
<div className="qb-content-container">
{currentQuery.builder.queryData.map((query, index) => (
<QueryV2
key={query.queryName}
index={index}
query={query}
filterConfigs={filterConfigs}
version={version}
isAvailableToDisable={false}
queryVariant="static"
source={DataSource.TRACES}
showSpanScopeSelector
/>
))}
{currentQuery.builder.queryFormulas.length > 0 && (
<div className="qb-formulas-container">
{currentQuery.builder.queryFormulas.map((formula, index) => {
const query =
currentQuery.builder.queryData[index] ||
currentQuery.builder.queryData[0];
return (
<div key={formula.queryName} className="qb-formula">
<Formula
filterConfigs={filterConfigs}
query={query}
formula={formula}
index={index}
isAdditionalFilterEnable={isMetricsDataSource}
/>
</div>
);
})}
</div>
)}
<QueryFooter
addNewBuilderQuery={addNewBuilderQuery}
addNewFormula={addNewFormula}
/>
</div>
<div className="query-names-section">
{currentQuery.builder.queryData.map((query) => (
<div key={query.queryName} className="query-name">
{query.queryName}
</div>
))}
{currentQuery.builder.queryFormulas.map((formula) => (
<div key={formula.queryName} className="formula-name">
{formula.queryName}
</div>
))}
</div>
<QueryAggregation source={DataSource.TRACES} />
<QueryAddOns query={query} version="v3" isListViewPanel={false} />
</div>
);
}

View File

@ -110,7 +110,13 @@ function LogExplorerQuerySection({
)}
{selectedView === SELECTED_VIEWS.QUERY_BUILDER_V2 && (
<QueryBuilderV2 source={DataSource.LOGS} query={query} />
<QueryBuilderV2
source={DataSource.LOGS}
isListViewPanel={panelTypes === PANEL_TYPES.LIST}
panelType={panelTypes}
filterConfigs={filterConfigs}
version="v3" // setting this to v3 as we this is rendered in logs explorer
/>
)}
</>
);

View File

@ -6,6 +6,7 @@
align-items: center;
justify-content: space-between;
margin: 10px 0;
padding: 0 1rem;
.explore-header-left-actions {
display: flex;

View File

@ -1,9 +1,10 @@
import './QuerySection.styles.scss';
import { Color } from '@signozhq/design-tokens';
import { Button, Tabs, Typography } from 'antd';
import { Button, Select, Tabs, Typography } from 'antd';
import logEvent from 'api/common/logEvent';
import PromQLIcon from 'assets/Dashboard/PromQl';
import QueryBuilderV2 from 'components/QueryBuilderV2/QueryBuilderV2';
import TextToolTip from 'components/TextToolTip';
import { PANEL_TYPES } from 'constants/queryBuilder';
import { QBShortcuts } from 'constants/shortcuts/QBShortcuts';
@ -11,7 +12,7 @@ import {
getDefaultWidgetData,
PANEL_TYPE_TO_QUERY_TYPES,
} from 'container/NewWidget/utils';
import { QueryBuilder } from 'container/QueryBuilder';
// import { QueryBuilder } from 'container/QueryBuilder';
import { QueryBuilderProps } from 'container/QueryBuilder/QueryBuilder.interfaces';
import { useKeyboardHotkeys } from 'hooks/hotkeys/useKeyboardHotkeys';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
@ -26,13 +27,14 @@ import {
getPreviousWidgets,
getSelectedWidgetIndex,
} from 'providers/Dashboard/util';
import { useCallback, useEffect, useMemo } from 'react';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { UseQueryResult } from 'react-query';
import { SuccessResponse } from 'types/api';
import { Widgets } from 'types/api/dashboard/getAll';
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
import { Query } from 'types/api/queryBuilder/queryBuilderData';
import { EQueryType } from 'types/common/dashboard';
import { DataSource } from 'types/common/queryBuilder';
import ClickHouseQueryContainer from './QueryBuilder/clickHouse';
import PromQLQueryContainer from './QueryBuilder/promQL';
@ -47,6 +49,10 @@ function QuerySection({
const { selectedDashboard, setSelectedDashboard } = useDashboard();
const [selectedDataSource, setSelectedDataSource] = useState<DataSource>(
DataSource.METRICS,
);
const isDarkMode = useIsDarkMode();
const { widgets } = selectedDashboard?.data || {};
@ -150,12 +156,23 @@ function QuerySection({
icon: <Atom size={14} />,
label: 'Query Builder',
component: (
<QueryBuilder
panelType={selectedGraph}
filterConfigs={filterConfigs}
version={selectedDashboard?.data?.version || 'v3'}
isListViewPanel={selectedGraph === PANEL_TYPES.LIST}
/>
<div className="query-builder-v2-container">
<Select
onChange={setSelectedDataSource}
value={selectedDataSource}
options={Object.values(DataSource).map((dataSource) => ({
label: dataSource,
value: dataSource,
}))}
/>
<QueryBuilderV2
panelType={selectedGraph}
filterConfigs={filterConfigs}
version={selectedDashboard?.data?.version || 'v3'}
isListViewPanel={selectedGraph === PANEL_TYPES.LIST}
source={selectedDataSource}
/>
</div>
),
},
[EQueryType.CLICKHOUSE]: {
@ -190,6 +207,7 @@ function QuerySection({
filterConfigs,
selectedDashboard?.data?.version,
isDarkMode,
selectedDataSource,
]);
useEffect(() => {

View File

@ -78,11 +78,11 @@
color: var(--bg-sakura-400);
}
&.sync-btn {
border: 1px solid rgba(78, 116, 248, 0.2);
background: rgba(78, 116, 248, 0.1);
color: var(--bg-robin-500);
}
// &.sync-btn {
// border: 1px solid rgba(78, 116, 248, 0.2);
// background: rgba(78, 116, 248, 0.1);
// color: var(--bg-robin-500);
// }
}
&.formula-btn {

View File

@ -165,6 +165,7 @@ export function Formula({
onChange={handleChange}
size="middle"
value={formula.expression}
placeholder="Enter formula"
rows={2}
/>
</Col>

View File

@ -47,11 +47,11 @@
border: 1px solid rgba(242, 71, 105, 0.2) !important;
background: rgba(242, 71, 105, 0.1) !important;
&.sync-btn {
border: 1px solid rgba(78, 116, 248, 0.2) !important;
background: rgba(78, 116, 248, 0.1) !important;
color: var(--bg-robin-500) !important;
}
// &.sync-btn {
// border: 1px solid rgba(78, 116, 248, 0.2) !important;
// background: rgba(78, 116, 248, 0.1) !important;
// color: var(--bg-robin-500) !important;
// }
&:hover {
border: 1px solid rgba(242, 71, 105, 0.4) !important;

View File

@ -31,12 +31,13 @@ interface QBEntityOptionsProps {
isCollapsed: boolean;
entityType: string;
entityData: any;
onDelete: () => void;
onDelete?: () => void;
onCloneQuery?: (type: string, query: IBuilderQuery) => void;
onToggleVisibility: () => void;
onCollapseEntity: () => void;
onQueryFunctionsUpdates?: (functions: QueryFunctionProps[]) => void;
showDeleteButton: boolean;
showDeleteButton?: boolean;
showCloneOption?: boolean;
isListViewPanel?: boolean;
index?: number;
}
@ -48,13 +49,14 @@ export default function QBEntityOptions({
showFunctions,
entityType,
entityData,
onDelete,
onCloneQuery,
onToggleVisibility,
onCollapseEntity,
showDeleteButton,
onQueryFunctionsUpdates,
isListViewPanel,
onDelete,
showDeleteButton,
showCloneOption,
onCloneQuery,
index,
}: QBEntityOptionsProps): JSX.Element {
const handleCloneEntity = (): void => {
@ -96,14 +98,14 @@ export default function QBEntityOptions({
{entityData.disabled ? <EyeOff size={16} /> : <Eye size={16} />}
</Button>
</Tooltip>
{/*
{entityType === 'query' && (
{entityType === 'query' && showCloneOption && (
<Tooltip title={`Clone Query ${entityData.queryName}`}>
<Button className={cx('periscope-btn')} onClick={handleCloneEntity}>
<Copy size={14} />
</Button>
</Tooltip>
)} */}
)}
<Button
className={cx(
@ -156,4 +158,7 @@ QBEntityOptions.defaultProps = {
showFunctions: false,
onCloneQuery: noop,
index: 0,
onDelete: noop,
showDeleteButton: false,
showCloneOption: true,
};

View File

@ -5,8 +5,9 @@ export type QueryProps = {
index: number;
isAvailableToDisable: boolean;
query: IBuilderQuery;
queryVariant: 'static' | 'dropdown';
queryVariant?: 'static' | 'dropdown';
isListViewPanel?: boolean;
showFunctions?: boolean;
version: string;
showSpanScopeSelector?: boolean;
} & Pick<QueryBuilderProps, 'filterConfigs' | 'queryComponents'>;

View File

@ -24,7 +24,6 @@ import { getMetricsOperatorsByAttributeType } from 'lib/newQueryBuilder/getMetri
import { getOperatorsBySourceAndPanelType } from 'lib/newQueryBuilder/getOperatorsBySourceAndPanelType';
import { findDataTypeOfOperator } from 'lib/query/findDataTypeOfOperator';
import { isEmpty, isEqual } from 'lodash-es';
import cloneDeep from 'lodash-es/cloneDeep';
import { useCallback, useEffect, useState } from 'react';
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
import {
@ -182,11 +181,6 @@ export const useQueryOperations: UseQueryOperations = ({
break;
}
console.log(
'newOperators handleMetricAggregateAtributeTypes',
cloneDeep(newOperators),
);
setOperators(newOperators);
},
[panelType],
@ -200,9 +194,6 @@ export const useQueryOperations: UseQueryOperations = ({
having: [],
};
console.log('newQuery', newQuery.dataSource);
console.log('entityVersion', entityVersion);
if (
newQuery.dataSource === DataSource.METRICS &&
entityVersion === ENTITY_VERSION_V4
@ -276,8 +267,6 @@ export const useQueryOperations: UseQueryOperations = ({
aggregateOperator: newOperators[0].value,
};
console.log('newOperators handleChangeDataSource', cloneDeep(newOperators));
setOperators(newOperators);
handleSetQueryData(index, newQuery);
},
@ -399,8 +388,6 @@ export const useQueryOperations: UseQueryOperations = ({
setListOfAdditionalFormulaFilters(additionalFilters);
}, [dataSource, aggregateOperator, getNewListOfAdditionalFilters]);
console.log('operators useQueryOperations', cloneDeep(operators));
return {
isTracePanelType,
isMetricsDataSource,

View File

@ -3,6 +3,7 @@
display: flex;
flex-direction: column;
height: 100%;
margin: 0 -1rem;
.ant-tabs {
height: 100%;

View File

@ -2,6 +2,7 @@
display: flex;
justify-content: space-between;
align-items: center;
padding-left: 8px;
.trace-explorer-run-query {
display: flex;
@ -54,7 +55,7 @@
background: var(--bg-ink-500);
> .ant-card-body {
padding: 8px 8px;
padding: 0;
}
border-color: var(--bg-slate-400);