diff --git a/frontend/public/locales/en-GB/dashboard.json b/frontend/public/locales/en-GB/dashboard.json index 6179004aff..bc7969d053 100644 --- a/frontend/public/locales/en-GB/dashboard.json +++ b/frontend/public/locales/en-GB/dashboard.json @@ -25,5 +25,5 @@ "dashboard_unsave_changes": "There are unsaved changes in the Query builder, please stage and run the query or the changes will be lost. Press OK to discard.", "dashboard_save_changes": "Your graph built with {{queryTag}} query will be saved. Press OK to confirm.", "your_graph_build_with": "Your graph built with", - "dashboar_ok_confirm": "query will be saved. Press OK to confirm." + "dashboard_ok_confirm": "query will be saved. Press OK to confirm." } diff --git a/frontend/public/locales/en/dashboard.json b/frontend/public/locales/en/dashboard.json index a74f23d228..9c0529cd73 100644 --- a/frontend/public/locales/en/dashboard.json +++ b/frontend/public/locales/en/dashboard.json @@ -28,5 +28,5 @@ "dashboard_unsave_changes": "There are unsaved changes in the Query builder, please stage and run the query or the changes will be lost. Press OK to discard.", "dashboard_save_changes": "Your graph built with {{queryTag}} query will be saved. Press OK to confirm.", "your_graph_build_with": "Your graph built with", - "dashboar_ok_confirm": "query will be saved. Press OK to confirm." + "dashboard_ok_confirm": "query will be saved. Press OK to confirm." } diff --git a/frontend/src/api/apiV1.ts b/frontend/src/api/apiV1.ts index 2e7df02395..4fba137e18 100644 --- a/frontend/src/api/apiV1.ts +++ b/frontend/src/api/apiV1.ts @@ -2,6 +2,7 @@ const apiV1 = '/api/v1/'; export const apiV2 = '/api/v2/'; export const apiV3 = '/api/v3/'; +export const apiV4 = '/api/v4/'; export const apiAlertManager = '/api/alertmanager'; export default apiV1; diff --git a/frontend/src/api/index.ts b/frontend/src/api/index.ts index bde915f201..92a06363a1 100644 --- a/frontend/src/api/index.ts +++ b/frontend/src/api/index.ts @@ -9,7 +9,7 @@ import { ENVIRONMENT } from 'constants/env'; import { LOCALSTORAGE } from 'constants/localStorage'; import store from 'store'; -import apiV1, { apiAlertManager, apiV2, apiV3 } from './apiV1'; +import apiV1, { apiAlertManager, apiV2, apiV3, apiV4 } from './apiV1'; import { Logout } from './utils'; const interceptorsResponse = ( @@ -114,6 +114,7 @@ ApiV2Instance.interceptors.request.use(interceptorsRequestResponse); export const ApiV3Instance = axios.create({ baseURL: `${ENVIRONMENT.baseURL}${apiV3}`, }); + ApiV3Instance.interceptors.response.use( interceptorsResponse, interceptorRejected, @@ -121,6 +122,18 @@ ApiV3Instance.interceptors.response.use( ApiV3Instance.interceptors.request.use(interceptorsRequestResponse); // +// axios V4 +export const ApiV4Instance = axios.create({ + baseURL: `${ENVIRONMENT.baseURL}${apiV4}`, +}); + +ApiV4Instance.interceptors.response.use( + interceptorsResponse, + interceptorRejected, +); +ApiV4Instance.interceptors.request.use(interceptorsRequestResponse); +// + AxiosAlertManagerInstance.interceptors.response.use( interceptorsResponse, interceptorRejected, diff --git a/frontend/src/api/metrics/getQueryRange.ts b/frontend/src/api/metrics/getQueryRange.ts index 984d381e10..a33cedee95 100644 --- a/frontend/src/api/metrics/getQueryRange.ts +++ b/frontend/src/api/metrics/getQueryRange.ts @@ -1,4 +1,4 @@ -import { ApiV3Instance as axios } from 'api'; +import { ApiV3Instance, ApiV4Instance } from 'api'; import { ErrorResponseHandler } from 'api/ErrorResponseHandler'; import { AxiosError } from 'axios'; import { ErrorResponse, SuccessResponse } from 'types/api'; @@ -9,10 +9,23 @@ import { export const getMetricsQueryRange = async ( props: QueryRangePayload, + version: string, signal: AbortSignal, ): Promise | ErrorResponse> => { try { - const response = await axios.post('/query_range', props, { signal }); + if (version && version === 'v4') { + const response = await ApiV4Instance.post('/query_range', props, { signal }); + + return { + statusCode: 200, + error: null, + message: response.data.status, + payload: response.data, + params: props, + }; + } + + const response = await ApiV3Instance.post('/query_range', props, { signal }); return { statusCode: 200, diff --git a/frontend/src/components/LogsFormatOptionsMenu/LogsFormatOptionsMenu.tsx b/frontend/src/components/LogsFormatOptionsMenu/LogsFormatOptionsMenu.tsx index dcfa88325e..558a97c63b 100644 --- a/frontend/src/components/LogsFormatOptionsMenu/LogsFormatOptionsMenu.tsx +++ b/frontend/src/components/LogsFormatOptionsMenu/LogsFormatOptionsMenu.tsx @@ -72,8 +72,6 @@ export default function LogsFormatOptionsMenu({ setAddNewColumn(!addNewColumn); }; - // console.log('optionsMenuConfig', config); - const handleLinesPerRowChange = (maxLinesPerRow: number | null): void => { if ( maxLinesPerRow && @@ -221,8 +219,6 @@ export default function LogsFormatOptionsMenu({ className="column-name" key={value} onClick={(eve): void => { - console.log('coluimn name', label, value); - eve.stopPropagation(); if (addColumn && addColumn?.onSelect) { diff --git a/frontend/src/constants/app.ts b/frontend/src/constants/app.ts index 8529db4e4d..3b7b0fc960 100644 --- a/frontend/src/constants/app.ts +++ b/frontend/src/constants/app.ts @@ -13,3 +13,5 @@ export const SIGNOZ_UPGRADE_PLAN_URL = 'https://upgrade.signoz.io/upgrade-from-app'; export const DASHBOARD_TIME_IN_DURATION = 'refreshInterval'; + +export const DEFAULT_ENTITY_VERSION = 'v3'; diff --git a/frontend/src/constants/queryBuilder.ts b/frontend/src/constants/queryBuilder.ts index 936bfccdde..0999b634ba 100644 --- a/frontend/src/constants/queryBuilder.ts +++ b/frontend/src/constants/queryBuilder.ts @@ -36,6 +36,11 @@ import { v4 as uuid } from 'uuid'; import { logsAggregateOperatorOptions, metricAggregateOperatorOptions, + metricsGaugeAggregateOperatorOptions, + metricsGaugeSpaceAggregateOperatorOptions, + metricsHistogramSpaceAggregateOperatorOptions, + metricsSumAggregateOperatorOptions, + metricsSumSpaceAggregateOperatorOptions, tracesAggregateOperatorOptions, } from './queryBuilderOperators'; @@ -74,6 +79,18 @@ export const mapOfOperators = { traces: tracesAggregateOperatorOptions, }; +export const metricsOperatorsByType = { + Sum: metricsSumAggregateOperatorOptions, + Gauge: metricsGaugeAggregateOperatorOptions, +}; + +export const metricsSpaceAggregationOperatorsByType = { + Sum: metricsSumSpaceAggregateOperatorOptions, + Gauge: metricsGaugeSpaceAggregateOperatorOptions, + Histogram: metricsHistogramSpaceAggregateOperatorOptions, + ExponentialHistogram: metricsHistogramSpaceAggregateOperatorOptions, +}; + export const mapOfQueryFilters: Record = { metrics: [ // eslint-disable-next-line sonarjs/no-duplicate-string @@ -148,6 +165,9 @@ export const initialQueryBuilderFormValues: IBuilderQuery = { queryName: createNewBuilderItemName({ existNames: [], sourceNames: alphabet }), aggregateOperator: MetricAggregateOperator.COUNT, aggregateAttribute: initialAutocompleteData, + timeAggregation: MetricAggregateOperator.RATE, + spaceAggregation: MetricAggregateOperator.SUM, + functions: [], filters: { items: [], op: 'AND' }, expression: createNewBuilderItemName({ existNames: [], @@ -160,7 +180,7 @@ export const initialQueryBuilderFormValues: IBuilderQuery = { orderBy: [], groupBy: [], legend: '', - reduceTo: 'sum', + reduceTo: 'avg', }; const initialQueryBuilderFormLogsValues: IBuilderQuery = { @@ -268,6 +288,14 @@ export enum PANEL_TYPES { EMPTY_WIDGET = 'EMPTY_WIDGET', } +// eslint-disable-next-line @typescript-eslint/naming-convention +export enum ATTRIBUTE_TYPES { + SUM = 'Sum', + GAUGE = 'Gauge', + HISTOGRAM = 'Histogram', + EXPONENTIAL_HISTOGRAM = 'ExponentialHistogram', +} + export type IQueryBuilderState = 'search'; export const QUERY_BUILDER_SEARCH_VALUES = { diff --git a/frontend/src/constants/queryBuilderOperators.ts b/frontend/src/constants/queryBuilderOperators.ts index 7c5cff2b69..581d517875 100644 --- a/frontend/src/constants/queryBuilderOperators.ts +++ b/frontend/src/constants/queryBuilderOperators.ts @@ -302,3 +302,126 @@ export const logsAggregateOperatorOptions: SelectOption[] = [ label: 'Rate_max', }, ]; + +export const metricsSumAggregateOperatorOptions: SelectOption< + string, + string +>[] = [ + { + value: MetricAggregateOperator.RATE, + label: 'Rate', + }, + { + value: MetricAggregateOperator.INCREASE, + label: 'Increase', + }, +]; + +export const metricsGaugeAggregateOperatorOptions: SelectOption< + string, + string +>[] = [ + { + value: MetricAggregateOperator.LATEST, + label: 'Latest', + }, + { + value: MetricAggregateOperator.SUM, + label: 'Sum', + }, + { + value: MetricAggregateOperator.AVG, + label: 'Avg', + }, + { + value: MetricAggregateOperator.MIN, + label: 'Min', + }, + { + value: MetricAggregateOperator.MAX, + label: 'Max', + }, + { + value: MetricAggregateOperator.COUNT, + label: 'Count', + }, + { + value: MetricAggregateOperator.COUNT_DISTINCT, + label: 'Count Distinct', + }, +]; + +export const metricsSumSpaceAggregateOperatorOptions: SelectOption< + string, + string +>[] = [ + { + value: MetricAggregateOperator.SUM, + label: 'Sum', + }, + { + value: MetricAggregateOperator.AVG, + label: 'Avg', + }, + { + value: MetricAggregateOperator.MIN, + label: 'Min', + }, + { + value: MetricAggregateOperator.MAX, + label: 'Max', + }, +]; + +export const metricsGaugeSpaceAggregateOperatorOptions: SelectOption< + string, + string +>[] = [ + { + value: MetricAggregateOperator.SUM, + label: 'Sum', + }, + { + value: MetricAggregateOperator.AVG, + label: 'Avg', + }, + { + value: MetricAggregateOperator.MIN, + label: 'Min', + }, + { + value: MetricAggregateOperator.MAX, + label: 'Max', + }, +]; + +export const metricsHistogramSpaceAggregateOperatorOptions: SelectOption< + string, + string +>[] = [ + { + value: MetricAggregateOperator.P50, + label: 'P50', + }, + { + value: MetricAggregateOperator.P75, + label: 'P75', + }, + { + value: MetricAggregateOperator.P90, + label: 'P90', + }, + { + value: MetricAggregateOperator.P95, + label: 'P95', + }, + { + value: MetricAggregateOperator.P99, + label: 'P99', + }, +]; + +export const metricsEmptyTimeAggregateOperatorOptions: SelectOption< + string, + string +>[] = []; diff --git a/frontend/src/constants/queryFunctionOptions.ts b/frontend/src/constants/queryFunctionOptions.ts new file mode 100644 index 0000000000..b79f673c46 --- /dev/null +++ b/frontend/src/constants/queryFunctionOptions.ts @@ -0,0 +1,137 @@ +/* eslint-disable sonarjs/no-duplicate-string */ +import { QueryFunctionsTypes } from 'types/common/queryBuilder'; +import { SelectOption } from 'types/common/select'; + +export const queryFunctionOptions: SelectOption[] = [ + { + value: QueryFunctionsTypes.CUTOFF_MIN, + label: 'Cut Off Min', + }, + { + value: QueryFunctionsTypes.CUTOFF_MAX, + label: 'Cut Off Max', + }, + { + value: QueryFunctionsTypes.CLAMP_MIN, + label: 'Clamp Min', + }, + { + value: QueryFunctionsTypes.CLAMP_MAX, + label: 'Clamp Max', + }, + { + value: QueryFunctionsTypes.ABSOLUTE, + label: 'Absolute', + }, + { + value: QueryFunctionsTypes.LOG_2, + label: 'Log2', + }, + { + value: QueryFunctionsTypes.LOG_10, + label: 'Log10', + }, + { + value: QueryFunctionsTypes.CUMULATIVE_SUM, + label: 'Cumulative Sum', + }, + { + value: QueryFunctionsTypes.EWMA_3, + label: 'EWMA 3', + }, + { + value: QueryFunctionsTypes.EWMA_5, + label: 'EWMA 5', + }, + { + value: QueryFunctionsTypes.EWMA_7, + label: 'EWMA 7', + }, + { + value: QueryFunctionsTypes.MEDIAN_3, + label: 'Median 3', + }, + { + value: QueryFunctionsTypes.MEDIAN_5, + label: 'Median 5', + }, + { + value: QueryFunctionsTypes.MEDIAN_7, + label: 'Median 7', + }, + { + value: QueryFunctionsTypes.TIME_SHIFT, + label: 'Time Shift', + }, +]; + +interface QueryFunctionConfigType { + [key: string]: { + showInput: boolean; + inputType?: string; + placeholder?: string; + }; +} + +export const queryFunctionsTypesConfig: QueryFunctionConfigType = { + cutOffMin: { + showInput: true, + inputType: 'text', + placeholder: 'Threshold', + }, + cutOffMax: { + showInput: true, + inputType: 'text', + placeholder: 'Threshold', + }, + clampMin: { + showInput: true, + inputType: 'text', + placeholder: 'Threshold', + }, + clampMax: { + showInput: true, + inputType: 'text', + placeholder: 'Threshold', + }, + absolute: { + showInput: false, + }, + log2: { + showInput: false, + }, + log10: { + showInput: false, + }, + cumSum: { + showInput: false, + }, + ewma3: { + showInput: true, + inputType: 'text', + placeholder: 'Alpha', + }, + ewma5: { + showInput: true, + inputType: 'text', + placeholder: 'Alpha', + }, + ewma7: { + showInput: true, + inputType: 'text', + placeholder: 'Alpha', + }, + median3: { + showInput: false, + }, + median5: { + showInput: false, + }, + median7: { + showInput: false, + }, + timeShift: { + showInput: true, + inputType: 'text', + }, +}; diff --git a/frontend/src/constants/shortcuts/DashboardShortcuts.ts b/frontend/src/constants/shortcuts/DashboardShortcuts.ts new file mode 100644 index 0000000000..ee861708f7 --- /dev/null +++ b/frontend/src/constants/shortcuts/DashboardShortcuts.ts @@ -0,0 +1,17 @@ +import { getUserOperatingSystem, UserOperatingSystem } from 'utils/getUserOS'; + +const userOS = getUserOperatingSystem(); + +export const DashboardShortcuts = { + SaveChanges: 's+meta', + DiscardChanges: 'd+meta', +}; + +export const DashboardShortcutsName = { + SaveChanges: `${userOS === UserOperatingSystem.MACOS ? 'cmd' : 'ctrl'}+s`, +}; + +export const DashboardShortcutsDescription = { + SaveChanges: 'Save Changes', + DiscardChanges: 'Discard Changes', +}; diff --git a/frontend/src/constants/shortcuts/QBShortcuts.ts b/frontend/src/constants/shortcuts/QBShortcuts.ts new file mode 100644 index 0000000000..56fea081df --- /dev/null +++ b/frontend/src/constants/shortcuts/QBShortcuts.ts @@ -0,0 +1,17 @@ +import { getUserOperatingSystem, UserOperatingSystem } from 'utils/getUserOS'; + +const userOS = getUserOperatingSystem(); + +export const QBShortcuts = { + StageAndRunQuery: 'enter+meta', +}; + +export const QBShortcutsName = { + StageAndRunQuery: `${ + userOS === UserOperatingSystem.MACOS ? 'cmd' : 'ctrl' + }+enter`, +}; + +export const QBShortcutsDescription = { + StageAndRunQuery: 'Stage and Run the query', +}; diff --git a/frontend/src/container/CreateAlertRule/defaults.ts b/frontend/src/container/CreateAlertRule/defaults.ts index 8517d9b18c..fd998c1035 100644 --- a/frontend/src/container/CreateAlertRule/defaults.ts +++ b/frontend/src/container/CreateAlertRule/defaults.ts @@ -25,6 +25,7 @@ const defaultAnnotations = { export const alertDefaults: AlertDef = { alertType: AlertTypes.METRICS_BASED_ALERT, + version: 'v4', condition: { compositeQuery: { builderQueries: { diff --git a/frontend/src/container/CreateAlertRule/index.tsx b/frontend/src/container/CreateAlertRule/index.tsx index 9ce1634d13..0a0aa6dfeb 100644 --- a/frontend/src/container/CreateAlertRule/index.tsx +++ b/frontend/src/container/CreateAlertRule/index.tsx @@ -2,6 +2,7 @@ import { Form, Row } from 'antd'; import FormAlertRules from 'container/FormAlertRules'; import { useGetCompositeQueryParam } from 'hooks/queryBuilder/useGetCompositeQueryParam'; import { useEffect, useState } from 'react'; +import { useLocation } from 'react-router-dom'; import { AlertTypes } from 'types/api/alerts/alertTypes'; import { AlertDef } from 'types/api/alerts/def'; @@ -20,6 +21,10 @@ function CreateRules(): JSX.Element { AlertTypes.METRICS_BASED_ALERT, ); + const location = useLocation(); + const queryParams = new URLSearchParams(location.search); + const version = queryParams.get('version'); + const compositeQuery = useGetCompositeQueryParam(); const [formInstance] = Form.useForm(); @@ -37,7 +42,10 @@ function CreateRules(): JSX.Element { setInitValues(exceptionAlertDefaults); break; default: - setInitValues(alertDefaults); + setInitValues({ + ...alertDefaults, + version: version || 'v3', + }); } }; @@ -52,6 +60,7 @@ function CreateRules(): JSX.Element { if (alertType) { onSelectType(alertType); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [compositeQuery]); if (!initValues) { diff --git a/frontend/src/container/FormAlertRules/ChartPreview/index.tsx b/frontend/src/container/FormAlertRules/ChartPreview/index.tsx index 9df51314d0..59dd78e96b 100644 --- a/frontend/src/container/FormAlertRules/ChartPreview/index.tsx +++ b/frontend/src/container/FormAlertRules/ChartPreview/index.tsx @@ -1,5 +1,6 @@ import { InfoCircleOutlined } from '@ant-design/icons'; import Spinner from 'components/Spinner'; +import { DEFAULT_ENTITY_VERSION } from 'constants/app'; import { initialQueriesMap, PANEL_TYPES } from 'constants/queryBuilder'; import GridPanelSwitch from 'container/GridPanelSwitch'; import { getFormatNameByOptionId } from 'container/NewWidget/RightContainer/alertFomatCategories'; @@ -39,6 +40,7 @@ export interface ChartPreviewProps { yAxisUnit: string; } +// eslint-disable-next-line sonarjs/cognitive-complexity function ChartPreview({ name, query, @@ -94,6 +96,7 @@ function ChartPreview({ allowSelectedIntervalForStepGen, }, }, + alertDef?.version || DEFAULT_ENTITY_VERSION, { queryKey: [ 'chartPreview', diff --git a/frontend/src/container/FormAlertRules/QuerySection.tsx b/frontend/src/container/FormAlertRules/QuerySection.tsx index 9eb4fd4703..66583ba058 100644 --- a/frontend/src/container/FormAlertRules/QuerySection.tsx +++ b/frontend/src/container/FormAlertRules/QuerySection.tsx @@ -3,13 +3,16 @@ import './QuerySection.styles.scss'; import { Button, Tabs, Tooltip } from 'antd'; import { ALERTS_DATA_SOURCE_MAP } from 'constants/alerts'; import { PANEL_TYPES } from 'constants/queryBuilder'; +import { QBShortcuts } from 'constants/shortcuts/QBShortcuts'; import { QueryBuilder } from 'container/QueryBuilder'; +import { useKeyboardHotkeys } from 'hooks/hotkeys/useKeyboardHotkeys'; import { Atom, Play, Terminal } from 'lucide-react'; -import { useMemo, useState } from 'react'; +import { useEffect, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useSelector } from 'react-redux'; import { AppState } from 'store/reducers'; import { AlertTypes } from 'types/api/alerts/alertTypes'; +import { AlertDef } from 'types/api/alerts/def'; import { EQueryType } from 'types/common/dashboard'; import AppReducer from 'types/reducer/app'; @@ -22,6 +25,7 @@ function QuerySection({ setQueryCategory, alertType, runQuery, + alertDef, panelType, }: QuerySectionProps): JSX.Element { // init namespace for translations @@ -50,6 +54,10 @@ function QuerySection({ queryVariant: 'static', initialDataSource: ALERTS_DATA_SOURCE_MAP[alertType], }} + showFunctions={ + alertType === AlertTypes.METRICS_BASED_ALERT && alertDef.version === 'v4' + } + version={alertDef.version || 'v3'} /> ); @@ -112,6 +120,17 @@ function QuerySection({ [], ); + const { registerShortcut, deregisterShortcut } = useKeyboardHotkeys(); + + useEffect(() => { + registerShortcut(QBShortcuts.StageAndRunQuery, runQuery); + + return (): void => { + deregisterShortcut(QBShortcuts.StageAndRunQuery); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [runQuery]); + const renderTabs = (typ: AlertTypes): JSX.Element | null => { switch (typ) { case AlertTypes.TRACES_BASED_ALERT: @@ -197,6 +216,7 @@ interface QuerySectionProps { setQueryCategory: (n: EQueryType) => void; alertType: AlertTypes; runQuery: VoidFunction; + alertDef: AlertDef; panelType: PANEL_TYPES; } diff --git a/frontend/src/container/FormAlertRules/index.tsx b/frontend/src/container/FormAlertRules/index.tsx index 396474211f..9fbafc14ff 100644 --- a/frontend/src/container/FormAlertRules/index.tsx +++ b/frontend/src/container/FormAlertRules/index.tsx @@ -304,7 +304,7 @@ function FormAlertRules({ panelType, ]); - const isAlertAvialable = useIsFeatureDisabled( + const isAlertAvailable = useIsFeatureDisabled( FeatureKeys.QUERY_BUILDER_ALERTS, ); @@ -458,8 +458,8 @@ function FormAlertRules({ const isAlertNameMissing = !formInstance.getFieldValue('alert'); - const isAlertAvialableToSave = - isAlertAvialable && + const isAlertAvailableToSave = + isAlertAvailable && currentQuery.queryType === EQueryType.QUERY_BUILDER && alertType !== AlertTypes.METRICS_BASED_ALERT; @@ -509,6 +509,7 @@ function FormAlertRules({ setQueryCategory={onQueryCategoryChange} alertType={alertType || AlertTypes.METRICS_BASED_ALERT} runQuery={handleRunQuery} + alertDef={alertDef} panelType={panelType || PANEL_TYPES.TIME_SERIES} /> @@ -521,7 +522,7 @@ function FormAlertRules({ {renderBasicInfo()} - + } disabled={ isAlertNameMissing || - isAlertAvialableToSave || + isAlertAvailableToSave || !isChannelConfigurationValid } > diff --git a/frontend/src/container/GridCardLayout/GridCard/FullView/index.tsx b/frontend/src/container/GridCardLayout/GridCard/FullView/index.tsx index f9462375c6..a4d3fb5cbb 100644 --- a/frontend/src/container/GridCardLayout/GridCard/FullView/index.tsx +++ b/frontend/src/container/GridCardLayout/GridCard/FullView/index.tsx @@ -6,6 +6,7 @@ import cx from 'classnames'; import { ToggleGraphProps } from 'components/Graph/types'; import Spinner from 'components/Spinner'; import TimePreference from 'components/TimePreferenceDropDown'; +import { DEFAULT_ENTITY_VERSION } from 'constants/app'; import { PANEL_TYPES } from 'constants/queryBuilder'; import GridPanelSwitch from 'container/GridPanelSwitch'; import { @@ -96,6 +97,7 @@ function FullView({ globalSelectedInterval: globalSelectedTime, variables: getDashboardVariables(selectedDashboard?.data.variables), }, + selectedDashboard?.data?.version || DEFAULT_ENTITY_VERSION, { queryKey: `FullViewGetMetricsQueryRange-${selectedTime.enum}-${globalSelectedTime}-${widget.id}`, enabled: !isDependedDataLoaded && widget.panelTypes !== PANEL_TYPES.LIST, // Internally both the list view panel has it's own query range api call, so we don't need to call it again diff --git a/frontend/src/container/GridCardLayout/GridCard/index.tsx b/frontend/src/container/GridCardLayout/GridCard/index.tsx index 623679df34..79aef8d554 100644 --- a/frontend/src/container/GridCardLayout/GridCard/index.tsx +++ b/frontend/src/container/GridCardLayout/GridCard/index.tsx @@ -1,3 +1,4 @@ +import { DEFAULT_ENTITY_VERSION } from 'constants/app'; import { QueryParams } from 'constants/query'; import { PANEL_TYPES } from 'constants/queryBuilder'; import { useGetQueryRange } from 'hooks/queryBuilder/useGetQueryRange'; @@ -39,6 +40,7 @@ function GridCardGraph({ threshold, variables, fillSpans = false, + version, }: GridCardGraphProps): JSX.Element { const dispatch = useDispatch(); const [errorMessage, setErrorMessage] = useState(); @@ -132,6 +134,7 @@ function GridCardGraph({ globalSelectedInterval, variables: getDashboardVariables(variables), }, + version || DEFAULT_ENTITY_VERSION, { queryKey: [ maxTime, @@ -253,6 +256,7 @@ GridCardGraph.defaultProps = { isQueryEnabled: true, threshold: undefined, headerMenuList: [MenuItemKeys.View], + version: 'v3', }; export default memo(GridCardGraph); diff --git a/frontend/src/container/GridCardLayout/GridCard/types.ts b/frontend/src/container/GridCardLayout/GridCard/types.ts index 59711ef9e5..b98bda5f83 100644 --- a/frontend/src/container/GridCardLayout/GridCard/types.ts +++ b/frontend/src/container/GridCardLayout/GridCard/types.ts @@ -43,6 +43,7 @@ export interface GridCardGraphProps { isQueryEnabled: boolean; variables?: Dashboard['data']['variables']; fillSpans?: boolean; + version?: string; } export interface GetGraphVisibilityStateOnLegendClickProps { diff --git a/frontend/src/container/GridCardLayout/GridCardLayout.styles.scss b/frontend/src/container/GridCardLayout/GridCardLayout.styles.scss index c8b1c72897..4b27dbda43 100644 --- a/frontend/src/container/GridCardLayout/GridCardLayout.styles.scss +++ b/frontend/src/container/GridCardLayout/GridCardLayout.styles.scss @@ -1,6 +1,6 @@ .fullscreen-grid-container { overflow: auto; - margin-top: 1rem; + margin: 8px -8px; .react-grid-layout { border: none !important; diff --git a/frontend/src/container/GridCardLayout/GridCardLayout.tsx b/frontend/src/container/GridCardLayout/GridCardLayout.tsx index b4f1dbe19c..16ae0eeaa5 100644 --- a/frontend/src/container/GridCardLayout/GridCardLayout.tsx +++ b/frontend/src/container/GridCardLayout/GridCardLayout.tsx @@ -1,6 +1,7 @@ import './GridCardLayout.styles.scss'; import { PlusOutlined } from '@ant-design/icons'; +import { Tooltip } from 'antd'; import { SOMETHING_WENT_WRONG } from 'constants/api'; import { PANEL_TYPES } from 'constants/queryBuilder'; import { themeColors } from 'constants/theme'; @@ -144,17 +145,19 @@ function GraphLayout({ onAddPanelHandler }: GraphLayoutProps): JSX.Element { return ( <> - + +