diff --git a/frontend/src/components/InputWithLabel/InputWithLabel.styles.scss b/frontend/src/components/InputWithLabel/InputWithLabel.styles.scss
index 2aaca3eb9f9c..c656fe563499 100644
--- a/frontend/src/components/InputWithLabel/InputWithLabel.styles.scss
+++ b/frontend/src/components/InputWithLabel/InputWithLabel.styles.scss
@@ -6,12 +6,11 @@
.label {
color: var(--bg-vanilla-400);
- font-size: 11px;
+ font-size: 12px;
font-style: normal;
font-weight: 500;
line-height: 18px; /* 128.571% */
letter-spacing: 0.56px;
- text-transform: uppercase;
max-width: 150px;
min-width: 120px;
@@ -61,6 +60,14 @@
border-radius: 0px 2px 2px 0px;
border: 1px solid var(--bg-slate-400);
background: var(--bg-ink-300);
+ border-top-right-radius: 0px;
+ border-bottom-right-radius: 0px;
+ }
+
+ .label {
+ border-left: none;
+ border-top-left-radius: 0px;
+ border-bottom-left-radius: 0px;
}
}
}
diff --git a/frontend/src/components/QueryBuilderV2/Metrics/MerticsAggregateSection/MetricsAggegateSection.styles.scss b/frontend/src/components/QueryBuilderV2/Metrics/MerticsAggregateSection/MetricsAggegateSection.styles.scss
new file mode 100644
index 000000000000..25995359edd6
--- /dev/null
+++ b/frontend/src/components/QueryBuilderV2/Metrics/MerticsAggregateSection/MetricsAggegateSection.styles.scss
@@ -0,0 +1,100 @@
+.metrics-aggregate-section {
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+ margin: 4px 0;
+
+ .metrics-time-aggregation-section {
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+
+ .metrics-time-aggregation-section-title {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+
+ color: var(--Slate-50, #62687c);
+ font-family: 'Geist Mono';
+ font-size: 12px;
+ font-style: normal;
+ font-weight: 500;
+ line-height: 18px; /* 150% */
+ letter-spacing: 0.48px;
+ }
+ }
+
+ .metrics-space-aggregation-section {
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+
+ .metrics-space-aggregation-section-title {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+
+ color: var(--Slate-50, #62687c);
+ font-family: 'Geist Mono';
+ font-size: 12px;
+ font-style: normal;
+ font-weight: 500;
+ line-height: 18px; /* 150% */
+ letter-spacing: 0.48px;
+ }
+ }
+
+ .metrics-aggregation-section-content {
+ display: flex;
+ flex-direction: row;
+ gap: 8px;
+
+ .metrics-aggregation-section-content-item {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+
+ .metrics-aggregation-section-content-item-label {
+ color: var(--Vanilla-400, #c0c1c3);
+ font-family: 'Geist Mono';
+ font-size: 13px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 20px; /* 142.857% */
+ letter-spacing: -0.07px;
+ }
+
+ .metrics-aggregation-section-content-item-value {
+ min-width: 320px;
+
+ .ant-select {
+ width: 100%;
+ }
+
+ .ant-select-selector {
+ border-radius: 2px;
+ border: 1.005px solid var(--Slate-400, #1d212d);
+ background: var(--Ink-300, #16181d);
+ }
+ }
+ }
+
+ .space-aggregation-select {
+ min-width: 480px !important;
+ }
+ }
+}
+
+.metrics-operators-select {
+ border-radius: 2px;
+ border: 1.005px solid var(--Slate-400, #1d212d);
+ background: var(--Ink-300, #16181d);
+
+ color: var(--Vanilla-400, #c0c1c3);
+ font-family: 'Geist Mono';
+ font-size: 13px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 20px; /* 142.857% */
+ letter-spacing: -0.07px;
+}
diff --git a/frontend/src/components/QueryBuilderV2/Metrics/MerticsAggregateSection/MetricsAggregateSection.tsx b/frontend/src/components/QueryBuilderV2/Metrics/MerticsAggregateSection/MetricsAggregateSection.tsx
new file mode 100644
index 000000000000..be25094f8168
--- /dev/null
+++ b/frontend/src/components/QueryBuilderV2/Metrics/MerticsAggregateSection/MetricsAggregateSection.tsx
@@ -0,0 +1,133 @@
+import './MetricsAggegateSection.styles.scss';
+
+import { Tooltip } from 'antd';
+import InputWithLabel from 'components/InputWithLabel/InputWithLabel';
+import { ATTRIBUTE_TYPES, PANEL_TYPES } from 'constants/queryBuilder';
+import SpaceAggregationOptions from 'container/QueryBuilder/components/SpaceAggregationOptions/SpaceAggregationOptions';
+import { GroupByFilter, OperatorsSelect } from 'container/QueryBuilder/filters';
+import { useQueryOperations } from 'hooks/queryBuilder/useQueryBuilderOperations';
+import { Info } from 'lucide-react';
+import { memo, useCallback } from 'react';
+import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
+
+const MetricsAggregateSection = memo(function MetricsAggregateSection({
+ query,
+ index,
+ version,
+}: {
+ query: IBuilderQuery;
+ index: number;
+ version: string;
+}): JSX.Element {
+ const panelType = PANEL_TYPES.LIST; // hardcoded for now
+
+ const {
+ operators,
+ spaceAggregationOptions,
+ handleChangeQueryData,
+ handleChangeOperator,
+ handleSpaceAggregationChange,
+ } = useQueryOperations({
+ index,
+ query,
+ entityVersion: version,
+ });
+
+ // console.log('operators', cloneDeep(operators));
+
+ const handleChangeGroupByKeys = useCallback(
+ (value: IBuilderQuery['groupBy']) => {
+ handleChangeQueryData('groupBy', value);
+ },
+ [handleChangeQueryData],
+ );
+
+ const disableOperatorSelector =
+ !query?.aggregateAttribute.key || query?.aggregateAttribute.key === '';
+
+ return (
+
+
+
+ AGGREGATE BY TIME{' '}
+
+
+
+
+
+
+
+
+ Align with
+
+
+
+
+
+
+
+
+
+ aggregated every
+
+
+
+
+
+
+
+
+
+
+
+ AGGREGATE LABELS
+
+
+
+
+
+
+
+
+ );
+});
+
+export default MetricsAggregateSection;
diff --git a/frontend/src/components/QueryBuilderV2/Metrics/MetricsSelect/MetricsSelect.styles.scss b/frontend/src/components/QueryBuilderV2/Metrics/MetricsSelect/MetricsSelect.styles.scss
new file mode 100644
index 000000000000..017480fffcad
--- /dev/null
+++ b/frontend/src/components/QueryBuilderV2/Metrics/MetricsSelect/MetricsSelect.styles.scss
@@ -0,0 +1,42 @@
+.metrics-select-container {
+ margin-bottom: 8px;
+
+ .ant-select-selector {
+ width: 100%;
+ border-radius: 2px;
+ border: 1px solid #1d212d !important;
+ background: #16181d;
+ color: #fff;
+ font-family: 'Geist Mono';
+ font-size: 13px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 20px; /* 142.857% */
+ min-height: 36px;
+ }
+
+ .ant-select-dropdown {
+ border-radius: 4px;
+ border: 1px solid var(--Slate-400, #1d212d);
+ background: linear-gradient(
+ 139deg,
+ rgba(18, 19, 23, 0.8) 0%,
+ rgba(18, 19, 23, 0.9) 98.68%
+ );
+ box-shadow: 4px 10px 16px 2px rgba(0, 0, 0, 0.2);
+ backdrop-filter: blur(20px);
+
+ .ant-select-item {
+ color: #fff;
+ font-family: 'Geist Mono';
+ font-size: 13px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 20px; /* 142.857% */
+
+ &:hover {
+ background: rgba(171, 189, 255, 0.04) !important;
+ }
+ }
+ }
+}
diff --git a/frontend/src/components/QueryBuilderV2/Metrics/MetricsSelect/MetricsSelect.tsx b/frontend/src/components/QueryBuilderV2/Metrics/MetricsSelect/MetricsSelect.tsx
new file mode 100644
index 000000000000..fd3b87a5e8c5
--- /dev/null
+++ b/frontend/src/components/QueryBuilderV2/Metrics/MetricsSelect/MetricsSelect.tsx
@@ -0,0 +1,28 @@
+import './MetricsSelect.styles.scss';
+
+import { AggregatorFilter } from 'container/QueryBuilder/filters';
+import { useQueryOperations } from 'hooks/queryBuilder/useQueryBuilderOperations';
+import { memo } from 'react';
+import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
+
+export const MetricsSelect = memo(function MetricsSelect({
+ query,
+ index,
+ version,
+}: {
+ query: IBuilderQuery;
+ index: number;
+ version: string;
+}): JSX.Element {
+ const { handleChangeAggregatorAttribute } = useQueryOperations({
+ index,
+ query,
+ entityVersion: version,
+ });
+
+ return (
+
+ );
+});
diff --git a/frontend/src/components/QueryBuilderV2/QueryAddOns/HavingFilter/HavingFilter.tsx b/frontend/src/components/QueryBuilderV2/QueryAddOns/HavingFilter/HavingFilter.tsx
index c78eaee13446..5e345c321ce6 100644
--- a/frontend/src/components/QueryBuilderV2/QueryAddOns/HavingFilter/HavingFilter.tsx
+++ b/frontend/src/components/QueryBuilderV2/QueryAddOns/HavingFilter/HavingFilter.tsx
@@ -9,7 +9,9 @@ import {
import { javascript } from '@codemirror/lang-javascript';
import { copilot } from '@uiw/codemirror-theme-copilot';
import CodeMirror, { EditorView, keymap } from '@uiw/react-codemirror';
+import { Button } from 'antd';
import { useQueryBuilderV2Context } from 'components/QueryBuilderV2/QueryBuilderV2Context';
+import { X } from 'lucide-react';
import { useEffect, useMemo, useRef, useState } from 'react';
const havingOperators = [
@@ -52,7 +54,7 @@ const conjunctions = [
{ label: 'OR', value: 'OR' },
];
-function HavingFilter(): JSX.Element {
+function HavingFilter({ onClose }: { onClose: () => void }): JSX.Element {
const { aggregationOptions } = useQueryBuilderV2Context();
const [input, setInput] = useState('');
@@ -170,6 +172,11 @@ function HavingFilter(): JSX.Element {
}}
ref={editorRef}
/>
+ }
+ onClick={onClose}
+ />
);
diff --git a/frontend/src/components/QueryBuilderV2/QueryAggregation/QueryAggregation.styles.scss b/frontend/src/components/QueryBuilderV2/QueryAggregation/QueryAggregation.styles.scss
index 5025c4677c81..9e9d389d6442 100644
--- a/frontend/src/components/QueryBuilderV2/QueryAggregation/QueryAggregation.styles.scss
+++ b/frontend/src/components/QueryBuilderV2/QueryAggregation/QueryAggregation.styles.scss
@@ -30,9 +30,13 @@
.query-aggregation-select-container {
width: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
.query-aggregation-select-editor {
border-radius: 2px;
+ flex: 1;
.cm-content {
padding: 0;
@@ -50,6 +54,8 @@
.cm-content {
border-radius: 2px;
border: 1px solid var(--Slate-400, #1d212d);
+ border-top-right-radius: 0px;
+ border-bottom-right-radius: 0px;
padding: 0px !important;
background-color: #121317 !important;
@@ -168,4 +174,16 @@
}
}
}
+
+ .close-btn {
+ border-radius: 0px 2px 2px 0px;
+ border: 1px solid var(--bg-slate-400);
+ background: var(--bg-ink-300);
+ height: 38px;
+ width: 38px;
+
+ border-left: none;
+ border-top-left-radius: 0px;
+ border-bottom-left-radius: 0px;
+ }
}
diff --git a/frontend/src/components/QueryBuilderV2/QueryAggregation/QueryAggregation.tsx b/frontend/src/components/QueryBuilderV2/QueryAggregation/QueryAggregation.tsx
index 3e4ced461143..af710ac80eaf 100644
--- a/frontend/src/components/QueryBuilderV2/QueryAggregation/QueryAggregation.tsx
+++ b/frontend/src/components/QueryBuilderV2/QueryAggregation/QueryAggregation.tsx
@@ -1,10 +1,17 @@
import './QueryAggregation.styles.scss';
import InputWithLabel from 'components/InputWithLabel/InputWithLabel';
+import { DataSource } from 'types/common/queryBuilder';
import QueryAggregationSelect from './QueryAggregationSelect';
-function QueryAggregationOptions(): JSX.Element {
+function QueryAggregationOptions({
+ source,
+}: {
+ source: DataSource;
+}): JSX.Element {
+ console.log('source', source);
+
return (
diff --git a/frontend/src/components/QueryBuilderV2/QueryBuilderV2.tsx b/frontend/src/components/QueryBuilderV2/QueryBuilderV2.tsx
index c9068ee12194..7fa64fa20a3b 100644
--- a/frontend/src/components/QueryBuilderV2/QueryBuilderV2.tsx
+++ b/frontend/src/components/QueryBuilderV2/QueryBuilderV2.tsx
@@ -1,32 +1,51 @@
import './QueryBuilderV2.styles.scss';
-import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
+import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
+import { DataSource } from 'types/common/queryBuilder';
+import MetricsAggregateSection from './Metrics/MerticsAggregateSection/MetricsAggregateSection';
+import { MetricsSelect } from './Metrics/MetricsSelect/MetricsSelect';
import QueryAddOns from './QueryAddOns/QueryAddOns';
import QueryAggregation from './QueryAggregation/QueryAggregation';
import { QueryBuilderV2Provider } from './QueryBuilderV2Context';
import QuerySearch from './QuerySearch/QuerySearch';
-function QueryBuilderV2Main(): JSX.Element {
- const { currentQuery } = useQueryBuilder();
+type QueryBuilderV2Props = {
+ source: DataSource;
+ query: IBuilderQuery;
+};
+
+function QueryBuilderV2Main({
+ source,
+ query,
+}: QueryBuilderV2Props): JSX.Element {
+ const isMetricsDataSource = query.dataSource === DataSource.METRICS;
return (
+ {isMetricsDataSource && (
+
+ )}
+
-
-
+
+ {isMetricsDataSource ? (
+
+ ) : (
+
+ )}
+
+
);
}
-function QueryBuilderV2(): JSX.Element {
+function QueryBuilderV2(props: QueryBuilderV2Props): JSX.Element {
+ const { source, query } = props;
+
return (
-
+
);
}
diff --git a/frontend/src/components/QueryBuilderV2/QuerySearch/QuerySearch.styles.scss b/frontend/src/components/QueryBuilderV2/QuerySearch/QuerySearch.styles.scss
index 0b86084e4f2e..6b4fb3f0444d 100644
--- a/frontend/src/components/QueryBuilderV2/QuerySearch/QuerySearch.styles.scss
+++ b/frontend/src/components/QueryBuilderV2/QuerySearch/QuerySearch.styles.scss
@@ -1,6 +1,5 @@
.code-mirror-where-clause {
width: 100%;
- height: 100%;
display: flex;
flex-direction: column;
gap: 8px;
diff --git a/frontend/src/container/LogExplorerQuerySection/index.tsx b/frontend/src/container/LogExplorerQuerySection/index.tsx
index 7ccd9f9e6e5e..86d1b8dc5ef0 100644
--- a/frontend/src/container/LogExplorerQuerySection/index.tsx
+++ b/frontend/src/container/LogExplorerQuerySection/index.tsx
@@ -109,7 +109,9 @@ function LogExplorerQuerySection({
/>
)}
- {selectedView === SELECTED_VIEWS.QUERY_BUILDER_V2 &&
}
+ {selectedView === SELECTED_VIEWS.QUERY_BUILDER_V2 && (
+
+ )}
>
);
}
diff --git a/frontend/src/container/MetricsExplorer/Explorer/Explorer.tsx b/frontend/src/container/MetricsExplorer/Explorer/Explorer.tsx
index d20b18dc0ee5..248c41499dff 100644
--- a/frontend/src/container/MetricsExplorer/Explorer/Explorer.tsx
+++ b/frontend/src/container/MetricsExplorer/Explorer/Explorer.tsx
@@ -3,6 +3,7 @@ import './Explorer.styles.scss';
import * as Sentry from '@sentry/react';
import { Switch } from 'antd';
import logEvent from 'api/common/logEvent';
+import QueryBuilderV2 from 'components/QueryBuilderV2/QueryBuilderV2';
import { initialQueriesMap, PANEL_TYPES } from 'constants/queryBuilder';
import ExplorerOptionWrapper from 'container/ExplorerOptions/ExplorerOptionWrapper';
import RightToolbarActions from 'container/QueryBuilder/components/ToolbarActions/RightToolbarActions';
@@ -20,7 +21,7 @@ import { generateExportToDashboardLink } from 'utils/dashboard/generateExportToD
import { v4 as uuid } from 'uuid';
import { MetricsExplorerEventKeys, MetricsExplorerEvents } from '../events';
-import QuerySection from './QuerySection';
+// import QuerySection from './QuerySection';
import TimeSeries from './TimeSeries';
import { ExplorerTabs } from './types';
import { splitQueryIntoOneChartPerQuery } from './utils';
@@ -118,7 +119,11 @@ function Explorer(): JSX.Element {
-
+ {/* */}
+
{/* TODO: Enable once we have resolved all related metrics issues */}
{/*