mirror of
https://github.com/SigNoz/signoz.git
synced 2025-12-18 07:56:56 +00:00
feat: handle having options creation
This commit is contained in:
parent
00ce2e3034
commit
51d697c91a
@ -0,0 +1,99 @@
|
|||||||
|
import { Button, Select } from 'antd';
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
const havingOperators = [
|
||||||
|
{
|
||||||
|
label: '=',
|
||||||
|
value: '=',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '!=',
|
||||||
|
value: '!=',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '>',
|
||||||
|
value: '>',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '<',
|
||||||
|
value: '<',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '>=',
|
||||||
|
value: '>=',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '<=',
|
||||||
|
value: '<=',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'IN',
|
||||||
|
value: 'IN',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'NOT_IN',
|
||||||
|
value: 'NOT_IN',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
function HavingFilter({
|
||||||
|
selectedAggreateOptions,
|
||||||
|
onClose,
|
||||||
|
}: {
|
||||||
|
selectedAggreateOptions: { func: string; arg: string }[];
|
||||||
|
onClose: () => void;
|
||||||
|
}): JSX.Element {
|
||||||
|
const [selectedHavingOptions, setSelectedHavingOptions] = useState<string[]>(
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
const [options, setOptions] = useState<{ label: string; value: string }[]>([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const options = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < selectedAggreateOptions.length; i++) {
|
||||||
|
const opt = selectedAggreateOptions[i];
|
||||||
|
|
||||||
|
for (let j = 0; j < havingOperators.length; j++) {
|
||||||
|
const operator = havingOperators[j];
|
||||||
|
|
||||||
|
options.push({
|
||||||
|
label: `${opt.func}(${opt.arg}) ${operator.label}`,
|
||||||
|
value: `${opt.func}(${opt.arg}) ${operator.label}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('options', options);
|
||||||
|
|
||||||
|
setOptions(options);
|
||||||
|
}, [selectedAggreateOptions]);
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
'selectedHavingOptions',
|
||||||
|
selectedHavingOptions,
|
||||||
|
selectedAggreateOptions,
|
||||||
|
setSelectedHavingOptions,
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log('options', options);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="having-filter-container">
|
||||||
|
<Select
|
||||||
|
mode="multiple"
|
||||||
|
options={options}
|
||||||
|
onChange={(value): void => {
|
||||||
|
setSelectedHavingOptions(value);
|
||||||
|
}}
|
||||||
|
style={{ width: '100%' }}
|
||||||
|
/>
|
||||||
|
<Button className="close-btn periscope-btn ghost" onClick={onClose}>
|
||||||
|
Close
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default HavingFilter;
|
||||||
@ -8,6 +8,8 @@ import { useCallback, 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';
|
||||||
|
|
||||||
|
import HavingFilter from './HavingFilter/HavingFilter';
|
||||||
|
|
||||||
interface AddOn {
|
interface AddOn {
|
||||||
icon: React.ReactNode;
|
icon: React.ReactNode;
|
||||||
label: string;
|
label: string;
|
||||||
@ -46,10 +48,12 @@ function QueryAddOns({
|
|||||||
query,
|
query,
|
||||||
version,
|
version,
|
||||||
isListViewPanel,
|
isListViewPanel,
|
||||||
|
selectedAggreateOptions,
|
||||||
}: {
|
}: {
|
||||||
query: IBuilderQuery;
|
query: IBuilderQuery;
|
||||||
version: string;
|
version: string;
|
||||||
isListViewPanel: boolean;
|
isListViewPanel: boolean;
|
||||||
|
selectedAggreateOptions: { func: string; arg: string }[];
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const [selectedViews, setSelectedViews] = useState<AddOn[]>([]);
|
const [selectedViews, setSelectedViews] = useState<AddOn[]>([]);
|
||||||
|
|
||||||
@ -118,9 +122,8 @@ function QueryAddOns({
|
|||||||
)}
|
)}
|
||||||
{selectedViews.find((view) => view.key === 'having') && (
|
{selectedViews.find((view) => view.key === 'having') && (
|
||||||
<div className="add-on-content">
|
<div className="add-on-content">
|
||||||
<InputWithLabel
|
<HavingFilter
|
||||||
label="Having"
|
selectedAggreateOptions={selectedAggreateOptions}
|
||||||
placeholder="Select a field"
|
|
||||||
onClose={(): void => {
|
onClose={(): void => {
|
||||||
setSelectedViews(
|
setSelectedViews(
|
||||||
selectedViews.filter((view) => view.key !== 'having'),
|
selectedViews.filter((view) => view.key !== 'having'),
|
||||||
@ -134,7 +137,6 @@ function QueryAddOns({
|
|||||||
<InputWithLabel
|
<InputWithLabel
|
||||||
label="Limit"
|
label="Limit"
|
||||||
placeholder="Select a field"
|
placeholder="Select a field"
|
||||||
type="number"
|
|
||||||
onClose={(): void => {
|
onClose={(): void => {
|
||||||
setSelectedViews(selectedViews.filter((view) => view.key !== 'limit'));
|
setSelectedViews(selectedViews.filter((view) => view.key !== 'limit'));
|
||||||
}}
|
}}
|
||||||
|
|||||||
@ -154,7 +154,8 @@
|
|||||||
background: rgba(36, 40, 52, 1) !important;
|
background: rgba(36, 40, 52, 1) !important;
|
||||||
color: var(--bg-vanilla-100) !important;
|
color: var(--bg-vanilla-100) !important;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
padding: 2px 8px;
|
padding: 2px 4px;
|
||||||
|
margin-right: 4px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,19 +1,19 @@
|
|||||||
import './QueryAggregation.styles.scss';
|
import './QueryAggregation.styles.scss';
|
||||||
|
|
||||||
// import { Input } from 'antd';
|
|
||||||
import InputWithLabel from 'components/InputWithLabel/InputWithLabel';
|
import InputWithLabel from 'components/InputWithLabel/InputWithLabel';
|
||||||
|
|
||||||
import QueryAggregationSelect from './QueryAggregationSelect';
|
import QueryAggregationSelect from './QueryAggregationSelect';
|
||||||
|
|
||||||
function QueryAggregationOptions(): JSX.Element {
|
function QueryAggregationOptions({
|
||||||
|
onAggregationOptionsSelect,
|
||||||
|
}: {
|
||||||
|
onAggregationOptionsSelect: (value: { func: string; arg: string }[]) => void;
|
||||||
|
}): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<div className="query-aggregation-container">
|
<div className="query-aggregation-container">
|
||||||
{/* <Input
|
<QueryAggregationSelect
|
||||||
placeholder="Search aggregation options..."
|
onAggregationOptionsSelect={onAggregationOptionsSelect}
|
||||||
className="query-aggregation-options-input"
|
/>
|
||||||
/> */}
|
|
||||||
|
|
||||||
<QueryAggregationSelect />
|
|
||||||
|
|
||||||
<div className="query-aggregation-interval">
|
<div className="query-aggregation-interval">
|
||||||
<div className="query-aggregation-interval-label">every</div>
|
<div className="query-aggregation-interval-label">every</div>
|
||||||
|
|||||||
@ -110,7 +110,11 @@ function getFunctionContextAtCursor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line react/no-this-in-sfc
|
// eslint-disable-next-line react/no-this-in-sfc
|
||||||
function QueryAggregationSelect(): JSX.Element {
|
function QueryAggregationSelect({
|
||||||
|
onAggregationOptionsSelect,
|
||||||
|
}: {
|
||||||
|
onAggregationOptionsSelect: (value: { func: string; arg: string }[]) => void;
|
||||||
|
}): JSX.Element {
|
||||||
const { currentQuery } = useQueryBuilder();
|
const { currentQuery } = useQueryBuilder();
|
||||||
const queryData = currentQuery.builder.queryData[0];
|
const queryData = currentQuery.builder.queryData[0];
|
||||||
const [input, setInput] = useState('');
|
const [input, setInput] = useState('');
|
||||||
@ -142,6 +146,8 @@ function QueryAggregationSelect(): JSX.Element {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
setFunctionArgPairs(pairs);
|
setFunctionArgPairs(pairs);
|
||||||
|
onAggregationOptionsSelect(pairs);
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [input]);
|
}, [input]);
|
||||||
|
|
||||||
// Find function context for fetching suggestions
|
// Find function context for fetching suggestions
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import './QueryBuilderV2.styles.scss';
|
import './QueryBuilderV2.styles.scss';
|
||||||
|
|
||||||
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
import QueryAddOns from './QueryAddOns/QueryAddOns';
|
import QueryAddOns from './QueryAddOns/QueryAddOns';
|
||||||
import QueryAggregation from './QueryAggregation/QueryAggregation';
|
import QueryAggregation from './QueryAggregation/QueryAggregation';
|
||||||
@ -9,14 +10,25 @@ import QuerySearch from './QuerySearch/QuerySearch';
|
|||||||
function QueryBuilderV2(): JSX.Element {
|
function QueryBuilderV2(): JSX.Element {
|
||||||
const { currentQuery } = useQueryBuilder();
|
const { currentQuery } = useQueryBuilder();
|
||||||
|
|
||||||
|
const [selectedAggreateOptions, setSelectedAggreateOptions] = useState<
|
||||||
|
{ func: string; arg: string }[]
|
||||||
|
>([]);
|
||||||
|
|
||||||
|
console.log('selectedAggreateOptions', selectedAggreateOptions);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="query-builder-v2">
|
<div className="query-builder-v2">
|
||||||
<QuerySearch />
|
<QuerySearch />
|
||||||
<QueryAggregation />
|
<QueryAggregation
|
||||||
|
onAggregationOptionsSelect={(pairs): void => {
|
||||||
|
setSelectedAggreateOptions(pairs);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
<QueryAddOns
|
<QueryAddOns
|
||||||
query={currentQuery.builder.queryData[0]}
|
query={currentQuery.builder.queryData[0]}
|
||||||
version="v3"
|
version="v3"
|
||||||
isListViewPanel={false}
|
isListViewPanel={false}
|
||||||
|
selectedAggreateOptions={selectedAggreateOptions}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user