diff --git a/frontend/package.json b/frontend/package.json index 9072afdad9f..ac19becf8d8 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -89,7 +89,7 @@ "lodash-es": "^4.17.21", "motion": "12.4.13", "nuqs": "2.8.8", - "overlayscrollbars": "^2.8.1", + "overlayscrollbars": "^2.16.0", "overlayscrollbars-react": "^0.5.6", "papaparse": "5.4.1", "posthog-js": "1.298.0", @@ -221,5 +221,18 @@ "*.(scss|css)": [ "stylelint" ] + }, + "overrides": { + "@babel/core@<=7.29.0": ">=7.29.6 <8", + "@istanbuljs/load-nyc-config>js-yaml": ">=4.2.0 <5", + "cookie@<0.7.0": ">=0.7.1 <1", + "dompurify@<=3.4.10": ">=3.4.11 <4", + "esbuild@>=0.27.3 <0.28.1": ">=0.28.1 <0.29.0", + "js-cookie@<=3.0.5": ">=3.0.7 <4", + "js-yaml@>=4.0.0 <=4.1.1": ">=4.2.0 <5", + "prismjs@<1.30.0": ">=1.30.0 <2", + "react-router@>=6.7.0 <6.30.4": ">=6.30.4 <7", + "tmp@<0.2.6": ">=0.2.6 <0.3.0", + "yaml@>=1.0.0 <1.10.3": ">=1.10.3 <2" } -} \ No newline at end of file +} diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 5f149114d44..02169d12e28 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -187,11 +187,11 @@ importers: specifier: 2.8.8 version: 2.8.8(react-router-dom@5.3.4(react@18.2.0))(react-router@6.30.4(react@18.2.0))(react@18.2.0) overlayscrollbars: - specifier: ^2.8.1 - version: 2.9.2 + specifier: ^2.16.0 + version: 2.16.0 overlayscrollbars-react: specifier: ^0.5.6 - version: 0.5.6(overlayscrollbars@2.9.2)(react@18.2.0) + version: 0.5.6(overlayscrollbars@2.16.0)(react@18.2.0) papaparse: specifier: 5.4.1 version: 5.4.1 @@ -6941,8 +6941,8 @@ packages: overlayscrollbars: ^2.0.0 react: '>=16.8.0' - overlayscrollbars@2.9.2: - resolution: {integrity: sha512-iDT84r39i7oWP72diZN2mbJUsn/taCq568aQaIrc84S87PunBT7qtsVltAF2esk7ORTRjQDnfjVYoqqTzgs8QA==} + overlayscrollbars@2.16.0: + resolution: {integrity: sha512-N03oje/q7j93D0aLZtoCdsDSYLmhheSsv8H7oSLE7HhdV9P/bmCURtLV/KbPye7P/bpfyt/obSfDpGUYoJ0OWg==} oxfmt@0.54.0: resolution: {integrity: sha512-DjnMwn7smSLF+Mc2+pRItnuPftm/dkUFpY/d4+33y9TfKrsHZo8GLhmUg9BrOIUEy94Rlom1Q11N6vuhE+e0oQ==} @@ -16456,12 +16456,12 @@ snapshots: outvariant@1.4.0: {} - overlayscrollbars-react@0.5.6(overlayscrollbars@2.9.2)(react@18.2.0): + overlayscrollbars-react@0.5.6(overlayscrollbars@2.16.0)(react@18.2.0): dependencies: - overlayscrollbars: 2.9.2 + overlayscrollbars: 2.16.0 react: 18.2.0 - overlayscrollbars@2.9.2: {} + overlayscrollbars@2.16.0: {} oxfmt@0.54.0: dependencies: diff --git a/frontend/src/__tests__/fields_api.util.ts b/frontend/src/__tests__/fields_api.util.ts new file mode 100644 index 00000000000..85149405992 --- /dev/null +++ b/frontend/src/__tests__/fields_api.util.ts @@ -0,0 +1,20 @@ +import { ENVIRONMENT } from 'constants/env'; +import { server } from 'mocks-server/server'; +import { rest } from 'msw'; + +export function mockFieldsAPIsWithEmptyResponse(): void { + server.use( + rest.get(`${ENVIRONMENT.baseURL}/api/v1/fields/keys`, (_, res, ctx) => + res( + ctx.status(200), + ctx.json({ status: 'success', data: { keys: {}, complete: true } }), + ), + ), + rest.get(`${ENVIRONMENT.baseURL}/api/v1/fields/values`, (_, res, ctx) => + res( + ctx.status(200), + ctx.json({ status: 'success', data: { values: {}, complete: true } }), + ), + ), + ); +} diff --git a/frontend/src/container/InfraMonitoringK8sV2/Base/K8sBaseDetails.tsx b/frontend/src/container/InfraMonitoringK8sV2/Base/K8sBaseDetails.tsx index 4d3ce224328..13db22f17b2 100644 --- a/frontend/src/container/InfraMonitoringK8sV2/Base/K8sBaseDetails.tsx +++ b/frontend/src/container/InfraMonitoringK8sV2/Base/K8sBaseDetails.tsx @@ -1,148 +1,39 @@ -import React, { - useCallback, - useEffect, - useMemo, - useRef, - useState, -} from 'react'; +import { useCallback, useEffect, useMemo } from 'react'; import { useQuery } from 'react-query'; import { Color, Spacing } from '@signozhq/design-tokens'; -import { Button, Drawer, Tooltip } from 'antd'; -import { ToggleGroupSimple } from '@signozhq/ui/toggle-group'; +import { X } from '@signozhq/icons'; import { Divider } from '@signozhq/ui/divider'; import { Typography } from '@signozhq/ui/typography'; +import { Drawer } from 'antd'; import logEvent from 'api/common/logEvent'; import ErrorContent from 'components/ErrorModal/components/ErrorContent'; import APIError from 'types/api/error'; -import { combineInitialAndUserExpression } from 'components/QueryBuilderV2/QueryV2/QuerySearch/utils'; import { InfraMonitoringEvents } from 'constants/events'; -import { QueryParams } from 'constants/query'; -import { - initialQueryBuilderFormValuesMap, - initialQueryState, -} from 'constants/queryBuilder'; -import ROUTES from 'constants/routes'; -import { DEFAULT_TIME_RANGE } from 'container/TopNav/DateTimeSelectionV2/constants'; -import { - CustomTimeType, - Time, -} from 'container/TopNav/DateTimeSelectionV2/types'; import { useIsDarkMode } from 'hooks/useDarkMode'; -import { GetQueryResultsProps } from 'lib/dashboard/getQueryResults'; -import GetMinMax from 'lib/getMinMax'; -import { - BarChart, - ChevronsLeftRight, - Compass, - DraftingCompass, - ScrollText, - X, -} from '@signozhq/icons'; -import { isCustomTimeRange, useGlobalTimeStore } from 'store/globalTime'; -import { NANO_SECOND_MULTIPLIER } from 'store/globalTime/utils'; import { - LogsAggregatorOperator, - TracesAggregatorOperator, -} from 'types/common/queryBuilder'; -import { openInNewTab } from 'utils/navigation'; + GlobalTimeProvider, + NANO_SECOND_MULTIPLIER, + useGlobalTimeStore, +} from 'store/globalTime'; -import { InfraMonitoringEntity, VIEW_TYPES } from '../constants'; -import EntityEvents from '../EntityDetailsUtils/EntityEvents'; -import EntityLogs from '../EntityDetailsUtils/EntityLogs'; -import { K8S_ENTITY_LOGS_EXPRESSION_KEY } from '../EntityDetailsUtils/EntityLogs/hooks'; -import EntityMetrics from '../EntityDetailsUtils/EntityMetrics'; -import EntityTraces from '../EntityDetailsUtils/EntityTraces'; -import { K8S_ENTITY_TRACES_EXPRESSION_KEY } from '../EntityDetailsUtils/EntityTraces/hooks'; -import { - SelectedItemParams, - useInfraMonitoringEventsFilters, - useInfraMonitoringLogFilters, - useInfraMonitoringSelectedItemParams, - useInfraMonitoringTracesFilters, - useInfraMonitoringView, -} from '../hooks'; +import { INFRA_MONITORING_K8S_PARAMS_KEYS } from '../constants'; +import { useInfraMonitoringSelectedItemParams } from '../hooks'; import LoadingContainer from '../LoadingContainer'; -import '../EntityDetailsUtils/entityDetails.styles.scss'; -import { parseAsString, useQueryState } from 'nuqs'; -import { - EntityCountConfig, - EntityCountsSection, -} from './components/EntityCountsSection/EntityCountsSection'; - -const TimeRangeOffset = 1000000000; - -export interface K8sDetailsMetadataConfig { - label: string; - getValue: (entity: T) => string | number; - render?: (value: string | number, entity: T) => React.ReactNode; -} - -export type K8sDetailsCountConfig = EntityCountConfig; +import K8sBaseDetailsContent from './K8sBaseDetailsContent'; +import { K8sBaseDetailsProps } from './types'; -export interface K8sDetailsFilters { - filter: { expression: string }; - start: number; - end: number; -} - -export interface CustomTabRenderProps { - entity: T; - timeRange: { startTime: number; endTime: number }; - selectedInterval: Time; - handleTimeChange: ( - interval: Time | CustomTimeType, - dateTimeRange?: [number, number], - ) => void; -} - -export interface CustomTab { - key: string; - label: string; - icon: React.ReactNode; - render: (props: CustomTabRenderProps) => React.ReactNode; -} +import '../EntityDetailsUtils/entityDetails.styles.scss'; -export interface K8sBaseDetailsProps { - category: InfraMonitoringEntity; - eventCategory: string; - // Data fetching configuration - getSelectedItemExpression: (params: SelectedItemParams) => string; - fetchEntityData: ( - filters: K8sDetailsFilters, - signal?: AbortSignal, - ) => Promise<{ data: T | null; error?: APIError | null }>; - // Entity configuration - getEntityName: (entity: T) => string; - getInitialLogTracesExpression: (entity: T) => string; - getInitialEventsExpression: (entity: T) => string; - metadataConfig: K8sDetailsMetadataConfig[]; - countsConfig?: K8sDetailsCountConfig[]; - getCountsFilterExpression?: (entity: T) => string; - entityWidgetInfo: { - title: string; - yAxisUnit: string; - docPath?: string; - }[]; - getEntityQueryPayload: ( - entity: T, - start: number, - end: number, - dotMetricsEnabled: boolean, - ) => GetQueryResultsProps[]; - queryKeyPrefix: string; - /** When true, only metrics are shown and the Metrics/Logs/Traces/Events tab bar is hidden. */ - hideDetailViewTabs?: boolean; - tabsConfig?: { - showMetrics?: boolean; - showLogs?: boolean; - showTraces?: boolean; - showEvents?: boolean; - }; - customTabs?: Array>; -} +export type { + CustomTab, + CustomTabRenderProps, + K8sBaseDetailsProps, + K8sDetailsCountConfig, + K8sDetailsFilters, + K8sDetailsMetadataConfig, +} from './types'; -// eslint-disable-next-line sonarjs/cognitive-complexity export default function K8sBaseDetails({ category, eventCategory, @@ -163,7 +54,6 @@ export default function K8sBaseDetails({ }: K8sBaseDetailsProps): JSX.Element { const selectedTime = useGlobalTimeStore((s) => s.selectedTime); const getMinMaxTime = useGlobalTimeStore((s) => s.getMinMaxTime); - const lastComputedMinMax = useGlobalTimeStore((s) => s.lastComputedMinMax); const getAutoRefreshQueryKey = useGlobalTimeStore( (s) => s.getAutoRefreshQueryKey, ); @@ -237,86 +127,9 @@ export default function K8sBaseDetails({ const entityName = entity ? getEntityName(entity) : ''; - // Content state (previously in K8sBaseDetailsContent) - const tabVisibility = useMemo( - () => ({ - showMetrics: true, - showLogs: true, - showTraces: true, - showEvents: true, - ...tabsConfig, - }), - [tabsConfig], - ); - - const { startMs, endMs } = useMemo( - () => ({ - startMs: Math.floor(lastComputedMinMax.minTime / NANO_SECOND_MULTIPLIER), - endMs: Math.floor(lastComputedMinMax.maxTime / NANO_SECOND_MULTIPLIER), - }), - [lastComputedMinMax], - ); - - const [modalTimeRange, setModalTimeRange] = useState(() => ({ - startTime: startMs, - endTime: endMs, - })); - - // TODO(h4ad): Remove this and use context/zustand - const lastSelectedInterval = useRef