feat: added span selector

This commit is contained in:
ahrefabhi 2025-08-21 01:27:58 +05:30
parent b574fee2d4
commit aa1dfc6eb1
2 changed files with 142 additions and 32 deletions

View File

@ -25,6 +25,32 @@
} }
} }
&-span-source-label {
display: flex;
align-items: center;
gap: 8px;
height: 24px;
&-query {
font-size: 14px;
font-weight: 400;
color: var(--bg-vanilla-100);
}
&-query-name {
width: 18px;
height: 18px;
display: grid;
place-content: center;
padding: 2px;
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-size: 12px;
}
}
&-arrow { &-arrow {
position: relative; position: relative;
&::before { &::before {
@ -83,6 +109,13 @@
&-add-ons-input { &-add-ons-input {
position: relative; position: relative;
display: flex;
align-items: center;
flex-direction: row;
border-radius: 2px;
border: 1px solid var(--bg-slate-400);
background: var(--bg-ink-300);
&::before { &::before {
content: ''; content: '';
@ -93,5 +126,55 @@
width: 16px; width: 16px;
background-color: var(--bg-slate-400); background-color: var(--bg-slate-400);
} }
.label {
color: var(--bg-vanilla-400);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding: 0px 8px;
border-right: 1px solid var(--bg-slate-400);
}
}
}
.lightMode {
.qb-trace-operator {
&-arrow {
&::before {
background: repeating-linear-gradient(
to right,
var(--bg-vanilla-300),
var(--bg-vanilla-300) 4px,
transparent 4px,
transparent 8px
);
}
&::after {
background-color: var(--bg-vanilla-300);
}
}
&.non-list-view {
&::before {
background: repeating-linear-gradient(
to bottom,
var(--bg-vanilla-300),
var(--bg-vanilla-300) 4px,
transparent 4px,
transparent 8px
);
}
}
&-add-ons-input {
border: 1px solid var(--bg-vanilla-300) !important;
background: var(--bg-vanilla-100) !important;
.label {
color: var(--bg-ink-500) !important;
border-right: 1px solid var(--bg-vanilla-300) !important;
background: var(--bg-vanilla-100) !important;
}
}
} }
} }

View File

@ -5,62 +5,87 @@ import InputWithLabel from 'components/InputWithLabel/InputWithLabel';
import cx from 'classnames'; import cx from 'classnames';
import './TraceOperator.styles.scss'; import './TraceOperator.styles.scss';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder'; import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { useCallback } from 'react'; import { useCallback, useMemo } from 'react';
import { import {
IBuilderQuery, IBuilderQuery,
IBuilderTraceOperator, IBuilderTraceOperator,
} from 'types/api/queryBuilder/queryBuilderData'; } from 'types/api/queryBuilder/queryBuilderData';
import QueryAddOns from '../QueryAddOns/QueryAddOns'; import QueryAddOns from '../QueryAddOns/QueryAddOns';
import QueryAggregation from '../QueryAggregation/QueryAggregation'; import QueryAggregation from '../QueryAggregation/QueryAggregation';
import { useTraceOperatorOperations } from 'hooks/queryBuilder/userTraceOperatorOperations'; import { Button, Select, Tooltip, Typography } from 'antd';
import { Button, Tooltip } from 'antd';
import { Trash2 } from 'lucide-react'; import { Trash2 } from 'lucide-react';
import { DataSource } from 'types/common/queryBuilder';
import { useQueryOperations } from 'hooks/queryBuilder/useQueryBuilderOperations';
export default function TraceOperator({ export default function TraceOperator({
traceOperator, traceOperator,
isListViewPanel = false, isListViewPanel = false,
}: { }: {
traceOperator: IBuilderTraceOperator | undefined; traceOperator: IBuilderTraceOperator;
isListViewPanel?: boolean; isListViewPanel?: boolean;
}): JSX.Element { }): JSX.Element {
const { panelType, currentQuery, removeTraceOperator } = useQueryBuilder(); const { panelType, currentQuery, removeTraceOperator } = useQueryBuilder();
const { handleChangeTraceOperatorData } = useTraceOperatorOperations({ const { handleChangeQueryData } = useQueryOperations({
index: 0, index: 0,
query: traceOperator, query: traceOperator,
entityVersion: '',
isForTraceOperator: true,
}); });
const handleTraceOperatorChange = useCallback( const handleTraceOperatorChange = useCallback(
(traceOperatorExpression: string) => { (traceOperatorExpression: string) => {
handleChangeTraceOperatorData('expression', traceOperatorExpression); handleChangeQueryData('expression', traceOperatorExpression);
}, },
[handleChangeTraceOperatorData], [handleChangeQueryData],
); );
const handleChangeAggregateEvery = useCallback( const handleChangeAggregateEvery = useCallback(
(value: IBuilderQuery['stepInterval']) => { (value: IBuilderQuery['stepInterval']) => {
handleChangeTraceOperatorData('stepInterval', value); handleChangeQueryData('stepInterval', value);
}, },
[handleChangeTraceOperatorData], [handleChangeQueryData],
); );
const handleChangeAggregation = useCallback( const handleChangeAggregation = useCallback(
(value: string) => { (value: string) => {
handleChangeTraceOperatorData('aggregations', [ handleChangeQueryData('aggregations', [
{ {
expression: value, expression: value,
}, },
]); ]);
}, },
[handleChangeTraceOperatorData], [handleChangeQueryData],
); );
const handleChangeSpanSource = useCallback( const handleChangeSpanSource = useCallback(
(value: string) => { (value: string) => {
handleChangeTraceOperatorData('returnSpansFrom', value); handleChangeQueryData('returnSpansFrom', value);
}, },
[handleChangeTraceOperatorData], [handleChangeQueryData],
); );
const defaultSpanSource = useMemo(() => {
return (
traceOperator.returnSpansFrom ||
currentQuery.builder.queryData[0].queryName ||
''
);
}, [currentQuery.builder.queryData, traceOperator?.returnSpansFrom]);
const spanSourceOptions = useMemo(() => {
return currentQuery.builder.queryData.map((query) => ({
value: query.queryName,
label: (
<div className="qb-trace-operator-span-source-label">
<span className="qb-trace-operator-span-source-label-query">Query</span>
<p className="qb-trace-operator-span-source-label-query-name">
{query.queryName}
</p>
</div>
),
}));
}, [currentQuery.builder.queryData]);
return ( return (
<div className={cx('qb-trace-operator', !isListViewPanel && 'non-list-view')}> <div className={cx('qb-trace-operator', !isListViewPanel && 'non-list-view')}>
<div className="qb-trace-operator-container"> <div className="qb-trace-operator-container">
@ -79,12 +104,12 @@ export default function TraceOperator({
<div className="qb-trace-operator-aggregation-container"> <div className="qb-trace-operator-aggregation-container">
<div className={cx(!isListViewPanel && 'qb-trace-operator-arrow')}> <div className={cx(!isListViewPanel && 'qb-trace-operator-arrow')}>
<QueryAggregation <QueryAggregation
dataSource={currentQuery.builder.queryData[0].dataSource} dataSource={DataSource.TRACES}
key={`query-search-${currentQuery.builder.queryData[0].queryName}-${currentQuery.builder.queryData[0].dataSource}`} key={`query-search-${traceOperator.queryName}`}
panelType={panelType || undefined} panelType={panelType || undefined}
onAggregationIntervalChange={handleChangeAggregateEvery} onAggregationIntervalChange={handleChangeAggregateEvery}
onChange={handleChangeAggregation} onChange={handleChangeAggregation}
queryData={currentQuery.builder.queryData[0]} //TODO: replace this with the traceoperator queryData={traceOperator}
/> />
</div> </div>
<div <div
@ -95,32 +120,34 @@ export default function TraceOperator({
> >
<QueryAddOns <QueryAddOns
index={0} index={0}
query={currentQuery.builder.queryData[0]} //TODO: replace this with the traceoperator query={traceOperator} //TODO: replace this with the traceoperator
version="v3" version="v3"
isForTraceOperator={true}
isListViewPanel={false} isListViewPanel={false}
showReduceTo={false} showReduceTo={false}
panelType={panelType} panelType={panelType}
> >
<InputWithLabel <div className="qb-trace-operator-add-ons-input">
className="qb-trace-operator-add-ons-input" <Typography.Text className="label">Using spans from</Typography.Text>
initialValue={traceOperator?.expression || ''} <Select
label="Using spans from" bordered={false}
placeholder="Add condition..." defaultValue={defaultSpanSource}
type="text" style={{ minWidth: 120 }}
onChange={handleChangeSpanSource} onChange={handleChangeSpanSource}
options={spanSourceOptions}
listItemHeight={24}
/> />
</div>
</QueryAddOns> </QueryAddOns>
</div> </div>
</div> </div>
)} )}
</div> </div>
{true && (
<Tooltip title="Remove Trace Operator" placement="topLeft"> <Tooltip title="Remove Trace Operator" placement="topLeft">
<Button className="periscope-btn ghost" onClick={removeTraceOperator}> <Button className="periscope-btn ghost" onClick={removeTraceOperator}>
<Trash2 size={14} /> <Trash2 size={14} />
</Button> </Button>
</Tooltip> </Tooltip>
)}
</div> </div>
); );
} }