@parca/profile 0.19.136 → 0.19.138

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/ProfileExplorer/ProfileExplorerSingle.d.ts.map +1 -1
  3. package/dist/ProfileExplorer/ProfileExplorerSingle.js +9 -3
  4. package/dist/ProfileFlameChart/index.d.ts +2 -1
  5. package/dist/ProfileFlameChart/index.d.ts.map +1 -1
  6. package/dist/ProfileFlameChart/index.js +10 -3
  7. package/dist/ProfileFlameGraph/index.d.ts +1 -0
  8. package/dist/ProfileFlameGraph/index.d.ts.map +1 -1
  9. package/dist/ProfileFlameGraph/index.js +8 -3
  10. package/dist/ProfileView/components/DashboardItems/index.d.ts +2 -1
  11. package/dist/ProfileView/components/DashboardItems/index.d.ts.map +1 -1
  12. package/dist/ProfileView/components/DashboardItems/index.js +2 -2
  13. package/dist/ProfileView/components/Toolbars/index.d.ts.map +1 -1
  14. package/dist/ProfileView/components/Toolbars/index.js +3 -2
  15. package/dist/ProfileView/index.d.ts +1 -1
  16. package/dist/ProfileView/index.d.ts.map +1 -1
  17. package/dist/ProfileView/index.js +2 -1
  18. package/dist/ProfileView/types/visualization.d.ts +1 -0
  19. package/dist/ProfileView/types/visualization.d.ts.map +1 -1
  20. package/dist/ProfileViewWithData.d.ts +2 -1
  21. package/dist/ProfileViewWithData.d.ts.map +1 -1
  22. package/dist/ProfileViewWithData.js +2 -2
  23. package/package.json +3 -3
  24. package/src/ProfileExplorer/ProfileExplorerSingle.tsx +14 -3
  25. package/src/ProfileFlameChart/index.tsx +32 -2
  26. package/src/ProfileFlameGraph/index.tsx +24 -4
  27. package/src/ProfileView/components/DashboardItems/index.tsx +3 -0
  28. package/src/ProfileView/components/Toolbars/index.tsx +4 -2
  29. package/src/ProfileView/index.tsx +2 -0
  30. package/src/ProfileView/types/visualization.ts +1 -0
  31. package/src/ProfileViewWithData.tsx +3 -0
package/CHANGELOG.md CHANGED
@@ -3,6 +3,14 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [0.19.138](https://github.com/parca-dev/parca/compare/@parca/profile@0.19.137...@parca/profile@0.19.138) (2026-03-17)
7
+
8
+ **Note:** Version bump only for package @parca/profile
9
+
10
+ ## 0.19.137 (2026-03-17)
11
+
12
+ **Note:** Version bump only for package @parca/profile
13
+
6
14
  ## [0.19.136](https://github.com/parca-dev/parca/compare/@parca/profile@0.19.135...@parca/profile@0.19.136) (2026-03-12)
7
15
 
8
16
  **Note:** Version bump only for package @parca/profile
@@ -1 +1 @@
1
- {"version":3,"file":"ProfileExplorerSingle.d.ts","sourceRoot":"","sources":["../../src/ProfileExplorer/ProfileExplorerSingle.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,kBAAkB,CAAC;AAMvD,UAAU,0BAA0B;IAClC,WAAW,EAAE,kBAAkB,CAAC;IAChC,UAAU,EAAE,gBAAgB,CAAC;CAC9B;AAED,QAAA,MAAM,qBAAqB,GAAI,8BAG5B,0BAA0B,KAAG,GAAG,CAAC,OAwBnC,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
1
+ {"version":3,"file":"ProfileExplorerSingle.d.ts","sourceRoot":"","sources":["../../src/ProfileExplorer/ProfileExplorerSingle.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,kBAAkB,CAAC;AAMvD,UAAU,0BAA0B;IAClC,WAAW,EAAE,kBAAkB,CAAC;IAChC,UAAU,EAAE,gBAAgB,CAAC;CAC9B;AAED,QAAA,MAAM,qBAAqB,GAAI,8BAG5B,0BAA0B,KAAG,GAAG,CAAC,OAmCnC,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
@@ -11,13 +11,19 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
11
11
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  // See the License for the specific language governing permissions and
13
13
  // limitations under the License.
14
- import { useState } from 'react';
14
+ import { useCallback, useState } from 'react';
15
15
  import { ProfileViewWithData } from '..';
16
16
  import ProfileSelector from '../ProfileSelector';
17
17
  import { useQueryState } from '../hooks/useQueryState';
18
18
  const ProfileExplorerSingle = ({ queryClient, navigateTo, }) => {
19
19
  const [showMetricsGraph, setShowMetricsGraph] = useState(true);
20
- const { profileSource } = useQueryState({ suffix: '_a' });
21
- return (_jsxs(_Fragment, { children: [_jsx("div", { className: "relative", children: _jsx(ProfileSelector, { queryClient: queryClient, closeProfile: () => { }, comparing: false, enforcedProfileName: '', navigateTo: navigateTo, suffix: "_a", showMetricsGraph: showMetricsGraph, setDisplayHideMetricsGraphButton: setShowMetricsGraph }) }), profileSource != null && (_jsx(ProfileViewWithData, { queryClient: queryClient, profileSource: profileSource }))] }));
20
+ const { profileSource, setDraftTimeRange, commitDraft } = useQueryState({ suffix: '_a' });
21
+ const handleSwitchToFifteenMinutes = useCallback(() => {
22
+ const now = Date.now();
23
+ const from = now - 900000; // 15 minutes ago
24
+ setDraftTimeRange(from, now, 'relative:minute|15');
25
+ commitDraft({ from, to: now, timeSelection: 'relative:minute|15' });
26
+ }, [setDraftTimeRange, commitDraft]);
27
+ return (_jsxs(_Fragment, { children: [_jsx("div", { className: "relative", children: _jsx(ProfileSelector, { queryClient: queryClient, closeProfile: () => { }, comparing: false, enforcedProfileName: '', navigateTo: navigateTo, suffix: "_a", showMetricsGraph: showMetricsGraph, setDisplayHideMetricsGraphButton: setShowMetricsGraph }) }), profileSource != null && (_jsx(ProfileViewWithData, { queryClient: queryClient, profileSource: profileSource, onSwitchToFifteenMinutes: handleSwitchToFifteenMinutes }))] }));
22
28
  };
23
29
  export default ProfileExplorerSingle;
@@ -13,7 +13,8 @@ interface ProfileFlameChartProps {
13
13
  isHalfScreen: boolean;
14
14
  metadataMappingFiles?: string[];
15
15
  metadataLoading?: boolean;
16
+ onSwitchToFifteenMinutes?: () => void;
16
17
  }
17
- export declare const ProfileFlameChart: ({ samplesData, queryClient, profileSource, width, total, filtered, profileType, isHalfScreen, metadataMappingFiles, metadataLoading, }: ProfileFlameChartProps) => JSX.Element;
18
+ export declare const ProfileFlameChart: ({ samplesData, queryClient, profileSource, width, total, filtered, profileType, isHalfScreen, metadataMappingFiles, metadataLoading, onSwitchToFifteenMinutes, }: ProfileFlameChartProps) => JSX.Element;
18
19
  export default ProfileFlameChart;
19
20
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileFlameChart/index.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAoC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAEpF,OAAO,EAAwB,WAAW,EAAQ,MAAM,eAAe,CAAC;AAKxE,OAAO,EAAsB,aAAa,EAAa,MAAM,kBAAkB,CAAC;AAChF,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,oCAAoC,CAAC;AA4CpE,UAAU,sBAAsB;IAC9B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,WAAW,EAAE,kBAAkB,CAAC;IAChC,aAAa,EAAE,aAAa,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,YAAY,EAAE,OAAO,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AA+BD,eAAO,MAAM,iBAAiB,GAAI,wIAW/B,sBAAsB,KAAG,GAAG,CAAC,OAgL/B,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileFlameChart/index.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAoC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAQpF,OAAO,EAAwB,WAAW,EAAQ,MAAM,eAAe,CAAC;AAKxE,OAAO,EAAsB,aAAa,EAAa,MAAM,kBAAkB,CAAC;AAEhF,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,oCAAoC,CAAC;AA4CpE,UAAU,sBAAsB;IAC9B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,WAAW,EAAE,kBAAkB,CAAC;IAChC,aAAa,EAAE,aAAa,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,YAAY,EAAE,OAAO,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,wBAAwB,CAAC,EAAE,MAAM,IAAI,CAAC;CACvC;AA+BD,eAAO,MAAM,iBAAiB,GAAI,kKAY/B,sBAAsB,KAAG,GAAG,CAAC,OAqM/B,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
@@ -13,12 +13,13 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
13
  // limitations under the License.
14
14
  import { useEffect, useMemo, useRef } from 'react';
15
15
  import { QueryRequest_ReportType } from '@parca/client';
16
- import { useURLState, useURLStateCustom } from '@parca/components';
16
+ import { Button, useParcaContext, useURLState, useURLStateCustom, } from '@parca/components';
17
17
  import { Matcher, MatcherTypes, Query } from '@parca/parser';
18
18
  import { TimeUnits, formatDate, formatDuration } from '@parca/utilities';
19
19
  import ProfileFlameGraph, { validateFlameChartQuery } from '../ProfileFlameGraph';
20
20
  import { boundsFromProfileSource } from '../ProfileFlameGraph/FlameGraphArrow/utils';
21
21
  import { MergedProfileSource, timeFormat } from '../ProfileSource';
22
+ import { useProfileFilters } from '../ProfileView/components/ProfileFilters/useProfileFilters';
22
23
  import { useQuery } from '../useQuery';
23
24
  import { SamplesStrip } from './SamplesStrips';
24
25
  const TimeframeStateSerializer = {
@@ -70,7 +71,9 @@ const createFilteredProfileSource = (profileSource, selectedTimeframe) => {
70
71
  const query = new Query(profileSource.query.profType, [...profileSource.query.matchers, ...dimensionMatchers], '');
71
72
  return new MergedProfileSource(mergeFrom, mergeTo, query);
72
73
  };
73
- export const ProfileFlameChart = ({ samplesData, queryClient, profileSource, width, total, filtered, profileType, isHalfScreen, metadataMappingFiles, metadataLoading, }) => {
74
+ export const ProfileFlameChart = ({ samplesData, queryClient, profileSource, width, total, filtered, profileType, isHalfScreen, metadataMappingFiles, metadataLoading, onSwitchToFifteenMinutes, }) => {
75
+ const { enableFlamechartFiltering } = useParcaContext();
76
+ const { protoFilters } = useProfileFilters();
74
77
  const zoomControlsRef = useRef(null);
75
78
  const [selectedTimeframe, setSelectedTimeframe] = useURLStateCustom('flamechart_timeframe', TimeframeStateSerializer);
76
79
  // Read flamechart dimension from URL state to detect changes
@@ -113,6 +116,7 @@ export const ProfileFlameChart = ({ samplesData, queryClient, profileSource, wid
113
116
  // Query flamechart data only when a strip selection exists
114
117
  const { isLoading: flamechartLoading, response: flamechartResponse, error: flamechartError, } = useQuery(queryClient, filteredProfileSource ?? profileSource, QueryRequest_ReportType.FLAMECHART, {
115
118
  skip: selectedTimeframe == null || filteredProfileSource == null,
119
+ ...(enableFlamechartFiltering === true ? { protoFilters } : {}),
116
120
  });
117
121
  const flamechartArrow = flamechartResponse?.report.oneofKind === 'flamegraphArrow'
118
122
  ? flamechartResponse.report.flamegraphArrow
@@ -130,8 +134,11 @@ export const ProfileFlameChart = ({ samplesData, queryClient, profileSource, wid
130
134
  const stepMs = samplesData.stepMs ?? 0;
131
135
  return { cpus, data, stepMs };
132
136
  }, [samplesData?.series, samplesData?.stepMs]);
133
- const { isValid, isNonDelta } = validateFlameChartQuery(profileSource);
137
+ const { isValid, isNonDelta, isDurationTooLong } = validateFlameChartQuery(profileSource);
134
138
  if (!isValid) {
139
+ if (isDurationTooLong) {
140
+ return (_jsxs("div", { className: "flex flex-col justify-center items-center p-10 text-center gap-4 text-sm", children: [_jsx("span", { children: "Flame chart is unavailable for queries longer than 15 minutes. Try reducing the time range to 15 minutes or selecting a point in the metrics graph." }), onSwitchToFifteenMinutes != null && (_jsx(Button, { variant: "primary", onClick: onSwitchToFifteenMinutes, children: "Switch to last 15 minutes" }))] }));
141
+ }
135
142
  const message = isNonDelta
136
143
  ? 'To use the Flame chart, please switch to a Delta profile.'
137
144
  : 'Flame chart is unavailable for this query.';
@@ -30,6 +30,7 @@ interface ProfileFlameGraphProps {
30
30
  export declare const validateFlameChartQuery: (profileSource: MergedProfileSource) => {
31
31
  isValid: boolean;
32
32
  isNonDelta: boolean;
33
+ isDurationTooLong: boolean;
33
34
  };
34
35
  declare const ProfileFlameGraph: ({ arrow, total, filtered, curPathArrow, setNewCurPathArrow, profileType, loading, error, width, isHalfScreen, metadataMappingFiles, isFlameChart, profileSource, isInSandwichView, isRenderedAsFlamegraph, tooltipId, maxFrameCount, isExpanded, metadataLoading, zoomControlsRef, }: ProfileFlameGraphProps) => JSX.Element;
35
36
  export default ProfileFlameGraph;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileFlameGraph/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAwE,MAAM,OAAO,CAAC;AAM7F,OAAO,EAAC,eAAe,EAAC,MAAM,eAAe,CAAC;AAO9C,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAI1C,OAAO,EAAC,mBAAmB,EAAE,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAMpE,OAAO,EAAC,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAIzD,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;AAEpE,UAAU,sBAAsB;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,gBAAgB,EAAE,GAAG,EAAE,CAAC;IACtC,kBAAkB,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IACvD,OAAO,EAAE,OAAO,CAAC;IACjB,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,KAAK,IAAI,CAAC;IACxD,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,YAAY,EAAE,OAAO,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,eAAe,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;CAC1D;AAUD,eAAO,MAAM,uBAAuB,GAClC,eAAe,mBAAmB,KACjC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAGxC,CAAC;AAEF,QAAA,MAAM,iBAAiB,GAAqC,sRAqBzD,sBAAsB,KAAG,GAAG,CAAC,OA+R/B,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileFlameGraph/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAwE,MAAM,OAAO,CAAC;AAM7F,OAAO,EAAC,eAAe,EAAC,MAAM,eAAe,CAAC;AAO9C,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAI1C,OAAO,EAAC,mBAAmB,EAAE,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAMpE,OAAO,EAAC,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAIzD,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;AAEpE,UAAU,sBAAsB;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,gBAAgB,EAAE,GAAG,EAAE,CAAC;IACtC,kBAAkB,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IACvD,OAAO,EAAE,OAAO,CAAC;IACjB,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,KAAK,IAAI,CAAC;IACxD,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,YAAY,EAAE,OAAO,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,eAAe,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;CAC1D;AAUD,eAAO,MAAM,uBAAuB,GAClC,eAAe,mBAAmB,KACjC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,OAAO,CAAC;IAAC,iBAAiB,EAAE,OAAO,CAAA;CAKpE,CAAC;AAEF,QAAA,MAAM,iBAAiB,GAAqC,sRAqBzD,sBAAsB,KAAG,GAAG,CAAC,OAiT/B,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
@@ -29,7 +29,9 @@ const ErrorContent = ({ errorMessage }) => {
29
29
  };
30
30
  export const validateFlameChartQuery = (profileSource) => {
31
31
  const isNonDelta = !profileSource.ProfileType().delta;
32
- return { isValid: !isNonDelta, isNonDelta };
32
+ const duration = profileSource.mergeTo - profileSource.mergeFrom;
33
+ const isDurationTooLong = duration > 900000000000n; // 15 minutes in nanoseconds
34
+ return { isValid: !isNonDelta && !isDurationTooLong, isNonDelta, isDurationTooLong };
33
35
  };
34
36
  const ProfileFlameGraph = function ProfileFlameGraphNonMemo({ arrow, total, filtered, curPathArrow, setNewCurPathArrow, profileType, loading, error, width, isHalfScreen, metadataMappingFiles, isFlameChart = false, profileSource, isInSandwichView = false, isRenderedAsFlamegraph = false, tooltipId, maxFrameCount, isExpanded = false, metadataLoading = false, zoomControlsRef, }) {
35
37
  const { onError, authenticationErrorMessage, isDarkMode, flamechartHelpText } = useParcaContext();
@@ -96,9 +98,9 @@ const ProfileFlameGraph = function ProfileFlameGraphNonMemo({ arrow, total, filt
96
98
  }
97
99
  }, [loadingState]);
98
100
  const flameGraph = useMemo(() => {
99
- const { isValid: isFlameChartValid, isNonDelta } = isFlameChart
101
+ const { isValid: isFlameChartValid, isNonDelta, isDurationTooLong, } = isFlameChart
100
102
  ? validateFlameChartQuery(profileSource)
101
- : { isValid: true, isNonDelta: false };
103
+ : { isValid: true, isNonDelta: false, isDurationTooLong: false };
102
104
  const isInvalidFlameChartQuery = isFlameChart && !isFlameChartValid;
103
105
  if (isLoading && !isInvalidFlameChartQuery) {
104
106
  return (_jsx("div", { className: "h-auto overflow-clip", "data-testid": TEST_IDS.FLAMEGRAPH_SKELETON, children: isRenderedAsFlamegraph ? (_jsx(SandwichFlameGraphSkeleton, { isHalfScreen: isHalfScreen, isDarkMode: isDarkMode })) : (_jsx(FlameGraphSkeleton, { isHalfScreen: isHalfScreen, isDarkMode: isDarkMode })) }));
@@ -108,6 +110,9 @@ const ProfileFlameGraph = function ProfileFlameGraphNonMemo({ arrow, total, filt
108
110
  if (isNonDelta) {
109
111
  return (_jsx(ErrorContent, { errorMessage: _jsxs(_Fragment, { children: [_jsx("span", { children: "To use the Flame chart, please switch to a Delta profile." }), flamechartHelpText ?? null] }) }));
110
112
  }
113
+ else if (isDurationTooLong) {
114
+ return (_jsx(ErrorContent, { errorMessage: _jsxs(_Fragment, { children: [_jsx("span", { children: "Flame chart is unavailable for queries longer than 15 minutes. Please select a point in the metrics graph to continue." }), flamechartHelpText ?? null] }) }));
115
+ }
111
116
  else {
112
117
  return (_jsx(ErrorContent, { errorMessage: _jsxs(_Fragment, { children: [_jsx("span", { children: "The Flame chart is not available for this query." }), flamechartHelpText ?? null] }) }));
113
118
  }
@@ -21,7 +21,8 @@ interface GetDashboardItemProps {
21
21
  onRender?: ProfilerOnRenderCallback;
22
22
  };
23
23
  queryClient: QueryServiceClient;
24
+ onSwitchToFifteenMinutes?: () => void;
24
25
  }
25
- export declare const getDashboardItem: ({ type, isHalfScreen, dimensions, flamegraphData, samplesData, topTableData, sourceData, sandwichData, profileSource, total, filtered, curPathArrow, setNewCurPathArrow, perf, queryClient, }: GetDashboardItemProps) => JSX.Element;
26
+ export declare const getDashboardItem: ({ type, isHalfScreen, dimensions, flamegraphData, samplesData, topTableData, sourceData, sandwichData, profileSource, total, filtered, curPathArrow, setNewCurPathArrow, perf, queryClient, onSwitchToFifteenMinutes, }: GetDashboardItemProps) => JSX.Element;
26
27
  export {};
27
28
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/DashboardItems/index.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAW,wBAAwB,EAAC,MAAM,OAAO,CAAC;AAEzD,OAAO,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAKjD,OAAO,EAAC,gBAAgB,EAAC,MAAM,kDAAkD,CAAC;AAClF,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAIrD,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EACX,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,iBAAiB,EAClB,MAAM,2BAA2B,CAAC;AAEnC,UAAU,qBAAqB;IAC7B,IAAI,EAAE,iBAAiB,CAAC;IACxB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,OAAO,GAAG,SAAS,CAAC;IAChC,cAAc,EAAE,cAAc,CAAC;IAC/B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,YAAY,EAAE,YAAY,CAAC;IAC3B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,aAAa,EAAE,aAAa,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,kBAAkB,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IACvD,IAAI,CAAC,EAAE;QACL,QAAQ,CAAC,EAAE,wBAAwB,CAAC;KACrC,CAAC;IACF,WAAW,EAAE,kBAAkB,CAAC;CACjC;AAED,eAAO,MAAM,gBAAgB,GAAI,+LAgB9B,qBAAqB,KAAG,GAAG,CAAC,OA4F9B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/DashboardItems/index.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAW,wBAAwB,EAAC,MAAM,OAAO,CAAC;AAEzD,OAAO,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAKjD,OAAO,EAAC,gBAAgB,EAAC,MAAM,kDAAkD,CAAC;AAClF,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAIrD,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EACX,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,iBAAiB,EAClB,MAAM,2BAA2B,CAAC;AAEnC,UAAU,qBAAqB;IAC7B,IAAI,EAAE,iBAAiB,CAAC;IACxB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,OAAO,GAAG,SAAS,CAAC;IAChC,cAAc,EAAE,cAAc,CAAC;IAC/B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,YAAY,EAAE,YAAY,CAAC;IAC3B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,aAAa,EAAE,aAAa,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,kBAAkB,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IACvD,IAAI,CAAC,EAAE;QACL,QAAQ,CAAC,EAAE,wBAAwB,CAAC;KACrC,CAAC;IACF,WAAW,EAAE,kBAAkB,CAAC;IAChC,wBAAwB,CAAC,EAAE,MAAM,IAAI,CAAC;CACvC;AAED,eAAO,MAAM,gBAAgB,GAAI,yNAiB9B,qBAAqB,KAAG,GAAG,CAAC,OA6F9B,CAAC"}
@@ -18,7 +18,7 @@ import ProfileFlameGraph from '../../../ProfileFlameGraph';
18
18
  import Sandwich from '../../../Sandwich';
19
19
  import { SourceView } from '../../../SourceView';
20
20
  import { Table } from '../../../Table';
21
- export const getDashboardItem = ({ type, isHalfScreen, dimensions, flamegraphData, samplesData, topTableData, sourceData, sandwichData, profileSource, total, filtered, curPathArrow, setNewCurPathArrow, perf, queryClient, }) => {
21
+ export const getDashboardItem = ({ type, isHalfScreen, dimensions, flamegraphData, samplesData, topTableData, sourceData, sandwichData, profileSource, total, filtered, curPathArrow, setNewCurPathArrow, perf, queryClient, onSwitchToFifteenMinutes, }) => {
22
22
  switch (type) {
23
23
  case 'flamegraph':
24
24
  return (_jsx(ConditionalWrapper, { condition: perf?.onRender != null, WrapperComponent: Profiler, wrapperProps: {
@@ -34,7 +34,7 @@ export const getDashboardItem = ({ type, isHalfScreen, dimensions, flamegraphDat
34
34
  ? isHalfScreen
35
35
  ? (dimensions.width - 54) / 2
36
36
  : dimensions.width - 16
37
- : 0, total: total, filtered: filtered, profileType: profileSource?.ProfileType(), isHalfScreen: isHalfScreen, metadataMappingFiles: flamegraphData.metadataMappingFiles, metadataLoading: flamegraphData.metadataLoading }));
37
+ : 0, total: total, filtered: filtered, profileType: profileSource?.ProfileType(), isHalfScreen: isHalfScreen, metadataMappingFiles: flamegraphData.metadataMappingFiles, metadataLoading: flamegraphData.metadataLoading, onSwitchToFifteenMinutes: onSwitchToFifteenMinutes }));
38
38
  case 'table':
39
39
  return topTableData != null ? (_jsx(Table, { error: topTableData.error, total: total, filtered: filtered, loading: topTableData.loading, data: topTableData.arrow?.record, unit: topTableData.unit, profileType: profileSource?.ProfileType(), isHalfScreen: isHalfScreen, metadataMappingFiles: flamegraphData.metadataMappingFiles })) : (_jsx(_Fragment, {}));
40
40
  case 'sandwich':
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/Toolbars/index.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAC,EAAE,EAAC,MAAM,OAAO,CAAC;AAIzB,OAAO,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAG1C,OAAO,EAAC,gBAAgB,EAAC,MAAM,kDAAkD,CAAC;AAClF,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAUrD,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,aAAa,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IAClD,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,6BAA6B,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAChD,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC7C,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,sBAAsB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACnD,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oBAAoB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,QAAQ,EAAE;QACR,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QAC9B,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC;CACH;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,aAAa,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;CACnD;AAED,MAAM,WAAW,8BAA8B;IAC7C,yBAAyB,EAAE,MAAM,IAAI,CAAC;IACtC,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CAQ9C,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,EAAE,CAAC,sBAAsB,CAkBxD,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,EAAE,CAAC,8BAA8B,CAmBxE,CAAC;AAMF,eAAO,MAAM,oBAAoB,EAAE,EAAE,CAAC,yBAAyB,CAkH9D,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/Toolbars/index.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAC,EAAE,EAAC,MAAM,OAAO,CAAC;AAIzB,OAAO,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAG1C,OAAO,EAAC,gBAAgB,EAAC,MAAM,kDAAkD,CAAC;AAClF,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAUrD,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,aAAa,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IAClD,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,6BAA6B,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAChD,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC7C,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,sBAAsB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACnD,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oBAAoB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,QAAQ,EAAE;QACR,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QAC9B,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC;CACH;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,aAAa,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;CACnD;AAED,MAAM,WAAW,8BAA8B;IAC7C,yBAAyB,EAAE,MAAM,IAAI,CAAC;IACtC,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CAQ9C,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,EAAE,CAAC,sBAAsB,CAkBxD,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,EAAE,CAAC,8BAA8B,CAmBxE,CAAC;AAMF,eAAO,MAAM,oBAAoB,EAAE,EAAE,CAAC,yBAAyB,CAoH9D,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Icon } from '@iconify/react';
3
- import { Button } from '@parca/components';
3
+ import { Button, useParcaContext } from '@parca/components';
4
4
  import { TEST_IDS, testId } from '@parca/test-utils';
5
5
  import { useDashboard } from '../../context/DashboardContext';
6
6
  import GroupByDropdown from '../ActionButtons/GroupByDropdown';
@@ -28,11 +28,12 @@ export const VisualisationToolbar = ({ groupBy, toggleGroupBy, setGroupByLabels,
28
28
  const isGraphVizOnly = dashboardItems?.length === 1 && isGraphViz;
29
29
  const isFlamechartViz = dashboardItems?.includes('flamechart');
30
30
  const isFlamechartVizOnly = dashboardItems?.length === 1 && isFlamechartViz;
31
+ const { enableFlamechartFiltering } = useParcaContext();
31
32
  const req = profileSource?.QueryRequest();
32
33
  if (req !== null && req !== undefined) {
33
34
  req.groupBy = {
34
35
  fields: groupBy ?? [],
35
36
  };
36
37
  }
37
- return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex w-full justify-between items-start gap-2", children: [_jsxs("div", { className: "flex gap-2 items-start", children: [isGraphViz && (_jsxs(_Fragment, { children: [_jsx(GroupByDropdown, { groupBy: groupBy, labels: groupByLabels, setGroupByLabels: setGroupByLabels, metadataRefetch: metadataRefetch, metadataLoading: metadataLoading }), _jsx(InvertCallStack, {})] })), isFlamechartViz && (_jsx(GroupByDropdown, { groupBy: flamechartDimension, labels: groupByLabels, setGroupByLabels: setFlamechartDimension, metadataRefetch: metadataRefetch, metadataLoading: metadataLoading, label: "Samples group by" })), _jsxs("div", { className: "flex mt-5", children: [!isFlamechartVizOnly && _jsx(ProfileFilters, {}), profileViewExternalSubActions != null ? profileViewExternalSubActions : null] })] }), _jsxs("div", { className: "flex gap-2 mt-5", children: [_jsx(MultiLevelDropdown, { groupBy: groupBy, toggleGroupBy: toggleGroupBy, profileType: profileType, onSelect: () => { }, isTableVizOnly: isTableVizOnly, alignFunctionName: alignFunctionName, setAlignFunctionName: setAlignFunctionName, colorBy: colorBy, setColorBy: setColorBy }), _jsx(ShareButton, { profileSource: profileSource, queryClient: queryClient, queryRequest: req, onDownloadPProf: onDownloadPProf, pprofdownloading: pprofdownloading ?? false, profileViewExternalSubActions: profileViewExternalSubActions }), showVisualizationSelector ? _jsx(ViewSelector, { profileSource: profileSource }) : null] })] }), isGraphVizOnly && (_jsxs(_Fragment, { children: [_jsx(Divider, {}), _jsx(FlameGraphToolbar, { curPath: curPath, setNewCurPath: setNewCurPath })] })), isTableVizOnly && (_jsxs(_Fragment, { children: [_jsx(Divider, {}), _jsx(TableToolbar, { profileType: profileType, total: total, filtered: filtered })] }))] }));
38
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex w-full justify-between items-start gap-2", children: [_jsxs("div", { className: "flex gap-2 items-start", children: [isGraphViz && (_jsxs(_Fragment, { children: [_jsx(GroupByDropdown, { groupBy: groupBy, labels: groupByLabels, setGroupByLabels: setGroupByLabels, metadataRefetch: metadataRefetch, metadataLoading: metadataLoading }), _jsx(InvertCallStack, {})] })), isFlamechartViz && (_jsx(GroupByDropdown, { groupBy: flamechartDimension, labels: groupByLabels, setGroupByLabels: setFlamechartDimension, metadataRefetch: metadataRefetch, metadataLoading: metadataLoading, label: "Samples group by" })), _jsxs("div", { className: "flex mt-5", children: [(!isFlamechartVizOnly || enableFlamechartFiltering === true) && _jsx(ProfileFilters, {}), profileViewExternalSubActions != null ? profileViewExternalSubActions : null] })] }), _jsxs("div", { className: "flex gap-2 mt-5", children: [_jsx(MultiLevelDropdown, { groupBy: groupBy, toggleGroupBy: toggleGroupBy, profileType: profileType, onSelect: () => { }, isTableVizOnly: isTableVizOnly, alignFunctionName: alignFunctionName, setAlignFunctionName: setAlignFunctionName, colorBy: colorBy, setColorBy: setColorBy }), _jsx(ShareButton, { profileSource: profileSource, queryClient: queryClient, queryRequest: req, onDownloadPProf: onDownloadPProf, pprofdownloading: pprofdownloading ?? false, profileViewExternalSubActions: profileViewExternalSubActions }), showVisualizationSelector ? _jsx(ViewSelector, { profileSource: profileSource }) : null] })] }), isGraphVizOnly && (_jsxs(_Fragment, { children: [_jsx(Divider, {}), _jsx(FlameGraphToolbar, { curPath: curPath, setNewCurPath: setNewCurPath })] })), isTableVizOnly && (_jsxs(_Fragment, { children: [_jsx(Divider, {}), _jsx(TableToolbar, { profileType: profileType, total: total, filtered: filtered })] }))] }));
38
39
  };
@@ -1,3 +1,3 @@
1
1
  import type { ProfileViewProps } from './types/visualization';
2
- export declare const ProfileView: ({ total, filtered, flamegraphData, samplesData, topTableData, sourceData, profileSource, queryClient, onDownloadPProf, pprofDownloading, compare, showVisualizationSelector, sandwichData, }: ProfileViewProps) => JSX.Element;
2
+ export declare const ProfileView: ({ total, filtered, flamegraphData, samplesData, topTableData, sourceData, profileSource, queryClient, onDownloadPProf, pprofDownloading, compare, showVisualizationSelector, sandwichData, onSwitchToFifteenMinutes, }: ProfileViewProps) => JSX.Element;
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileView/index.tsx"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAC,gBAAgB,EAAoB,MAAM,uBAAuB,CAAC;AAE/E,eAAO,MAAM,WAAW,GAAI,8LAczB,gBAAgB,KAAG,GAAG,CAAC,OAiJzB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileView/index.tsx"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAC,gBAAgB,EAAoB,MAAM,uBAAuB,CAAC;AAE/E,eAAO,MAAM,WAAW,GAAI,wNAezB,gBAAgB,KAAG,GAAG,CAAC,OAkJzB,CAAC"}
@@ -24,7 +24,7 @@ import { ProfileViewContextProvider } from './context/ProfileViewContext';
24
24
  import { useAutoSelectDimension } from './hooks/useAutoSelectDimension';
25
25
  import { useProfileMetadata } from './hooks/useProfileMetadata';
26
26
  import { useVisualizationState } from './hooks/useVisualizationState';
27
- export const ProfileView = ({ total, filtered, flamegraphData, samplesData, topTableData, sourceData, profileSource, queryClient, onDownloadPProf, pprofDownloading, compare, showVisualizationSelector, sandwichData, }) => {
27
+ export const ProfileView = ({ total, filtered, flamegraphData, samplesData, topTableData, sourceData, profileSource, queryClient, onDownloadPProf, pprofDownloading, compare, showVisualizationSelector, sandwichData, onSwitchToFifteenMinutes, }) => {
28
28
  const { timezone, perf, profileViewExternalMainActions, preferencesModal, profileViewExternalSubActions, } = useParcaContext();
29
29
  const { ref, dimensions } = useContainerDimensions();
30
30
  const { curPathArrow, setCurPathArrow, colorStackLegend, colorBy, setColorBy, groupBy, toggleGroupBy, setGroupByLabels, flamechartDimension, setFlamechartDimension, sandwichFunctionName, resetSandwichFunctionName, alignFunctionName, setAlignFunctionName, } = useVisualizationState();
@@ -55,6 +55,7 @@ export const ProfileView = ({ total, filtered, flamegraphData, samplesData, topT
55
55
  setNewCurPathArrow: setCurPathArrow,
56
56
  perf,
57
57
  queryClient,
58
+ onSwitchToFifteenMinutes,
58
59
  });
59
60
  };
60
61
  const actionButtons = {
@@ -55,5 +55,6 @@ export interface ProfileViewProps {
55
55
  onDownloadPProf: () => void;
56
56
  pprofDownloading?: boolean;
57
57
  showVisualizationSelector?: boolean;
58
+ onSwitchToFifteenMinutes?: () => void;
58
59
  }
59
60
  //# sourceMappingURL=visualization.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"visualization.d.ts","sourceRoot":"","sources":["../../../src/ProfileView/types/visualization.ts"],"names":[],"mappings":"AAaA,OAAO,EAAC,QAAQ,EAAC,MAAM,0BAA0B,CAAC;AAElD,OAAO,EAAC,eAAe,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,EAAE,UAAU,EAAC,MAAM,eAAe,CAAC;AAEhG,OAAO,EAAC,SAAS,EAAC,MAAM,oDAAoD,CAAC;AAC7E,OAAO,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAElD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;IACvB,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,cAAc,CAAC;IACxB,OAAO,EAAE,cAAc,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,SAAS,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC;IACzB,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,iBAAiB,GACzB,YAAY,GACZ,WAAW,GACX,OAAO,GACP,QAAQ,GACR,YAAY,GACZ,UAAU,CAAC;AAEf,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,cAAc,CAAC;IAC/B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,YAAY,EAAE,YAAY,CAAC;IAC3B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,aAAa,EAAE,aAAa,CAAC;IAC7B,WAAW,EAAE,kBAAkB,CAAC;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,yBAAyB,CAAC,EAAE,OAAO,CAAC;CACrC"}
1
+ {"version":3,"file":"visualization.d.ts","sourceRoot":"","sources":["../../../src/ProfileView/types/visualization.ts"],"names":[],"mappings":"AAaA,OAAO,EAAC,QAAQ,EAAC,MAAM,0BAA0B,CAAC;AAElD,OAAO,EAAC,eAAe,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,EAAE,UAAU,EAAC,MAAM,eAAe,CAAC;AAEhG,OAAO,EAAC,SAAS,EAAC,MAAM,oDAAoD,CAAC;AAC7E,OAAO,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAElD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;IACvB,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,cAAc,CAAC;IACxB,OAAO,EAAE,cAAc,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,SAAS,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC;IACzB,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,iBAAiB,GACzB,YAAY,GACZ,WAAW,GACX,OAAO,GACP,QAAQ,GACR,YAAY,GACZ,UAAU,CAAC;AAEf,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,cAAc,CAAC;IAC/B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,YAAY,EAAE,YAAY,CAAC;IAC3B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,aAAa,EAAE,aAAa,CAAC;IAC7B,WAAW,EAAE,kBAAkB,CAAC;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,wBAAwB,CAAC,EAAE,MAAM,IAAI,CAAC;CACvC"}
@@ -5,7 +5,8 @@ interface ProfileViewWithDataProps {
5
5
  profileSource: ProfileSource;
6
6
  compare?: boolean;
7
7
  showVisualizationSelector?: boolean;
8
+ onSwitchToFifteenMinutes?: () => void;
8
9
  }
9
- export declare const ProfileViewWithData: ({ queryClient, profileSource, showVisualizationSelector, }: ProfileViewWithDataProps) => JSX.Element;
10
+ export declare const ProfileViewWithData: ({ queryClient, profileSource, showVisualizationSelector, onSwitchToFifteenMinutes, }: ProfileViewWithDataProps) => JSX.Element;
10
11
  export default ProfileViewWithData;
11
12
  //# sourceMappingURL=ProfileViewWithData.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ProfileViewWithData.d.ts","sourceRoot":"","sources":["../src/ProfileViewWithData.tsx"],"names":[],"mappings":"AAeA,OAAO,EAA0B,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAkB1E,OAAO,EAAsB,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAOnE,UAAU,wBAAwB;IAChC,WAAW,EAAE,kBAAkB,CAAC;IAChC,aAAa,EAAE,aAAa,CAAC;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,yBAAyB,CAAC,EAAE,OAAO,CAAC;CACrC;AAED,eAAO,MAAM,mBAAmB,GAAI,4DAIjC,wBAAwB,KAAG,GAAG,CAAC,OA2UjC,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"ProfileViewWithData.d.ts","sourceRoot":"","sources":["../src/ProfileViewWithData.tsx"],"names":[],"mappings":"AAeA,OAAO,EAA0B,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAkB1E,OAAO,EAAsB,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAOnE,UAAU,wBAAwB;IAChC,WAAW,EAAE,kBAAkB,CAAC;IAChC,aAAa,EAAE,aAAa,CAAC;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,wBAAwB,CAAC,EAAE,MAAM,IAAI,CAAC;CACvC;AAED,eAAO,MAAM,mBAAmB,GAAI,sFAKjC,wBAAwB,KAAG,GAAG,CAAC,OA4UjC,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
@@ -23,7 +23,7 @@ import { ProfileView } from './ProfileView';
23
23
  import { useProfileFilters } from './ProfileView/components/ProfileFilters/useProfileFilters';
24
24
  import { useQuery } from './useQuery';
25
25
  import { downloadPprof } from './utils';
26
- export const ProfileViewWithData = ({ queryClient, profileSource, showVisualizationSelector, }) => {
26
+ export const ProfileViewWithData = ({ queryClient, profileSource, showVisualizationSelector, onSwitchToFifteenMinutes, }) => {
27
27
  const metadata = useGrpcMetadata();
28
28
  const [dashboardItems, setDashboardItems] = useURLState('dashboard_items', {
29
29
  alwaysReturnArray: true,
@@ -262,6 +262,6 @@ export const ProfileViewWithData = ({ queryClient, profileSource, showVisualizat
262
262
  : undefined,
263
263
  metadataLoading: profileMetadataLoading,
264
264
  },
265
- }, samplesData: samplesData, profileSource: profileSource, queryClient: queryClient, onDownloadPProf: () => void downloadPProfClick(), pprofDownloading: pprofDownloading, showVisualizationSelector: showVisualizationSelector }));
265
+ }, samplesData: samplesData, profileSource: profileSource, queryClient: queryClient, onDownloadPProf: () => void downloadPProfClick(), pprofDownloading: pprofDownloading, showVisualizationSelector: showVisualizationSelector, onSwitchToFifteenMinutes: onSwitchToFifteenMinutes }));
266
266
  };
267
267
  export default ProfileViewWithData;
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@parca/profile",
3
- "version": "0.19.136",
3
+ "version": "0.19.138",
4
4
  "description": "Profile viewing libraries",
5
5
  "dependencies": {
6
6
  "@floating-ui/react": "^0.27.12",
7
7
  "@headlessui/react": "^1.7.19",
8
8
  "@iconify/react": "^4.0.0",
9
9
  "@parca/client": "0.17.20",
10
- "@parca/components": "0.16.409",
10
+ "@parca/components": "0.16.410",
11
11
  "@parca/dynamicsize": "0.16.73",
12
12
  "@parca/hooks": "0.0.121",
13
13
  "@parca/icons": "0.16.80",
@@ -88,5 +88,5 @@
88
88
  "access": "public",
89
89
  "registry": "https://registry.npmjs.org/"
90
90
  },
91
- "gitHead": "49b2a23d58b63ce07cbdcbeed8ea34fd223ee40e"
91
+ "gitHead": "1db0ab5d776be443d6739892d31d746d4d2124ae"
92
92
  }
@@ -11,7 +11,7 @@
11
11
  // See the License for the specific language governing permissions and
12
12
  // limitations under the License.
13
13
 
14
- import {useState} from 'react';
14
+ import {useCallback, useState} from 'react';
15
15
 
16
16
  import {QueryServiceClient} from '@parca/client';
17
17
  import type {NavigateFunction} from '@parca/utilities';
@@ -30,7 +30,14 @@ const ProfileExplorerSingle = ({
30
30
  navigateTo,
31
31
  }: ProfileExplorerSingleProps): JSX.Element => {
32
32
  const [showMetricsGraph, setShowMetricsGraph] = useState(true);
33
- const {profileSource} = useQueryState({suffix: '_a'});
33
+ const {profileSource, setDraftTimeRange, commitDraft} = useQueryState({suffix: '_a'});
34
+
35
+ const handleSwitchToFifteenMinutes = useCallback(() => {
36
+ const now = Date.now();
37
+ const from = now - 900_000; // 15 minutes ago
38
+ setDraftTimeRange(from, now, 'relative:minute|15');
39
+ commitDraft({from, to: now, timeSelection: 'relative:minute|15'});
40
+ }, [setDraftTimeRange, commitDraft]);
34
41
 
35
42
  return (
36
43
  <>
@@ -48,7 +55,11 @@ const ProfileExplorerSingle = ({
48
55
  </div>
49
56
 
50
57
  {profileSource != null && (
51
- <ProfileViewWithData queryClient={queryClient} profileSource={profileSource} />
58
+ <ProfileViewWithData
59
+ queryClient={queryClient}
60
+ profileSource={profileSource}
61
+ onSwitchToFifteenMinutes={handleSwitchToFifteenMinutes}
62
+ />
52
63
  )}
53
64
  </>
54
65
  );
@@ -14,13 +14,20 @@
14
14
  import {useEffect, useMemo, useRef} from 'react';
15
15
 
16
16
  import {LabelSet, QueryRequest_ReportType, QueryServiceClient} from '@parca/client';
17
- import {useURLState, useURLStateCustom, type OptionsCustom} from '@parca/components';
17
+ import {
18
+ Button,
19
+ useParcaContext,
20
+ useURLState,
21
+ useURLStateCustom,
22
+ type OptionsCustom,
23
+ } from '@parca/components';
18
24
  import {Matcher, MatcherTypes, ProfileType, Query} from '@parca/parser';
19
25
  import {TimeUnits, formatDate, formatDuration} from '@parca/utilities';
20
26
 
21
27
  import ProfileFlameGraph, {validateFlameChartQuery} from '../ProfileFlameGraph';
22
28
  import {boundsFromProfileSource} from '../ProfileFlameGraph/FlameGraphArrow/utils';
23
29
  import {MergedProfileSource, ProfileSource, timeFormat} from '../ProfileSource';
30
+ import {useProfileFilters} from '../ProfileView/components/ProfileFilters/useProfileFilters';
24
31
  import type {SamplesData} from '../ProfileView/types/visualization';
25
32
  import {useQuery} from '../useQuery';
26
33
  import {NumberDuo} from '../utils';
@@ -76,6 +83,7 @@ interface ProfileFlameChartProps {
76
83
  isHalfScreen: boolean;
77
84
  metadataMappingFiles?: string[];
78
85
  metadataLoading?: boolean;
86
+ onSwitchToFifteenMinutes?: () => void;
79
87
  }
80
88
 
81
89
  // Helper to create a filtered profile source with narrowed time bounds
@@ -118,7 +126,10 @@ export const ProfileFlameChart = ({
118
126
  isHalfScreen,
119
127
  metadataMappingFiles,
120
128
  metadataLoading,
129
+ onSwitchToFifteenMinutes,
121
130
  }: ProfileFlameChartProps): JSX.Element => {
131
+ const {enableFlamechartFiltering} = useParcaContext();
132
+ const {protoFilters} = useProfileFilters();
122
133
  const zoomControlsRef = useRef<HTMLDivElement>(null);
123
134
 
124
135
  const [selectedTimeframe, setSelectedTimeframe] = useURLStateCustom<
@@ -176,6 +187,7 @@ export const ProfileFlameChart = ({
176
187
  QueryRequest_ReportType.FLAMECHART,
177
188
  {
178
189
  skip: selectedTimeframe == null || filteredProfileSource == null,
190
+ ...(enableFlamechartFiltering === true ? {protoFilters} : {}),
179
191
  }
180
192
  );
181
193
 
@@ -202,9 +214,27 @@ export const ProfileFlameChart = ({
202
214
  return {cpus, data, stepMs};
203
215
  }, [samplesData?.series, samplesData?.stepMs]);
204
216
 
205
- const {isValid, isNonDelta} = validateFlameChartQuery(profileSource as MergedProfileSource);
217
+ const {isValid, isNonDelta, isDurationTooLong} = validateFlameChartQuery(
218
+ profileSource as MergedProfileSource
219
+ );
206
220
 
207
221
  if (!isValid) {
222
+ if (isDurationTooLong) {
223
+ return (
224
+ <div className="flex flex-col justify-center items-center p-10 text-center gap-4 text-sm">
225
+ <span>
226
+ Flame chart is unavailable for queries longer than 15 minutes. Try reducing the time
227
+ range to 15 minutes or selecting a point in the metrics graph.
228
+ </span>
229
+ {onSwitchToFifteenMinutes != null && (
230
+ <Button variant="primary" onClick={onSwitchToFifteenMinutes}>
231
+ Switch to last 15 minutes
232
+ </Button>
233
+ )}
234
+ </div>
235
+ );
236
+ }
237
+
208
238
  const message = isNonDelta
209
239
  ? 'To use the Flame chart, please switch to a Delta profile.'
210
240
  : 'Flame chart is unavailable for this query.';
@@ -74,9 +74,11 @@ const ErrorContent = ({errorMessage}: {errorMessage: string | ReactNode}): JSX.E
74
74
 
75
75
  export const validateFlameChartQuery = (
76
76
  profileSource: MergedProfileSource
77
- ): {isValid: boolean; isNonDelta: boolean} => {
77
+ ): {isValid: boolean; isNonDelta: boolean; isDurationTooLong: boolean} => {
78
78
  const isNonDelta = !profileSource.ProfileType().delta;
79
- return {isValid: !isNonDelta, isNonDelta};
79
+ const duration = profileSource.mergeTo - profileSource.mergeFrom;
80
+ const isDurationTooLong = duration > 900_000_000_000n; // 15 minutes in nanoseconds
81
+ return {isValid: !isNonDelta && !isDurationTooLong, isNonDelta, isDurationTooLong};
80
82
  };
81
83
 
82
84
  const ProfileFlameGraph = function ProfileFlameGraphNonMemo({
@@ -192,9 +194,13 @@ const ProfileFlameGraph = function ProfileFlameGraphNonMemo({
192
194
  }, [loadingState]);
193
195
 
194
196
  const flameGraph = useMemo(() => {
195
- const {isValid: isFlameChartValid, isNonDelta} = isFlameChart
197
+ const {
198
+ isValid: isFlameChartValid,
199
+ isNonDelta,
200
+ isDurationTooLong,
201
+ } = isFlameChart
196
202
  ? validateFlameChartQuery(profileSource as MergedProfileSource)
197
- : {isValid: true, isNonDelta: false};
203
+ : {isValid: true, isNonDelta: false, isDurationTooLong: false};
198
204
  const isInvalidFlameChartQuery = isFlameChart && !isFlameChartValid;
199
205
 
200
206
  if (isLoading && !isInvalidFlameChartQuery) {
@@ -222,6 +228,20 @@ const ProfileFlameGraph = function ProfileFlameGraphNonMemo({
222
228
  }
223
229
  />
224
230
  );
231
+ } else if (isDurationTooLong) {
232
+ return (
233
+ <ErrorContent
234
+ errorMessage={
235
+ <>
236
+ <span>
237
+ Flame chart is unavailable for queries longer than 15 minutes. Please select a
238
+ point in the metrics graph to continue.
239
+ </span>
240
+ {flamechartHelpText ?? null}
241
+ </>
242
+ }
243
+ />
244
+ );
225
245
  } else {
226
246
  return (
227
247
  <ErrorContent
@@ -50,6 +50,7 @@ interface GetDashboardItemProps {
50
50
  onRender?: ProfilerOnRenderCallback;
51
51
  };
52
52
  queryClient: QueryServiceClient;
53
+ onSwitchToFifteenMinutes?: () => void;
53
54
  }
54
55
 
55
56
  export const getDashboardItem = ({
@@ -68,6 +69,7 @@ export const getDashboardItem = ({
68
69
  setNewCurPathArrow,
69
70
  perf,
70
71
  queryClient,
72
+ onSwitchToFifteenMinutes,
71
73
  }: GetDashboardItemProps): JSX.Element => {
72
74
  switch (type) {
73
75
  case 'flamegraph':
@@ -122,6 +124,7 @@ export const getDashboardItem = ({
122
124
  isHalfScreen={isHalfScreen}
123
125
  metadataMappingFiles={flamegraphData.metadataMappingFiles}
124
126
  metadataLoading={flamegraphData.metadataLoading}
127
+ onSwitchToFifteenMinutes={onSwitchToFifteenMinutes}
125
128
  />
126
129
  );
127
130
  case 'table':
@@ -16,7 +16,7 @@ import {FC} from 'react';
16
16
  import {Icon} from '@iconify/react';
17
17
 
18
18
  import {QueryServiceClient} from '@parca/client';
19
- import {Button} from '@parca/components';
19
+ import {Button, useParcaContext} from '@parca/components';
20
20
  import {ProfileType} from '@parca/parser';
21
21
  import {TEST_IDS, testId} from '@parca/test-utils';
22
22
 
@@ -165,6 +165,8 @@ export const VisualisationToolbar: FC<VisualisationToolbarProps> = ({
165
165
  const isFlamechartViz = dashboardItems?.includes('flamechart');
166
166
  const isFlamechartVizOnly = dashboardItems?.length === 1 && isFlamechartViz;
167
167
 
168
+ const {enableFlamechartFiltering} = useParcaContext();
169
+
168
170
  const req = profileSource?.QueryRequest();
169
171
  if (req !== null && req !== undefined) {
170
172
  req.groupBy = {
@@ -202,7 +204,7 @@ export const VisualisationToolbar: FC<VisualisationToolbarProps> = ({
202
204
  )}
203
205
 
204
206
  <div className="flex mt-5">
205
- {!isFlamechartVizOnly && <ProfileFilters />}
207
+ {(!isFlamechartVizOnly || enableFlamechartFiltering === true) && <ProfileFilters />}
206
208
 
207
209
  {profileViewExternalSubActions != null ? profileViewExternalSubActions : null}
208
210
  </div>
@@ -46,6 +46,7 @@ export const ProfileView = ({
46
46
  compare,
47
47
  showVisualizationSelector,
48
48
  sandwichData,
49
+ onSwitchToFifteenMinutes,
49
50
  }: ProfileViewProps): JSX.Element => {
50
51
  const {
51
52
  timezone,
@@ -115,6 +116,7 @@ export const ProfileView = ({
115
116
  setNewCurPathArrow: setCurPathArrow,
116
117
  perf,
117
118
  queryClient,
119
+ onSwitchToFifteenMinutes,
118
120
  });
119
121
  };
120
122
 
@@ -84,4 +84,5 @@ export interface ProfileViewProps {
84
84
  onDownloadPProf: () => void;
85
85
  pprofDownloading?: boolean;
86
86
  showVisualizationSelector?: boolean;
87
+ onSwitchToFifteenMinutes?: () => void;
87
88
  }
@@ -43,12 +43,14 @@ interface ProfileViewWithDataProps {
43
43
  profileSource: ProfileSource;
44
44
  compare?: boolean;
45
45
  showVisualizationSelector?: boolean;
46
+ onSwitchToFifteenMinutes?: () => void;
46
47
  }
47
48
 
48
49
  export const ProfileViewWithData = ({
49
50
  queryClient,
50
51
  profileSource,
51
52
  showVisualizationSelector,
53
+ onSwitchToFifteenMinutes,
52
54
  }: ProfileViewWithDataProps): JSX.Element => {
53
55
  const metadata = useGrpcMetadata();
54
56
  const [dashboardItems, setDashboardItems] = useURLState<string[]>('dashboard_items', {
@@ -378,6 +380,7 @@ export const ProfileViewWithData = ({
378
380
  onDownloadPProf={() => void downloadPProfClick()}
379
381
  pprofDownloading={pprofDownloading}
380
382
  showVisualizationSelector={showVisualizationSelector}
383
+ onSwitchToFifteenMinutes={onSwitchToFifteenMinutes}
381
384
  />
382
385
  );
383
386
  };