import React, { useEffect } from 'react'; import 'react-dom'; import Box from '@webapp/ui/Box'; import { FlamegraphRenderer } from '@pyroscope/flamegraph/src/FlamegraphRenderer'; import { useAppDispatch, useAppSelector } from '@webapp/redux/hooks'; import { selectContinuousState, actions, selectComparisonState, fetchComparisonSide, fetchTagValues, selectQueries, selectTimelineSides, selectAnnotationsOrDefault, } from '@webapp/redux/reducers/continuous'; import SideTimelineComparator from '@webapp/components/SideTimelineComparator'; import TimelineChartWrapper from '@webapp/components/TimelineChart/TimelineChartWrapper'; import SyncTimelines from '@webapp/components/TimelineChart/SyncTimelines'; import Toolbar from '@webapp/components/Toolbar'; import ExportData from '@webapp/components/ExportData'; import useExportToFlamegraphDotCom from '@webapp/components/exportToFlamegraphDotCom.hook'; import TagsBar from '@webapp/components/TagsBar'; import ChartTitle from '@webapp/components/ChartTitle'; import useTimeZone from '@webapp/hooks/timeZone.hook'; import useColorMode from '@webapp/hooks/colorMode.hook'; import { isExportToFlamegraphDotComEnabled } from '@webapp/util/features'; import { LoadingOverlay } from '@webapp/ui/LoadingOverlay'; import PageTitle from '@webapp/components/PageTitle'; import { Query } from '@webapp/models/query'; import styles from './ContinuousComparison.module.css'; import useTags from '../hooks/tags.hook'; import useTimelines, { leftColor, rightColor, selectionColor, } from '../hooks/timeline.hook'; import usePopulateLeftRightQuery from '../hooks/populateLeftRightQuery.hook'; import useFlamegraphSharedQuery from '../hooks/flamegraphSharedQuery.hook'; import { formatTitle } from './formatTitle'; import { isLoadingOrReloading } from './loading'; function ComparisonApp() { const dispatch = useAppDispatch(); const { leftFrom, rightFrom, leftUntil, rightUntil, refreshToken, from, until, } = useAppSelector(selectContinuousState); const { leftQuery, rightQuery } = useAppSelector(selectQueries); const { offset } = useTimeZone(); const { colorMode } = useColorMode(); usePopulateLeftRightQuery(); const { left: comparisonLeft, right: comparisonRight, comparisonMode, } = useAppSelector(selectComparisonState); const { leftTags, rightTags } = useTags(); const { leftTimeline, rightTimeline } = useTimelines(); const sharedQuery = useFlamegraphSharedQuery(); const annotations = useAppSelector( selectAnnotationsOrDefault('comparisonView') ); const timelines = useAppSelector(selectTimelineSides); const isLoading = isLoadingOrReloading([ comparisonLeft.type, comparisonRight.type, timelines.left.type, timelines.right.type, ]); useEffect(() => { if (leftQuery) { const fetchLeftQueryData = dispatch( fetchComparisonSide({ side: 'left', query: leftQuery }) ); return fetchLeftQueryData.abort; } return undefined; }, [leftFrom, leftUntil, leftQuery, refreshToken]); useEffect(() => { if (rightQuery) { const fetchRightQueryData = dispatch( fetchComparisonSide({ side: 'right', query: rightQuery }) ); return fetchRightQueryData.abort; } return undefined; }, [rightFrom, rightUntil, rightQuery, refreshToken]); const leftSide = comparisonLeft.profile; const rightSide = comparisonRight.profile; const exportToFlamegraphDotComLeftFn = useExportToFlamegraphDotCom(leftSide); const exportToFlamegraphDotComRightFn = useExportToFlamegraphDotCom(rightSide); const timezone = offset === 0 ? 'utc' : 'browser'; const isSidesHasSameUnits = leftSide && rightSide && leftSide.metadata.units === rightSide.metadata.units; const handleCompare = ({ from, until, leftFrom, leftTo, rightFrom, rightTo, }: { from: string; until: string; leftFrom: string; leftTo: string; rightFrom: string; rightTo: string; }) => { dispatch( actions.setFromAndUntil({ from, until, }) ); dispatch(actions.setRight({ from: rightFrom, until: rightTo })); dispatch(actions.setLeft({ from: leftFrom, until: leftTo })); }; const setComparisonMode = (mode: { active: boolean; period: { label: string; ms: number; }; }) => { dispatch(actions.setComparisonMode(mode)); }; const handleSelectMain = (from: string, until: string) => { setComparisonMode({ ...comparisonMode, active: false, }); dispatch(actions.setFromAndUntil({ from, until })); }; const handleSelectLeft = (from: string, until: string) => { setComparisonMode({ ...comparisonMode, active: false, }); dispatch(actions.setLeft({ from, until })); }; const handleSelectRight = (from: string, until: string) => { setComparisonMode({ ...comparisonMode, active: false, }); dispatch(actions.setRight({ from, until })); }; const handleSelectedApp = (query: Query) => { setComparisonMode({ ...comparisonMode, active: false, }); dispatch(actions.setQuery(query)); }; return (
} selectionType="double" /> { dispatch(actions.setFromAndUntil({ from, until })); }} />
dispatch(actions.refresh())} onSetQuery={(q) => dispatch(actions.setLeftQuery(q))} onSelectedLabel={(label, query) => { dispatch(fetchTagValues({ query, label })); }} /> ) } >
dispatch(actions.refresh())} onSetQuery={(q) => dispatch(actions.setRightQuery(q))} onSelectedLabel={(label, query) => { dispatch(fetchTagValues({ query, label })); }} /> ) } >
); } export default ComparisonApp;