@parca/profile 0.19.140 → 0.19.143
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.
- package/CHANGELOG.md +9 -1
- package/dist/GraphTooltipArrow/Content.js +224 -30
- package/dist/GraphTooltipArrow/DockedGraphTooltip/index.js +192 -33
- package/dist/GraphTooltipArrow/ExpandOnHoverValue.js +53 -3
- package/dist/GraphTooltipArrow/index.d.ts.map +1 -1
- package/dist/GraphTooltipArrow/index.js +86 -56
- package/dist/GraphTooltipArrow/useGraphTooltip/index.js +37 -37
- package/dist/GraphTooltipArrow/useGraphTooltipMetaInfo/index.js +94 -68
- package/dist/MatchersInput/SuggestionItem.js +91 -12
- package/dist/MatchersInput/SuggestionsList.d.ts +2 -1
- package/dist/MatchersInput/SuggestionsList.d.ts.map +1 -1
- package/dist/MatchersInput/SuggestionsList.js +371 -157
- package/dist/MatchersInput/SuggestionsList.test.d.ts +2 -0
- package/dist/MatchersInput/SuggestionsList.test.d.ts.map +1 -0
- package/dist/MatchersInput/index.js +308 -115
- package/dist/MetricsCircle/index.js +39 -3
- package/dist/MetricsGraph/MetricsContextMenu/index.js +119 -19
- package/dist/MetricsGraph/MetricsInfoPanel/index.js +81 -20
- package/dist/MetricsGraph/MetricsTooltip/index.d.ts.map +1 -1
- package/dist/MetricsGraph/MetricsTooltip/index.js +107 -74
- package/dist/MetricsGraph/index.js +552 -203
- package/dist/MetricsGraph/useMetricsGraphDimensions.js +46 -25
- package/dist/MetricsGraph/utils/colorMapping.js +24 -17
- package/dist/MetricsSeries/index.js +70 -7
- package/dist/PreSelectedMatchers/index.d.ts.map +1 -1
- package/dist/PreSelectedMatchers/index.js +249 -102
- package/dist/ProfileExplorer/ProfileExplorerCompare.d.ts.map +1 -1
- package/dist/ProfileExplorer/ProfileExplorerCompare.js +240 -45
- package/dist/ProfileExplorer/ProfileExplorerSingle.js +98 -11
- package/dist/ProfileExplorer/index.js +183 -32
- package/dist/ProfileFlameChart/SamplesStrips/SamplesGraph/index.js +333 -148
- package/dist/ProfileFlameChart/SamplesStrips/SamplesStrips.stories.js +69 -35
- package/dist/ProfileFlameChart/SamplesStrips/index.js +645 -134
- package/dist/ProfileFlameChart/SamplesStrips/labelSetUtils.js +114 -55
- package/dist/ProfileFlameChart/index.js +260 -126
- package/dist/ProfileFlameGraph/FlameGraphArrow/ContextMenu.js +283 -85
- package/dist/ProfileFlameGraph/FlameGraphArrow/ContextMenuWrapper.js +56 -20
- package/dist/ProfileFlameGraph/FlameGraphArrow/FlameGraphNodes.js +211 -140
- package/dist/ProfileFlameGraph/FlameGraphArrow/MemoizedTooltip.js +133 -38
- package/dist/ProfileFlameGraph/FlameGraphArrow/MiniMap.js +261 -216
- package/dist/ProfileFlameGraph/FlameGraphArrow/TextWithEllipsis.d.ts.map +1 -1
- package/dist/ProfileFlameGraph/FlameGraphArrow/TextWithEllipsis.js +71 -45
- package/dist/ProfileFlameGraph/FlameGraphArrow/TooltipContext.d.ts.map +1 -1
- package/dist/ProfileFlameGraph/FlameGraphArrow/TooltipContext.js +58 -28
- package/dist/ProfileFlameGraph/FlameGraphArrow/ZoomControls.d.ts.map +1 -1
- package/dist/ProfileFlameGraph/FlameGraphArrow/ZoomControls.js +59 -8
- package/dist/ProfileFlameGraph/FlameGraphArrow/index.js +396 -179
- package/dist/ProfileFlameGraph/FlameGraphArrow/useBatchedRendering.d.ts.map +1 -1
- package/dist/ProfileFlameGraph/FlameGraphArrow/useBatchedRendering.js +68 -50
- package/dist/ProfileFlameGraph/FlameGraphArrow/useMappingList.js +62 -38
- package/dist/ProfileFlameGraph/FlameGraphArrow/useNodeColor.js +14 -6
- package/dist/ProfileFlameGraph/FlameGraphArrow/useScrollViewport.js +124 -82
- package/dist/ProfileFlameGraph/FlameGraphArrow/useVisibleNodes.js +160 -98
- package/dist/ProfileFlameGraph/FlameGraphArrow/useZoom.js +232 -112
- package/dist/ProfileFlameGraph/FlameGraphArrow/utils.js +137 -114
- package/dist/ProfileFlameGraph/benchmarks/benchdata/populateData.js +85 -0
- package/dist/ProfileFlameGraph/index.js +322 -147
- package/dist/ProfileMetricsGraph/hooks/useQueryRange.js +140 -32
- package/dist/ProfileMetricsGraph/index.js +515 -256
- package/dist/ProfileSelector/CompareButton.js +132 -12
- package/dist/ProfileSelector/MetricsGraphSection.js +228 -63
- package/dist/ProfileSelector/index.d.ts +1 -1
- package/dist/ProfileSelector/index.d.ts.map +1 -1
- package/dist/ProfileSelector/index.js +734 -142
- package/dist/ProfileSelector/useAutoQuerySelector.d.ts +1 -3
- package/dist/ProfileSelector/useAutoQuerySelector.d.ts.map +1 -1
- package/dist/ProfileSelector/useAutoQuerySelector.js +280 -132
- package/dist/ProfileSource.js +230 -163
- package/dist/ProfileTypeSelector/index.js +214 -125
- package/dist/ProfileView/components/ActionButtons/GroupByDropdown.js +50 -4
- package/dist/ProfileView/components/ActionButtons/SortByDropdown.js +137 -32
- package/dist/ProfileView/components/ColorStackLegend.js +182 -54
- package/dist/ProfileView/components/DashboardItems/index.js +87 -28
- package/dist/ProfileView/components/DashboardLayout/index.js +108 -16
- package/dist/ProfileView/components/DiffLegend.js +172 -29
- package/dist/ProfileView/components/GroupByLabelsDropdown/index.js +199 -55
- package/dist/ProfileView/components/InvertCallStack/index.js +97 -9
- package/dist/ProfileView/components/ProfileFilters/filterPresets.js +260 -315
- package/dist/ProfileView/components/ProfileFilters/index.js +518 -215
- package/dist/ProfileView/components/ProfileFilters/useProfileFilters.js +370 -306
- package/dist/ProfileView/components/ProfileFilters/useProfileFiltersUrlState.js +191 -118
- package/dist/ProfileView/components/ProfileHeader/index.js +105 -11
- package/dist/ProfileView/components/ShareButton/ResultBox.js +119 -16
- package/dist/ProfileView/components/ShareButton/index.js +352 -62
- package/dist/ProfileView/components/Toolbars/MultiLevelDropdown.d.ts.map +1 -1
- package/dist/ProfileView/components/Toolbars/MultiLevelDropdown.js +664 -192
- package/dist/ProfileView/components/Toolbars/SwitchMenuItem.js +94 -7
- package/dist/ProfileView/components/Toolbars/TableColumnsDropdown.js +196 -155
- package/dist/ProfileView/components/Toolbars/index.js +441 -21
- package/dist/ProfileView/components/ViewSelector/Dropdown.js +233 -22
- package/dist/ProfileView/components/ViewSelector/index.js +186 -82
- package/dist/ProfileView/components/VisualizationContainer/index.d.ts.map +1 -1
- package/dist/ProfileView/components/VisualizationContainer/index.js +52 -7
- package/dist/ProfileView/components/VisualizationPanel.js +185 -8
- package/dist/ProfileView/context/DashboardContext.js +74 -26
- package/dist/ProfileView/context/ProfileViewContext.js +56 -15
- package/dist/ProfileView/hooks/useAutoSelectDimension.js +71 -41
- package/dist/ProfileView/hooks/useProfileMetadata.js +50 -18
- package/dist/ProfileView/hooks/useResetFlameGraphState.js +31 -10
- package/dist/ProfileView/hooks/useResetStateOnProfileTypeChange.js +71 -27
- package/dist/ProfileView/hooks/useResetStateOnSeriesChange.js +53 -17
- package/dist/ProfileView/hooks/useVisualizationState.js +229 -69
- package/dist/ProfileView/index.js +383 -45
- package/dist/ProfileView/types/visualization.js +1 -13
- package/dist/ProfileView/utils/colorUtils.js +8 -7
- package/dist/ProfileViewWithData.js +319 -225
- package/dist/QueryControls/index.js +418 -47
- package/dist/Sandwich/components/CalleesSection.js +54 -4
- package/dist/Sandwich/components/CallersSection.js +97 -27
- package/dist/Sandwich/components/TableSection.js +77 -4
- package/dist/Sandwich/index.js +125 -12
- package/dist/Sandwich/utils/processRowData.js +48 -39
- package/dist/SelectWithRefresh/index.js +102 -28
- package/dist/SimpleMatchers/Select.js +520 -187
- package/dist/SimpleMatchers/index.js +590 -288
- package/dist/SourceView/Highlighter.js +230 -70
- package/dist/SourceView/LineNo.js +72 -17
- package/dist/SourceView/index.js +177 -101
- package/dist/SourceView/lang-detector/ext-to-lang.json +798 -798
- package/dist/SourceView/lang-detector/index.js +28 -14
- package/dist/SourceView/useSelectedLineRange.js +72 -20
- package/dist/Table/ColorCell.js +42 -1
- package/dist/Table/ColumnsVisibility.js +114 -6
- package/dist/Table/MoreDropdown.js +107 -21
- package/dist/Table/TableContextMenu.js +144 -134
- package/dist/Table/TableContextMenuWrapper.js +59 -14
- package/dist/Table/hooks/useColorManagement.js +58 -16
- package/dist/Table/hooks/useTableConfiguration.d.ts.map +1 -1
- package/dist/Table/hooks/useTableConfiguration.js +323 -167
- package/dist/Table/index.js +217 -123
- package/dist/Table/utils/functions.js +169 -144
- package/dist/Table/utils/topAndBottomExpandedRowModel.js +69 -52
- package/dist/TimelineGuide/index.js +209 -16
- package/dist/TopTable/benchmarks/benchdata/populateData.js +91 -0
- package/dist/TopTable/index.js +325 -121
- package/dist/contexts/LabelsQueryProvider.js +94 -32
- package/dist/contexts/UnifiedLabelsContext.js +114 -49
- package/dist/contexts/utils.js +37 -15
- package/dist/hooks/urlParsers.js +27 -15
- package/dist/hooks/useColorBy.js +47 -10
- package/dist/hooks/useCompareModeMeta.js +112 -62
- package/dist/hooks/useDashboardItems.js +52 -11
- package/dist/hooks/useLabels.js +295 -52
- package/dist/hooks/useQueryState.d.ts +1 -1
- package/dist/hooks/useQueryState.d.ts.map +1 -1
- package/dist/hooks/useQueryState.js +375 -329
- package/dist/index.js +11 -6
- package/dist/testdata/fg-diff.json +3750 -0
- package/dist/testdata/fg-simple.json +1879 -0
- package/dist/testdata/link_data.json +56 -0
- package/dist/testdata/tabular.json +30 -0
- package/dist/testdata/test_flamegraph.json +26846 -0
- package/dist/testdata/test_graph.json +53 -0
- package/dist/useDelayedLoader.js +32 -18
- package/dist/useGrpcQuery/index.js +71 -11
- package/dist/useHasProfileData.js +90 -12
- package/dist/useQuery.js +205 -64
- package/dist/useSumBy.d.ts.map +1 -1
- package/dist/useSumBy.js +294 -138
- package/dist/utils.js +62 -30
- package/package.json +9 -9
- package/src/GraphTooltipArrow/index.tsx +3 -0
- package/src/MatchersInput/SuggestionsList.test.tsx +70 -0
- package/src/MatchersInput/SuggestionsList.tsx +11 -10
- package/src/MatchersInput/index.tsx +1 -1
- package/src/MetricsGraph/MetricsTooltip/index.tsx +22 -34
- package/src/PreSelectedMatchers/index.tsx +3 -0
- package/src/ProfileExplorer/ProfileExplorerCompare.tsx +9 -2
- package/src/ProfileFlameGraph/FlameGraphArrow/TextWithEllipsis.tsx +3 -0
- package/src/ProfileFlameGraph/FlameGraphArrow/TooltipContext.tsx +3 -0
- package/src/ProfileFlameGraph/FlameGraphArrow/ZoomControls.tsx +3 -0
- package/src/ProfileFlameGraph/FlameGraphArrow/useBatchedRendering.ts +3 -0
- package/src/ProfileSelector/index.tsx +31 -9
- package/src/ProfileSelector/useAutoQuerySelector.ts +64 -42
- package/src/ProfileView/components/Toolbars/MultiLevelDropdown.tsx +3 -0
- package/src/ProfileView/components/VisualizationContainer/index.tsx +3 -0
- package/src/Table/hooks/useTableConfiguration.tsx +7 -13
- package/src/hooks/useQueryState.ts +18 -3
- package/src/useDelayedLoader.ts +10 -10
- package/src/useSumBy.ts +12 -18
- package/dist/ProfileView/components/ProfileFilters/useProfileFiltersUrlState.test.js +0 -455
- package/dist/hooks/useQueryState.test.js +0 -868
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
|
|
2
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
3
|
+
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
|
|
4
|
+
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
|
|
5
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
6
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
7
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
8
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
9
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
10
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
11
|
+
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
12
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
13
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
14
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
15
|
+
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
|
|
16
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
17
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
1
18
|
// Copyright 2022 The Parca Authors
|
|
2
19
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
20
|
// you may not use this file except in compliance with the License.
|
|
@@ -10,325 +27,372 @@
|
|
|
10
27
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
28
|
// See the License for the specific language governing permissions and
|
|
12
29
|
// limitations under the License.
|
|
30
|
+
|
|
13
31
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
14
32
|
import { useResetFlameGraphState } from '../../hooks/useResetFlameGraphState';
|
|
15
33
|
import { getPresetByKey, isPresetKey } from './filterPresets';
|
|
16
34
|
import { useProfileFiltersUrlState } from './useProfileFiltersUrlState';
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
var createStringCondition = function createStringCondition(matchType, value) {
|
|
36
|
+
return {
|
|
37
|
+
condition: matchType === 'equal' ? {
|
|
38
|
+
oneofKind: 'equal',
|
|
39
|
+
equal: value
|
|
40
|
+
} : matchType === 'not_equal' ? {
|
|
41
|
+
oneofKind: 'notEqual',
|
|
42
|
+
notEqual: value
|
|
43
|
+
} : matchType === 'contains' ? {
|
|
44
|
+
oneofKind: 'contains',
|
|
45
|
+
contains: value
|
|
46
|
+
} : matchType === 'not_contains' ? {
|
|
47
|
+
oneofKind: 'notContains',
|
|
48
|
+
notContains: value
|
|
49
|
+
} : matchType === 'starts_with' ? {
|
|
50
|
+
oneofKind: 'startsWith',
|
|
51
|
+
startsWith: value
|
|
52
|
+
} : matchType === 'not_starts_with' ? {
|
|
53
|
+
oneofKind: 'notStartsWith',
|
|
54
|
+
notStartsWith: value
|
|
55
|
+
} : {
|
|
56
|
+
oneofKind: 'notContains',
|
|
57
|
+
notContains: value
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
var createNumberCondition = function createNumberCondition(matchType, value) {
|
|
62
|
+
return {
|
|
63
|
+
condition: matchType === 'equal' ? {
|
|
64
|
+
oneofKind: 'equal',
|
|
65
|
+
equal: value
|
|
66
|
+
} : {
|
|
67
|
+
oneofKind: 'notEqual',
|
|
68
|
+
notEqual: value
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
|
|
37
73
|
// Convert protobuf Filter[] back to ProfileFilter[] format for editing
|
|
38
|
-
export
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
74
|
+
export var convertFromProtoFilters = function convertFromProtoFilters(protoFilters) {
|
|
75
|
+
var _conditionObj$conditi2, _conditionObj$conditi3;
|
|
76
|
+
var profileFilters = [];
|
|
77
|
+
var _iterator = _createForOfIteratorHelper(protoFilters.entries()),
|
|
78
|
+
_step;
|
|
79
|
+
try {
|
|
80
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
81
|
+
var _filter$stackFilter, _filter$frameFilter;
|
|
82
|
+
var _step$value = _slicedToArray(_step.value, 2),
|
|
83
|
+
index = _step$value[0],
|
|
84
|
+
protoFilter = _step$value[1];
|
|
85
|
+
if ((protoFilter === null || protoFilter === void 0 ? void 0 : protoFilter.filter) == null) continue;
|
|
86
|
+
var filter = protoFilter.filter;
|
|
87
|
+
var type = void 0;
|
|
88
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
89
|
+
var criteria = void 0;
|
|
90
|
+
if (filter.oneofKind === 'stackFilter' && ((_filter$stackFilter = filter.stackFilter) === null || _filter$stackFilter === void 0 || (_filter$stackFilter = _filter$stackFilter.filter) === null || _filter$stackFilter === void 0 ? void 0 : _filter$stackFilter.oneofKind) === 'criteria') {
|
|
91
|
+
type = 'stack';
|
|
92
|
+
criteria = filter.stackFilter.filter.criteria;
|
|
93
|
+
} else if (filter.oneofKind === 'frameFilter' && ((_filter$frameFilter = filter.frameFilter) === null || _filter$frameFilter === void 0 || (_filter$frameFilter = _filter$frameFilter.filter) === null || _filter$frameFilter === void 0 ? void 0 : _filter$frameFilter.oneofKind) === 'criteria') {
|
|
94
|
+
type = 'frame';
|
|
95
|
+
criteria = filter.frameFilter.filter.criteria;
|
|
96
|
+
} else {
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
for (var _i = 0, _Object$entries = Object.entries(criteria); _i < _Object$entries.length; _i++) {
|
|
100
|
+
var _conditionObj$conditi, _fieldMap$fieldName;
|
|
101
|
+
var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
|
|
102
|
+
fieldName = _Object$entries$_i[0],
|
|
103
|
+
condition = _Object$entries$_i[1];
|
|
104
|
+
if (condition === undefined || _typeof(condition) !== 'object') continue;
|
|
105
|
+
var conditionObj = condition;
|
|
106
|
+
if (((_conditionObj$conditi = conditionObj.condition) === null || _conditionObj$conditi === void 0 ? void 0 : _conditionObj$conditi.oneofKind) === undefined) continue;
|
|
107
|
+
var matchType = void 0;
|
|
108
|
+
var value = void 0;
|
|
109
|
+
switch (conditionObj.condition.oneofKind) {
|
|
110
|
+
case 'equal':
|
|
111
|
+
matchType = 'equal';
|
|
112
|
+
value = String(conditionObj.condition.equal);
|
|
113
|
+
break;
|
|
114
|
+
case 'notEqual':
|
|
115
|
+
matchType = 'not_equal';
|
|
116
|
+
value = String(conditionObj.condition.notEqual);
|
|
117
|
+
break;
|
|
118
|
+
case 'contains':
|
|
119
|
+
matchType = 'contains';
|
|
120
|
+
value = (_conditionObj$conditi2 = conditionObj.condition.contains) !== null && _conditionObj$conditi2 !== void 0 ? _conditionObj$conditi2 : '';
|
|
121
|
+
break;
|
|
122
|
+
case 'notContains':
|
|
123
|
+
matchType = 'not_contains';
|
|
124
|
+
value = (_conditionObj$conditi3 = conditionObj.condition.notContains) !== null && _conditionObj$conditi3 !== void 0 ? _conditionObj$conditi3 : '';
|
|
125
|
+
break;
|
|
126
|
+
default:
|
|
58
127
|
continue;
|
|
59
128
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
case 'contains':
|
|
78
|
-
matchType = 'contains';
|
|
79
|
-
value = conditionObj.condition.contains ?? '';
|
|
80
|
-
break;
|
|
81
|
-
case 'notContains':
|
|
82
|
-
matchType = 'not_contains';
|
|
83
|
-
value = conditionObj.condition.notContains ?? '';
|
|
84
|
-
break;
|
|
85
|
-
default:
|
|
86
|
-
continue;
|
|
87
|
-
}
|
|
88
|
-
const fieldMap = {
|
|
89
|
-
functionName: 'function_name',
|
|
90
|
-
binary: 'binary',
|
|
91
|
-
systemName: 'system_name',
|
|
92
|
-
filename: 'filename',
|
|
93
|
-
address: 'address',
|
|
94
|
-
lineNumber: 'line_number',
|
|
95
|
-
};
|
|
96
|
-
const field = fieldMap[fieldName] ?? fieldName;
|
|
97
|
-
profileFilters.push({
|
|
98
|
-
id: `parsed-${index}-${fieldName}`,
|
|
99
|
-
type: type,
|
|
100
|
-
field: field,
|
|
101
|
-
matchType: matchType,
|
|
102
|
-
value,
|
|
103
|
-
});
|
|
104
|
-
}
|
|
129
|
+
var fieldMap = {
|
|
130
|
+
functionName: 'function_name',
|
|
131
|
+
binary: 'binary',
|
|
132
|
+
systemName: 'system_name',
|
|
133
|
+
filename: 'filename',
|
|
134
|
+
address: 'address',
|
|
135
|
+
lineNumber: 'line_number'
|
|
136
|
+
};
|
|
137
|
+
var field = (_fieldMap$fieldName = fieldMap[fieldName]) !== null && _fieldMap$fieldName !== void 0 ? _fieldMap$fieldName : fieldName;
|
|
138
|
+
profileFilters.push({
|
|
139
|
+
id: "parsed-".concat(index, "-").concat(fieldName),
|
|
140
|
+
type: type,
|
|
141
|
+
field: field,
|
|
142
|
+
matchType: matchType,
|
|
143
|
+
value: value
|
|
144
|
+
});
|
|
145
|
+
}
|
|
105
146
|
}
|
|
106
|
-
|
|
147
|
+
} catch (err) {
|
|
148
|
+
_iterator.e(err);
|
|
149
|
+
} finally {
|
|
150
|
+
_iterator.f();
|
|
151
|
+
}
|
|
152
|
+
return profileFilters;
|
|
107
153
|
};
|
|
154
|
+
|
|
108
155
|
// Convert ProfileFilter[] to protobuf Filter[] matching the expected structure
|
|
109
|
-
export
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
// Regular filter, add as is
|
|
128
|
-
expandedFilters.push(filter);
|
|
156
|
+
export var convertToProtoFilters = function convertToProtoFilters(profileFilters) {
|
|
157
|
+
// First, expand any preset filters to their constituent filters
|
|
158
|
+
var expandedFilters = [];
|
|
159
|
+
var _iterator2 = _createForOfIteratorHelper(profileFilters),
|
|
160
|
+
_step2;
|
|
161
|
+
try {
|
|
162
|
+
var _loop = function _loop() {
|
|
163
|
+
var filter = _step2.value;
|
|
164
|
+
if (filter.type != null && isPresetKey(filter.type)) {
|
|
165
|
+
// This is a preset filter, expand it
|
|
166
|
+
var preset = getPresetByKey(filter.type);
|
|
167
|
+
if (preset != null) {
|
|
168
|
+
preset.filters.forEach(function (presetFilter, index) {
|
|
169
|
+
expandedFilters.push(_objectSpread(_objectSpread({}, presetFilter), {}, {
|
|
170
|
+
id: "".concat(filter.id, "-expanded-").concat(index),
|
|
171
|
+
value: presetFilter.value
|
|
172
|
+
}));
|
|
173
|
+
});
|
|
129
174
|
}
|
|
175
|
+
} else {
|
|
176
|
+
// Regular filter, add as is
|
|
177
|
+
expandedFilters.push(filter);
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
181
|
+
_loop();
|
|
130
182
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
return {
|
|
177
|
-
filter: {
|
|
178
|
-
oneofKind: 'frameFilter',
|
|
179
|
-
frameFilter: {
|
|
180
|
-
filter: {
|
|
181
|
-
oneofKind: 'criteria',
|
|
182
|
-
criteria,
|
|
183
|
-
},
|
|
184
|
-
},
|
|
185
|
-
},
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
});
|
|
189
|
-
};
|
|
190
|
-
export const useProfileFilters = () => {
|
|
191
|
-
const { appliedFilters, setAppliedFilters, forceApplyFilters } = useProfileFiltersUrlState();
|
|
192
|
-
const resetFlameGraphState = useResetFlameGraphState();
|
|
193
|
-
const [localFilters, setLocalFilters] = useState(appliedFilters ?? []);
|
|
194
|
-
const lastAppliedFiltersRef = useRef([]);
|
|
195
|
-
const localFiltersRef = useRef(localFilters);
|
|
196
|
-
localFiltersRef.current = localFilters;
|
|
197
|
-
useEffect(() => {
|
|
198
|
-
const currentApplied = appliedFilters ?? [];
|
|
199
|
-
const lastApplied = lastAppliedFiltersRef.current;
|
|
200
|
-
// Check if appliedFilters actually changed (avoid circular updates)
|
|
201
|
-
const appliedChanged = currentApplied.length !== lastApplied.length ||
|
|
202
|
-
currentApplied.some((applied, index) => {
|
|
203
|
-
const last = lastApplied[index];
|
|
204
|
-
return (last == null ||
|
|
205
|
-
applied.type !== last.type ||
|
|
206
|
-
applied.field !== last.field ||
|
|
207
|
-
applied.matchType !== last.matchType ||
|
|
208
|
-
applied.value !== last.value);
|
|
209
|
-
});
|
|
210
|
-
if (!appliedChanged) {
|
|
211
|
-
return;
|
|
212
|
-
}
|
|
213
|
-
lastAppliedFiltersRef.current = currentApplied;
|
|
214
|
-
setLocalFilters(currentApplied);
|
|
215
|
-
}, [appliedFilters]);
|
|
216
|
-
const hasUnsavedChanges = useMemo(() => {
|
|
217
|
-
const localWithValues = localFilters.filter(f => {
|
|
218
|
-
// For preset filters, only need type and value
|
|
219
|
-
if (f.type != null && isPresetKey(f.type)) {
|
|
220
|
-
return f.value !== '' && f.type != null;
|
|
221
|
-
}
|
|
222
|
-
// For regular filters, need all fields
|
|
223
|
-
return f.value !== '' && f.type != null && f.field != null && f.matchType != null;
|
|
224
|
-
});
|
|
225
|
-
const appliedWithValues = (appliedFilters ?? []).filter(f => {
|
|
226
|
-
// For preset filters, only need type and value
|
|
227
|
-
if (f.type != null && isPresetKey(f.type)) {
|
|
228
|
-
return f.value !== '' && f.type != null;
|
|
183
|
+
} catch (err) {
|
|
184
|
+
_iterator2.e(err);
|
|
185
|
+
} finally {
|
|
186
|
+
_iterator2.f();
|
|
187
|
+
}
|
|
188
|
+
return expandedFilters.filter(function (f) {
|
|
189
|
+
return f.value !== '' && f.type != null && f.field != null && f.matchType != null;
|
|
190
|
+
}) // Only include complete filters with values
|
|
191
|
+
.map(function (f) {
|
|
192
|
+
// Build the condition based on field type
|
|
193
|
+
var isNumberField = f.field === 'address' || f.field === 'line_number';
|
|
194
|
+
var condition = isNumberField ? createNumberCondition(f.matchType, BigInt(f.value)) : createStringCondition(f.matchType, f.value);
|
|
195
|
+
|
|
196
|
+
// Create FilterCriteria
|
|
197
|
+
var criteria = {};
|
|
198
|
+
switch (f.field) {
|
|
199
|
+
case 'function_name':
|
|
200
|
+
criteria.functionName = condition;
|
|
201
|
+
break;
|
|
202
|
+
case 'binary':
|
|
203
|
+
criteria.binary = condition;
|
|
204
|
+
break;
|
|
205
|
+
case 'system_name':
|
|
206
|
+
criteria.systemName = condition;
|
|
207
|
+
break;
|
|
208
|
+
case 'filename':
|
|
209
|
+
criteria.filename = condition;
|
|
210
|
+
break;
|
|
211
|
+
case 'address':
|
|
212
|
+
criteria.address = condition;
|
|
213
|
+
break;
|
|
214
|
+
case 'line_number':
|
|
215
|
+
criteria.lineNumber = condition;
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Create the appropriate filter type with proper oneofKind structure
|
|
220
|
+
if (f.type === 'stack') {
|
|
221
|
+
return {
|
|
222
|
+
filter: {
|
|
223
|
+
oneofKind: 'stackFilter',
|
|
224
|
+
stackFilter: {
|
|
225
|
+
filter: {
|
|
226
|
+
oneofKind: 'criteria',
|
|
227
|
+
criteria: criteria
|
|
229
228
|
}
|
|
230
|
-
|
|
231
|
-
return f.value !== '' && f.type != null && f.field != null && f.matchType != null;
|
|
232
|
-
});
|
|
233
|
-
if (localWithValues.length !== appliedWithValues.length)
|
|
234
|
-
return true;
|
|
235
|
-
return !localWithValues.every((local, index) => {
|
|
236
|
-
const applied = appliedWithValues[index];
|
|
237
|
-
return (local.type === applied?.type &&
|
|
238
|
-
local.field === applied?.field &&
|
|
239
|
-
local.matchType === applied?.matchType &&
|
|
240
|
-
local.value === applied?.value);
|
|
241
|
-
});
|
|
242
|
-
}, [localFilters, appliedFilters]);
|
|
243
|
-
const addFilter = useCallback(() => {
|
|
244
|
-
const newFilter = {
|
|
245
|
-
id: `filter-${Date.now()}-${Math.random()}`,
|
|
246
|
-
value: '',
|
|
247
|
-
};
|
|
248
|
-
setLocalFilters([...localFiltersRef.current, newFilter]);
|
|
249
|
-
}, []);
|
|
250
|
-
const excludeBinary = useCallback((binaryName) => {
|
|
251
|
-
// Check if this binary is already being filtered with not_contains
|
|
252
|
-
const existingFilter = (appliedFilters ?? []).find(f => f.type === 'frame' &&
|
|
253
|
-
f.field === 'binary' &&
|
|
254
|
-
f.matchType === 'not_contains' &&
|
|
255
|
-
f.value === binaryName);
|
|
256
|
-
if (existingFilter != null) {
|
|
257
|
-
return; // Already exists, don't add duplicate
|
|
229
|
+
}
|
|
258
230
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
const filtersToApply = [...(appliedFilters ?? []), newFilter];
|
|
269
|
-
setAppliedFilters(filtersToApply);
|
|
270
|
-
resetFlameGraphState();
|
|
271
|
-
},
|
|
272
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
273
|
-
[setAppliedFilters, resetFlameGraphState]);
|
|
274
|
-
const removeExcludeBinary = useCallback((binaryName) => {
|
|
275
|
-
// Search for the exclude filter (not_contains) for this binary
|
|
276
|
-
const filterToRemove = (appliedFilters ?? []).find(f => f.type === 'frame' &&
|
|
277
|
-
f.field === 'binary' &&
|
|
278
|
-
f.matchType === 'not_contains' &&
|
|
279
|
-
f.value === binaryName);
|
|
280
|
-
if (filterToRemove != null) {
|
|
281
|
-
// Remove the filter from applied filters
|
|
282
|
-
const updatedAppliedFilters = (appliedFilters ?? []).filter(f => f.id !== filterToRemove.id);
|
|
283
|
-
setAppliedFilters(updatedAppliedFilters);
|
|
284
|
-
resetFlameGraphState();
|
|
285
|
-
// Also remove from local filters
|
|
286
|
-
setLocalFilters(localFiltersRef.current.filter(f => f.id !== filterToRemove.id));
|
|
287
|
-
}
|
|
288
|
-
}, [appliedFilters, setAppliedFilters, resetFlameGraphState]);
|
|
289
|
-
const removeFilter = useCallback((id) => {
|
|
290
|
-
setLocalFilters(localFiltersRef.current.filter(f => f.id !== id));
|
|
291
|
-
}, []);
|
|
292
|
-
const updateFilter = useCallback((id, updates) => {
|
|
293
|
-
setLocalFilters(localFiltersRef.current.map(f => (f.id === id ? { ...f, ...updates } : f)));
|
|
294
|
-
}, []);
|
|
295
|
-
const resetFilters = useCallback(() => {
|
|
296
|
-
setLocalFilters([]);
|
|
297
|
-
setAppliedFilters([]);
|
|
298
|
-
resetFlameGraphState();
|
|
299
|
-
}, [setAppliedFilters, resetFlameGraphState]);
|
|
300
|
-
const onApplyFilters = useCallback(() => {
|
|
301
|
-
const validFilters = localFiltersRef.current.filter(f => {
|
|
302
|
-
// For preset filters, only need type and value
|
|
303
|
-
if (f.type != null && isPresetKey(f.type)) {
|
|
304
|
-
return f.value !== '' && f.type != null;
|
|
231
|
+
};
|
|
232
|
+
} else {
|
|
233
|
+
return {
|
|
234
|
+
filter: {
|
|
235
|
+
oneofKind: 'frameFilter',
|
|
236
|
+
frameFilter: {
|
|
237
|
+
filter: {
|
|
238
|
+
oneofKind: 'criteria',
|
|
239
|
+
criteria: criteria
|
|
305
240
|
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
id: `filter-${Date.now()}-${index}`,
|
|
312
|
-
}));
|
|
313
|
-
setAppliedFilters(filtersToApply);
|
|
314
|
-
resetFlameGraphState();
|
|
315
|
-
}, [setAppliedFilters, resetFlameGraphState]);
|
|
316
|
-
const protoFilters = useMemo(() => {
|
|
317
|
-
return convertToProtoFilters(appliedFilters ?? []);
|
|
318
|
-
}, [appliedFilters]);
|
|
319
|
-
return {
|
|
320
|
-
localFilters,
|
|
321
|
-
appliedFilters: appliedFilters ?? [],
|
|
322
|
-
protoFilters,
|
|
323
|
-
hasUnsavedChanges,
|
|
324
|
-
onApplyFilters,
|
|
325
|
-
addFilter,
|
|
326
|
-
excludeBinary,
|
|
327
|
-
removeExcludeBinary,
|
|
328
|
-
removeFilter,
|
|
329
|
-
updateFilter,
|
|
330
|
-
resetFilters,
|
|
331
|
-
setAppliedFilters,
|
|
332
|
-
forceApplyFilters,
|
|
333
|
-
};
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
});
|
|
334
246
|
};
|
|
247
|
+
export var useProfileFilters = function useProfileFilters() {
|
|
248
|
+
var _useProfileFiltersUrl = useProfileFiltersUrlState(),
|
|
249
|
+
appliedFilters = _useProfileFiltersUrl.appliedFilters,
|
|
250
|
+
setAppliedFilters = _useProfileFiltersUrl.setAppliedFilters,
|
|
251
|
+
forceApplyFilters = _useProfileFiltersUrl.forceApplyFilters;
|
|
252
|
+
var resetFlameGraphState = useResetFlameGraphState();
|
|
253
|
+
var _useState = useState(appliedFilters !== null && appliedFilters !== void 0 ? appliedFilters : []),
|
|
254
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
255
|
+
localFilters = _useState2[0],
|
|
256
|
+
setLocalFilters = _useState2[1];
|
|
257
|
+
var lastAppliedFiltersRef = useRef([]);
|
|
258
|
+
var localFiltersRef = useRef(localFilters);
|
|
259
|
+
localFiltersRef.current = localFilters;
|
|
260
|
+
useEffect(function () {
|
|
261
|
+
var currentApplied = appliedFilters !== null && appliedFilters !== void 0 ? appliedFilters : [];
|
|
262
|
+
var lastApplied = lastAppliedFiltersRef.current;
|
|
263
|
+
|
|
264
|
+
// Check if appliedFilters actually changed (avoid circular updates)
|
|
265
|
+
var appliedChanged = currentApplied.length !== lastApplied.length || currentApplied.some(function (applied, index) {
|
|
266
|
+
var last = lastApplied[index];
|
|
267
|
+
return last == null || applied.type !== last.type || applied.field !== last.field || applied.matchType !== last.matchType || applied.value !== last.value;
|
|
268
|
+
});
|
|
269
|
+
if (!appliedChanged) {
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
lastAppliedFiltersRef.current = currentApplied;
|
|
273
|
+
setLocalFilters(currentApplied);
|
|
274
|
+
}, [appliedFilters]);
|
|
275
|
+
var hasUnsavedChanges = useMemo(function () {
|
|
276
|
+
var localWithValues = localFilters.filter(function (f) {
|
|
277
|
+
// For preset filters, only need type and value
|
|
278
|
+
if (f.type != null && isPresetKey(f.type)) {
|
|
279
|
+
return f.value !== '' && f.type != null;
|
|
280
|
+
}
|
|
281
|
+
// For regular filters, need all fields
|
|
282
|
+
return f.value !== '' && f.type != null && f.field != null && f.matchType != null;
|
|
283
|
+
});
|
|
284
|
+
var appliedWithValues = (appliedFilters !== null && appliedFilters !== void 0 ? appliedFilters : []).filter(function (f) {
|
|
285
|
+
// For preset filters, only need type and value
|
|
286
|
+
if (f.type != null && isPresetKey(f.type)) {
|
|
287
|
+
return f.value !== '' && f.type != null;
|
|
288
|
+
}
|
|
289
|
+
// For regular filters, need all fields
|
|
290
|
+
return f.value !== '' && f.type != null && f.field != null && f.matchType != null;
|
|
291
|
+
});
|
|
292
|
+
if (localWithValues.length !== appliedWithValues.length) return true;
|
|
293
|
+
return !localWithValues.every(function (local, index) {
|
|
294
|
+
var applied = appliedWithValues[index];
|
|
295
|
+
return local.type === (applied === null || applied === void 0 ? void 0 : applied.type) && local.field === (applied === null || applied === void 0 ? void 0 : applied.field) && local.matchType === (applied === null || applied === void 0 ? void 0 : applied.matchType) && local.value === (applied === null || applied === void 0 ? void 0 : applied.value);
|
|
296
|
+
});
|
|
297
|
+
}, [localFilters, appliedFilters]);
|
|
298
|
+
var addFilter = useCallback(function () {
|
|
299
|
+
var newFilter = {
|
|
300
|
+
id: "filter-".concat(Date.now(), "-").concat(Math.random()),
|
|
301
|
+
value: ''
|
|
302
|
+
};
|
|
303
|
+
setLocalFilters([].concat(_toConsumableArray(localFiltersRef.current), [newFilter]));
|
|
304
|
+
}, []);
|
|
305
|
+
var excludeBinary = useCallback(function (binaryName) {
|
|
306
|
+
// Check if this binary is already being filtered with not_contains
|
|
307
|
+
var existingFilter = (appliedFilters !== null && appliedFilters !== void 0 ? appliedFilters : []).find(function (f) {
|
|
308
|
+
return f.type === 'frame' && f.field === 'binary' && f.matchType === 'not_contains' && f.value === binaryName;
|
|
309
|
+
});
|
|
310
|
+
if (existingFilter != null) {
|
|
311
|
+
return; // Already exists, don't add duplicate
|
|
312
|
+
}
|
|
313
|
+
var newFilter = {
|
|
314
|
+
id: "filter-".concat(Date.now(), "-").concat(Math.random()),
|
|
315
|
+
type: 'frame',
|
|
316
|
+
field: 'binary',
|
|
317
|
+
matchType: 'not_contains',
|
|
318
|
+
value: binaryName
|
|
319
|
+
};
|
|
320
|
+
setLocalFilters([].concat(_toConsumableArray(localFiltersRef.current), [newFilter]));
|
|
321
|
+
|
|
322
|
+
// Auto-apply the filter since it has a value
|
|
323
|
+
var filtersToApply = [].concat(_toConsumableArray(appliedFilters !== null && appliedFilters !== void 0 ? appliedFilters : []), [newFilter]);
|
|
324
|
+
setAppliedFilters(filtersToApply);
|
|
325
|
+
resetFlameGraphState();
|
|
326
|
+
},
|
|
327
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
328
|
+
[setAppliedFilters, resetFlameGraphState]);
|
|
329
|
+
var removeExcludeBinary = useCallback(function (binaryName) {
|
|
330
|
+
// Search for the exclude filter (not_contains) for this binary
|
|
331
|
+
var filterToRemove = (appliedFilters !== null && appliedFilters !== void 0 ? appliedFilters : []).find(function (f) {
|
|
332
|
+
return f.type === 'frame' && f.field === 'binary' && f.matchType === 'not_contains' && f.value === binaryName;
|
|
333
|
+
});
|
|
334
|
+
if (filterToRemove != null) {
|
|
335
|
+
// Remove the filter from applied filters
|
|
336
|
+
var updatedAppliedFilters = (appliedFilters !== null && appliedFilters !== void 0 ? appliedFilters : []).filter(function (f) {
|
|
337
|
+
return f.id !== filterToRemove.id;
|
|
338
|
+
});
|
|
339
|
+
setAppliedFilters(updatedAppliedFilters);
|
|
340
|
+
resetFlameGraphState();
|
|
341
|
+
|
|
342
|
+
// Also remove from local filters
|
|
343
|
+
setLocalFilters(localFiltersRef.current.filter(function (f) {
|
|
344
|
+
return f.id !== filterToRemove.id;
|
|
345
|
+
}));
|
|
346
|
+
}
|
|
347
|
+
}, [appliedFilters, setAppliedFilters, resetFlameGraphState]);
|
|
348
|
+
var removeFilter = useCallback(function (id) {
|
|
349
|
+
setLocalFilters(localFiltersRef.current.filter(function (f) {
|
|
350
|
+
return f.id !== id;
|
|
351
|
+
}));
|
|
352
|
+
}, []);
|
|
353
|
+
var updateFilter = useCallback(function (id, updates) {
|
|
354
|
+
setLocalFilters(localFiltersRef.current.map(function (f) {
|
|
355
|
+
return f.id === id ? _objectSpread(_objectSpread({}, f), updates) : f;
|
|
356
|
+
}));
|
|
357
|
+
}, []);
|
|
358
|
+
var resetFilters = useCallback(function () {
|
|
359
|
+
setLocalFilters([]);
|
|
360
|
+
setAppliedFilters([]);
|
|
361
|
+
resetFlameGraphState();
|
|
362
|
+
}, [setAppliedFilters, resetFlameGraphState]);
|
|
363
|
+
var onApplyFilters = useCallback(function () {
|
|
364
|
+
var validFilters = localFiltersRef.current.filter(function (f) {
|
|
365
|
+
// For preset filters, only need type and value
|
|
366
|
+
if (f.type != null && isPresetKey(f.type)) {
|
|
367
|
+
return f.value !== '' && f.type != null;
|
|
368
|
+
}
|
|
369
|
+
// For regular filters, need all fields
|
|
370
|
+
return f.value !== '' && f.type != null && f.field != null && f.matchType != null;
|
|
371
|
+
});
|
|
372
|
+
var filtersToApply = validFilters.map(function (f, index) {
|
|
373
|
+
return _objectSpread(_objectSpread({}, f), {}, {
|
|
374
|
+
id: "filter-".concat(Date.now(), "-").concat(index)
|
|
375
|
+
});
|
|
376
|
+
});
|
|
377
|
+
setAppliedFilters(filtersToApply);
|
|
378
|
+
resetFlameGraphState();
|
|
379
|
+
}, [setAppliedFilters, resetFlameGraphState]);
|
|
380
|
+
var protoFilters = useMemo(function () {
|
|
381
|
+
return convertToProtoFilters(appliedFilters !== null && appliedFilters !== void 0 ? appliedFilters : []);
|
|
382
|
+
}, [appliedFilters]);
|
|
383
|
+
return {
|
|
384
|
+
localFilters: localFilters,
|
|
385
|
+
appliedFilters: appliedFilters !== null && appliedFilters !== void 0 ? appliedFilters : [],
|
|
386
|
+
protoFilters: protoFilters,
|
|
387
|
+
hasUnsavedChanges: hasUnsavedChanges,
|
|
388
|
+
onApplyFilters: onApplyFilters,
|
|
389
|
+
addFilter: addFilter,
|
|
390
|
+
excludeBinary: excludeBinary,
|
|
391
|
+
removeExcludeBinary: removeExcludeBinary,
|
|
392
|
+
removeFilter: removeFilter,
|
|
393
|
+
updateFilter: updateFilter,
|
|
394
|
+
resetFilters: resetFilters,
|
|
395
|
+
setAppliedFilters: setAppliedFilters,
|
|
396
|
+
forceApplyFilters: forceApplyFilters
|
|
397
|
+
};
|
|
398
|
+
};
|