feat: handle having options creation

This commit is contained in:
Yunus M 2025-05-14 16:16:34 +05:30 committed by SagarRajput-7
parent 00ce2e3034
commit 51d697c91a
6 changed files with 135 additions and 15 deletions

View File

@ -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;

View File

@ -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'));
}} }}

View File

@ -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;
} }
} }

View File

@ -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>

View File

@ -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

View File

@ -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>
); );