@kylincloud/flamegraph 0.35.6

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 (267) hide show
  1. package/CHANGELOG.md +1211 -0
  2. package/LICENSE +202 -0
  3. package/README.md +251 -0
  4. package/dist/FlameGraph/FlameGraphComponent/CheckIcon.d.ts +2 -0
  5. package/dist/FlameGraph/FlameGraphComponent/CheckIcon.d.ts.map +1 -0
  6. package/dist/FlameGraph/FlameGraphComponent/ContextMenu.d.ts +17 -0
  7. package/dist/FlameGraph/FlameGraphComponent/ContextMenu.d.ts.map +1 -0
  8. package/dist/FlameGraph/FlameGraphComponent/ContextMenuHighlight.d.ts +14 -0
  9. package/dist/FlameGraph/FlameGraphComponent/ContextMenuHighlight.d.ts.map +1 -0
  10. package/dist/FlameGraph/FlameGraphComponent/DiffLegend.d.ts +9 -0
  11. package/dist/FlameGraph/FlameGraphComponent/DiffLegend.d.ts.map +1 -0
  12. package/dist/FlameGraph/FlameGraphComponent/DiffLegendPaletteDropdown.d.ts +8 -0
  13. package/dist/FlameGraph/FlameGraphComponent/DiffLegendPaletteDropdown.d.ts.map +1 -0
  14. package/dist/FlameGraph/FlameGraphComponent/Flamegraph.d.ts +96 -0
  15. package/dist/FlameGraph/FlameGraphComponent/Flamegraph.d.ts.map +1 -0
  16. package/dist/FlameGraph/FlameGraphComponent/Flamegraph_render.d.ts +27 -0
  17. package/dist/FlameGraph/FlameGraphComponent/Flamegraph_render.d.ts.map +1 -0
  18. package/dist/FlameGraph/FlameGraphComponent/GraphVizPane.d.ts +7 -0
  19. package/dist/FlameGraph/FlameGraphComponent/GraphVizPane.d.ts.map +1 -0
  20. package/dist/FlameGraph/FlameGraphComponent/Header.d.ts +12 -0
  21. package/dist/FlameGraph/FlameGraphComponent/Header.d.ts.map +1 -0
  22. package/dist/FlameGraph/FlameGraphComponent/Highlight.d.ts +18 -0
  23. package/dist/FlameGraph/FlameGraphComponent/Highlight.d.ts.map +1 -0
  24. package/dist/FlameGraph/FlameGraphComponent/LogoLink.d.ts +2 -0
  25. package/dist/FlameGraph/FlameGraphComponent/LogoLink.d.ts.map +1 -0
  26. package/dist/FlameGraph/FlameGraphComponent/color.d.ts +20 -0
  27. package/dist/FlameGraph/FlameGraphComponent/color.d.ts.map +1 -0
  28. package/dist/FlameGraph/FlameGraphComponent/colorPalette.d.ts +11 -0
  29. package/dist/FlameGraph/FlameGraphComponent/colorPalette.d.ts.map +1 -0
  30. package/dist/FlameGraph/FlameGraphComponent/constants.d.ts +6 -0
  31. package/dist/FlameGraph/FlameGraphComponent/constants.d.ts.map +1 -0
  32. package/dist/FlameGraph/FlameGraphComponent/index.d.ts +37 -0
  33. package/dist/FlameGraph/FlameGraphComponent/index.d.ts.map +1 -0
  34. package/dist/FlameGraph/FlameGraphComponent/murmur3.d.ts +2 -0
  35. package/dist/FlameGraph/FlameGraphComponent/murmur3.d.ts.map +1 -0
  36. package/dist/FlameGraph/FlameGraphComponent/testData.d.ts +53 -0
  37. package/dist/FlameGraph/FlameGraphComponent/testData.d.ts.map +1 -0
  38. package/dist/FlameGraph/FlameGraphComponent/utils.d.ts +6 -0
  39. package/dist/FlameGraph/FlameGraphComponent/utils.d.ts.map +1 -0
  40. package/dist/FlameGraph/FlameGraphComponent/viewTypes.d.ts +2 -0
  41. package/dist/FlameGraph/FlameGraphComponent/viewTypes.d.ts.map +1 -0
  42. package/dist/FlameGraph/FlameGraphRenderer.d.ts +86 -0
  43. package/dist/FlameGraph/FlameGraphRenderer.d.ts.map +1 -0
  44. package/dist/FlameGraph/decode.d.ts +27 -0
  45. package/dist/FlameGraph/decode.d.ts.map +1 -0
  46. package/dist/FlameGraph/normalize.d.ts +6 -0
  47. package/dist/FlameGraph/normalize.d.ts.map +1 -0
  48. package/dist/FlameGraph/uniqueness.d.ts +3 -0
  49. package/dist/FlameGraph/uniqueness.d.ts.map +1 -0
  50. package/dist/FlamegraphRenderer.d.ts +19 -0
  51. package/dist/FlamegraphRenderer.d.ts.map +1 -0
  52. package/dist/Icons.d.ts +9 -0
  53. package/dist/Icons.d.ts.map +1 -0
  54. package/dist/ProfilerTable.d.ts +21 -0
  55. package/dist/ProfilerTable.d.ts.map +1 -0
  56. package/dist/SharedQueryInput.d.ts +10 -0
  57. package/dist/SharedQueryInput.d.ts.map +1 -0
  58. package/dist/Toolbar.d.ts +31 -0
  59. package/dist/Toolbar.d.ts.map +1 -0
  60. package/dist/Tooltip/FlamegraphTooltip.d.ts +59 -0
  61. package/dist/Tooltip/FlamegraphTooltip.d.ts.map +1 -0
  62. package/dist/Tooltip/LeftClickIcon.d.ts +2 -0
  63. package/dist/Tooltip/LeftClickIcon.d.ts.map +1 -0
  64. package/dist/Tooltip/RightClickIcon.d.ts +2 -0
  65. package/dist/Tooltip/RightClickIcon.d.ts.map +1 -0
  66. package/dist/Tooltip/TableTooltip.d.ts +12 -0
  67. package/dist/Tooltip/TableTooltip.d.ts.map +1 -0
  68. package/dist/Tooltip/Tooltip.d.ts +29 -0
  69. package/dist/Tooltip/Tooltip.d.ts.map +1 -0
  70. package/dist/convert/convertJaegerTraceToProfile.d.ts +3 -0
  71. package/dist/convert/convertJaegerTraceToProfile.d.ts.map +1 -0
  72. package/dist/convert/diffTwoProfiles.d.ts +3 -0
  73. package/dist/convert/diffTwoProfiles.d.ts.map +1 -0
  74. package/dist/convert/flamebearersToTree.d.ts +11 -0
  75. package/dist/convert/flamebearersToTree.d.ts.map +1 -0
  76. package/dist/convert/sandwichViewProfiles.d.ts +14 -0
  77. package/dist/convert/sandwichViewProfiles.d.ts.map +1 -0
  78. package/dist/convert/subtract.d.ts +3 -0
  79. package/dist/convert/subtract.d.ts.map +1 -0
  80. package/dist/convert/testData.d.ts +50 -0
  81. package/dist/convert/testData.d.ts.map +1 -0
  82. package/dist/convert/toGraphviz.d.ts +3 -0
  83. package/dist/convert/toGraphviz.d.ts.map +1 -0
  84. package/dist/fitMode/fitMode.d.ts +42 -0
  85. package/dist/fitMode/fitMode.d.ts.map +1 -0
  86. package/dist/format/format.d.ts +42 -0
  87. package/dist/format/format.d.ts.map +1 -0
  88. package/dist/i18n.d.ts +55 -0
  89. package/dist/i18n.d.ts.map +1 -0
  90. package/dist/index.cjs.css +792 -0
  91. package/dist/index.cjs.js +5087 -0
  92. package/dist/index.d.ts +4 -0
  93. package/dist/index.d.ts.map +1 -0
  94. package/dist/index.esm.css +792 -0
  95. package/dist/index.esm.js +5079 -0
  96. package/dist/index.node.d.ts +9 -0
  97. package/dist/index.node.d.ts.map +1 -0
  98. package/dist/logo-v3-small-T5VXIMRR.svg +32 -0
  99. package/dist/models/decode.d.ts +3 -0
  100. package/dist/models/decode.d.ts.map +1 -0
  101. package/dist/models/flamebearer.d.ts +63 -0
  102. package/dist/models/flamebearer.d.ts.map +1 -0
  103. package/dist/models/groups.d.ts +37 -0
  104. package/dist/models/groups.d.ts.map +1 -0
  105. package/dist/models/index.d.ts +8 -0
  106. package/dist/models/index.d.ts.map +1 -0
  107. package/dist/models/profile.d.ts +152 -0
  108. package/dist/models/profile.d.ts.map +1 -0
  109. package/dist/models/spyName.d.ts +8 -0
  110. package/dist/models/spyName.d.ts.map +1 -0
  111. package/dist/models/trace.d.ts +357 -0
  112. package/dist/models/trace.d.ts.map +1 -0
  113. package/dist/models/units.d.ts +6 -0
  114. package/dist/models/units.d.ts.map +1 -0
  115. package/dist/search.d.ts +2 -0
  116. package/dist/search.d.ts.map +1 -0
  117. package/dist/shims/Box.d.ts +38 -0
  118. package/dist/shims/Box.d.ts.map +1 -0
  119. package/dist/shims/Button.d.ts +26 -0
  120. package/dist/shims/Button.d.ts.map +1 -0
  121. package/dist/shims/Dropdown.d.ts +30 -0
  122. package/dist/shims/Dropdown.d.ts.map +1 -0
  123. package/dist/shims/Input.d.ts +19 -0
  124. package/dist/shims/Input.d.ts.map +1 -0
  125. package/dist/shims/LoadingSpinner.d.ts +7 -0
  126. package/dist/shims/LoadingSpinner.d.ts.map +1 -0
  127. package/dist/shims/Menu.d.ts +4 -0
  128. package/dist/shims/Menu.d.ts.map +1 -0
  129. package/dist/shims/NoData.d.ts +2 -0
  130. package/dist/shims/NoData.d.ts.map +1 -0
  131. package/dist/shims/Table.d.ts +52 -0
  132. package/dist/shims/Table.d.ts.map +1 -0
  133. package/dist/shims/Tooltip.d.ts +9 -0
  134. package/dist/shims/Tooltip.d.ts.map +1 -0
  135. package/package.json +84 -0
  136. package/src/FlameGraph/FlameGraphComponent/CheckIcon.tsx +27 -0
  137. package/src/FlameGraph/FlameGraphComponent/ContextMenu.module.scss +10 -0
  138. package/src/FlameGraph/FlameGraphComponent/ContextMenu.spec.tsx +84 -0
  139. package/src/FlameGraph/FlameGraphComponent/ContextMenu.tsx +86 -0
  140. package/src/FlameGraph/FlameGraphComponent/ContextMenuHighlight.module.css +8 -0
  141. package/src/FlameGraph/FlameGraphComponent/ContextMenuHighlight.tsx +47 -0
  142. package/src/FlameGraph/FlameGraphComponent/DiffLegend.module.css +21 -0
  143. package/src/FlameGraph/FlameGraphComponent/DiffLegend.tsx +52 -0
  144. package/src/FlameGraph/FlameGraphComponent/DiffLegendPaletteDropdown.module.css +40 -0
  145. package/src/FlameGraph/FlameGraphComponent/DiffLegendPaletteDropdown.tsx +129 -0
  146. package/src/FlameGraph/FlameGraphComponent/Flamegraph.spec.ts +552 -0
  147. package/src/FlameGraph/FlameGraphComponent/Flamegraph.ts +446 -0
  148. package/src/FlameGraph/FlameGraphComponent/Flamegraph_render.spec.tsx +233 -0
  149. package/src/FlameGraph/FlameGraphComponent/Flamegraph_render.ts +478 -0
  150. package/src/FlameGraph/FlameGraphComponent/GraphVizPane.tsx +56 -0
  151. package/src/FlameGraph/FlameGraphComponent/GraphVizPanel.module.scss +55 -0
  152. package/src/FlameGraph/FlameGraphComponent/Header.module.css +27 -0
  153. package/src/FlameGraph/FlameGraphComponent/Header.tsx +71 -0
  154. package/src/FlameGraph/FlameGraphComponent/Highlight.module.css +7 -0
  155. package/src/FlameGraph/FlameGraphComponent/Highlight.spec.tsx +53 -0
  156. package/src/FlameGraph/FlameGraphComponent/Highlight.tsx +94 -0
  157. package/src/FlameGraph/FlameGraphComponent/LogoLink.module.scss +10 -0
  158. package/src/FlameGraph/FlameGraphComponent/LogoLink.tsx +101 -0
  159. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/canvas-renderer-spec-tsx-canvas-renderer-group-snapshot-collapses-small-blocks-into-one-1-snap.png +0 -0
  160. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/canvas-renderer-spec-tsx-canvas-renderer-group-snapshot-works-with-diff-mode-1-snap.png +0 -0
  161. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/canvas-renderer-spec-tsx-canvas-renderer-group-snapshot-works-with-highlighted-flamegraph-1-snap.png +0 -0
  162. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/canvas-renderer-spec-tsx-canvas-renderer-group-snapshot-works-with-normal-flamegraph-1-snap.png +0 -0
  163. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/canvas-renderer-spec-tsx-canvas-renderer-group-snapshot-works-with-selected-node-1-snap.png +0 -0
  164. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-focused-also-zooms-1-snap.png +0 -0
  165. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-focused-renders-a-focused-node-in-the-beginning-1-snap.png +0 -0
  166. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-focused-renders-a-focused-node-when-node-is-not-in-the-beginning-1-snap.png +0 -0
  167. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-focused-renders-a-focused-node-zoom-top-level-1-snap.png +0 -0
  168. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-renders-a-complex-flamegraph-1-snap.png +0 -0
  169. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-renders-a-double-diff-flamegraph-1-snap.png +0 -0
  170. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-renders-a-highlighted-double-flamegraph-1-snap.png +0 -0
  171. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-renders-a-highlighted-flamegraph-1-snap.png +0 -0
  172. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-renders-a-simple-flamegraph-1-snap.png +0 -0
  173. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-renders-a-simple-tree-1-snap.png +0 -0
  174. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-renders-a-zoomed-flamegraph-1-snap.png +0 -0
  175. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-renders-a-zoomed-with-fit-mode-tail-1-snap.png +0 -0
  176. package/src/FlameGraph/FlameGraphComponent/canvas.module.css +6 -0
  177. package/src/FlameGraph/FlameGraphComponent/color.spec.ts +308 -0
  178. package/src/FlameGraph/FlameGraphComponent/color.ts +167 -0
  179. package/src/FlameGraph/FlameGraphComponent/colorPalette.ts +58 -0
  180. package/src/FlameGraph/FlameGraphComponent/constants.ts +5 -0
  181. package/src/FlameGraph/FlameGraphComponent/index.spec.tsx +291 -0
  182. package/src/FlameGraph/FlameGraphComponent/index.tsx +411 -0
  183. package/src/FlameGraph/FlameGraphComponent/murmur3.ts +97 -0
  184. package/src/FlameGraph/FlameGraphComponent/styles.module.scss +10 -0
  185. package/src/FlameGraph/FlameGraphComponent/testData.ts +427 -0
  186. package/src/FlameGraph/FlameGraphComponent/utils.ts +31 -0
  187. package/src/FlameGraph/FlameGraphComponent/viewTypes.ts +6 -0
  188. package/src/FlameGraph/FlameGraphRenderer.tsx +603 -0
  189. package/src/FlameGraph/FlamegraphRenderer.module.scss +93 -0
  190. package/src/FlameGraph/decode.ts +78 -0
  191. package/src/FlameGraph/normalize.spec.ts +76 -0
  192. package/src/FlameGraph/normalize.ts +60 -0
  193. package/src/FlameGraph/testData.json +423 -0
  194. package/src/FlameGraph/uniqueness.spec.ts +16 -0
  195. package/src/FlameGraph/uniqueness.ts +84 -0
  196. package/src/FlamegraphRenderer.tsx +61 -0
  197. package/src/Icons.tsx +74 -0
  198. package/src/ProfilerTable.tsx +527 -0
  199. package/src/SharedQueryInput.module.scss +82 -0
  200. package/src/SharedQueryInput.tsx +127 -0
  201. package/src/Toolbar.module.scss +117 -0
  202. package/src/Toolbar.spec.tsx +217 -0
  203. package/src/Toolbar.tsx +471 -0
  204. package/src/Tooltip/FlamegraphTooltip.spec.tsx +81 -0
  205. package/src/Tooltip/FlamegraphTooltip.tsx +257 -0
  206. package/src/Tooltip/LeftClickIcon.tsx +18 -0
  207. package/src/Tooltip/RightClickIcon.tsx +18 -0
  208. package/src/Tooltip/TableTooltip.spec.tsx +44 -0
  209. package/src/Tooltip/TableTooltip.tsx +145 -0
  210. package/src/Tooltip/Tooltip.module.scss +71 -0
  211. package/src/Tooltip/Tooltip.spec.tsx +395 -0
  212. package/src/Tooltip/Tooltip.tsx +336 -0
  213. package/src/__snapshots__/Toolbar.spec.tsx.snap +297 -0
  214. package/src/convert/convertJaegerTraceToProfile.ts +97 -0
  215. package/src/convert/diffTwoProfiles.ts +81 -0
  216. package/src/convert/flamebearersToTree.ts +78 -0
  217. package/src/convert/sandwichViewProfiles.spec.ts +65 -0
  218. package/src/convert/sandwichViewProfiles.ts +191 -0
  219. package/src/convert/subtract.ts +87 -0
  220. package/src/convert/testData.ts +145 -0
  221. package/src/convert/toGraphviz.ts +485 -0
  222. package/src/fitMode/fitMode.spec.ts +93 -0
  223. package/src/fitMode/fitMode.ts +122 -0
  224. package/src/format/format.spec.ts +291 -0
  225. package/src/format/format.ts +303 -0
  226. package/src/globals.d.ts +13 -0
  227. package/src/i18n.tsx +293 -0
  228. package/src/index.node.ts +19 -0
  229. package/src/index.spec.tsx +383 -0
  230. package/src/index.tsx +10 -0
  231. package/src/logo-v3-small.svg +32 -0
  232. package/src/models/decode.ts +45 -0
  233. package/src/models/flamebearer.ts +86 -0
  234. package/src/models/groups.ts +14 -0
  235. package/src/models/index.ts +7 -0
  236. package/src/models/profile.spec.ts +32 -0
  237. package/src/models/profile.ts +48 -0
  238. package/src/models/spyName.spec.ts +18 -0
  239. package/src/models/spyName.ts +32 -0
  240. package/src/models/trace.ts +45 -0
  241. package/src/models/units.spec.ts +21 -0
  242. package/src/models/units.ts +24 -0
  243. package/src/sass/_common.scss +206 -0
  244. package/src/sass/_css-variables.scss +201 -0
  245. package/src/sass/_mixins.scss +15 -0
  246. package/src/sass/_sanitize.scss +407 -0
  247. package/src/sass/_variables.scss +53 -0
  248. package/src/sass/flamegraph.scss +18 -0
  249. package/src/search.spec.ts +11 -0
  250. package/src/search.ts +4 -0
  251. package/src/shameful-any.d.ts +2 -0
  252. package/src/shims/Box.module.scss +57 -0
  253. package/src/shims/Box.tsx +105 -0
  254. package/src/shims/Button.module.scss +129 -0
  255. package/src/shims/Button.tsx +128 -0
  256. package/src/shims/Dropdown.module.scss +63 -0
  257. package/src/shims/Dropdown.tsx +96 -0
  258. package/src/shims/Input.module.scss +15 -0
  259. package/src/shims/Input.tsx +55 -0
  260. package/src/shims/LoadingSpinner.tsx +19 -0
  261. package/src/shims/Menu.tsx +9 -0
  262. package/src/shims/NoData.module.scss +6 -0
  263. package/src/shims/NoData.tsx +11 -0
  264. package/src/shims/Table.module.scss +82 -0
  265. package/src/shims/Table.spec.tsx +121 -0
  266. package/src/shims/Table.tsx +252 -0
  267. package/src/shims/Tooltip.tsx +51 -0
@@ -0,0 +1,127 @@
1
+ /* eslint-disable no-unused-expressions */
2
+ import React, { useEffect, useMemo, ChangeEvent, useRef } from 'react';
3
+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
4
+ import { faLink } from '@fortawesome/free-solid-svg-icons/faLink';
5
+ import Input from './shims/Input';
6
+ import { Tooltip } from './shims/Tooltip';
7
+ import styles from './SharedQueryInput.module.scss';
8
+ import type { ProfileHeaderProps } from './Toolbar';
9
+ import { useFlamegraphI18n } from './i18n';
10
+
11
+ interface SharedQueryProps {
12
+ onHighlightChange: ProfileHeaderProps['handleSearchChange'];
13
+ highlightQuery: ProfileHeaderProps['highlightQuery'];
14
+ sharedQuery: ProfileHeaderProps['sharedQuery'];
15
+ width: number;
16
+ }
17
+
18
+ const usePreviousSyncEnabled = (syncEnabled?: string | boolean) => {
19
+ const ref = useRef<string | boolean | undefined>();
20
+
21
+ useEffect(() => {
22
+ ref.current = syncEnabled;
23
+ }, [syncEnabled]);
24
+
25
+ return ref.current;
26
+ };
27
+
28
+ const SharedQueryInput = ({
29
+ onHighlightChange,
30
+ highlightQuery,
31
+ sharedQuery,
32
+ width,
33
+ }: SharedQueryProps) => {
34
+ const messages = useFlamegraphI18n();
35
+ const prevSyncEnabled = usePreviousSyncEnabled(sharedQuery?.syncEnabled);
36
+
37
+ const onQueryChange = (e: ChangeEvent<HTMLInputElement>) => {
38
+ onHighlightChange(e.target.value);
39
+
40
+ if (sharedQuery && sharedQuery.syncEnabled) {
41
+ sharedQuery.onQueryChange(e.target.value);
42
+ }
43
+ };
44
+
45
+ useEffect(() => {
46
+ if (typeof sharedQuery?.searchQuery === 'string') {
47
+ if (sharedQuery.syncEnabled) {
48
+ onHighlightChange(sharedQuery.searchQuery);
49
+ }
50
+
51
+ if (
52
+ !sharedQuery.syncEnabled &&
53
+ prevSyncEnabled &&
54
+ prevSyncEnabled !== sharedQuery?.id
55
+ ) {
56
+ onHighlightChange('');
57
+ }
58
+ }
59
+ }, [sharedQuery?.searchQuery, sharedQuery?.syncEnabled]);
60
+
61
+ const onToggleSync = () => {
62
+ const newValue = sharedQuery?.syncEnabled ? false : sharedQuery?.id;
63
+ sharedQuery?.toggleSync(newValue as string | false);
64
+
65
+ if (newValue) {
66
+ sharedQuery?.onQueryChange(highlightQuery);
67
+ } else {
68
+ onHighlightChange(highlightQuery);
69
+ sharedQuery?.onQueryChange('');
70
+ }
71
+ };
72
+
73
+ const inputValue = useMemo(
74
+ () =>
75
+ sharedQuery && sharedQuery.syncEnabled
76
+ ? sharedQuery.searchQuery || ''
77
+ : highlightQuery,
78
+ [sharedQuery, highlightQuery]
79
+ );
80
+
81
+ const inputClassName = useMemo(
82
+ () =>
83
+ `${sharedQuery ? styles.searchWithSync : styles.search} ${
84
+ sharedQuery?.syncEnabled ? styles['search-synced'] : ''
85
+ }`,
86
+ [sharedQuery]
87
+ );
88
+
89
+ const syncTooltipTitle = sharedQuery?.syncEnabled
90
+ ? messages.unsyncSearchBars
91
+ : messages.syncSearchBars;
92
+
93
+ return (
94
+ <div className={styles.wrapper} style={{ width }}>
95
+ <Input
96
+ testId="flamegraph-search"
97
+ className={inputClassName}
98
+ type="search"
99
+ name="flamegraph-search"
100
+ placeholder={messages.searchPlaceholder}
101
+ minLength={2}
102
+ debounceTimeout={100}
103
+ onChange={onQueryChange}
104
+ value={inputValue}
105
+ />
106
+ {sharedQuery ? (
107
+ <Tooltip placement="top" title={syncTooltipTitle}>
108
+ <button
109
+ className={
110
+ sharedQuery.syncEnabled ? styles.syncSelected : styles.sync
111
+ }
112
+ onClick={onToggleSync}
113
+ >
114
+ <FontAwesomeIcon
115
+ className={`${
116
+ sharedQuery.syncEnabled ? styles.checked : styles.icon
117
+ }`}
118
+ icon={faLink}
119
+ />
120
+ </button>
121
+ </Tooltip>
122
+ ) : null}
123
+ </div>
124
+ );
125
+ };
126
+
127
+ export default SharedQueryInput;
@@ -0,0 +1,117 @@
1
+ $buttonHeight: 37px;
2
+
3
+ .navbar {
4
+ position: relative;
5
+ display: flex;
6
+ flex-direction: row;
7
+ margin: 10px 0;
8
+ justify-content: space-between;
9
+ height: 47px;
10
+ background-color: var(--ps-fl-toolbar-bg);
11
+ border: 1px solid var(--ps-ui-border);
12
+ padding: 4px;
13
+ align-items: center;
14
+ }
15
+
16
+ .viewType {
17
+ display: flex;
18
+ flex-direction: row;
19
+ flex-wrap: nowrap;
20
+ }
21
+
22
+ .navbar button {
23
+ color: var(--ps-toolbar-icon-color);
24
+ }
25
+
26
+ .toggleViewButton {
27
+ height: $buttonHeight;
28
+ min-width: auto;
29
+ width: 40px;
30
+ margin: 0 2px;
31
+ padding: 0;
32
+ border-color: transparent;
33
+ background-color: transparent;
34
+ display: flex;
35
+ justify-content: center;
36
+ align-items: center;
37
+
38
+ svg {
39
+ width: 22px;
40
+ height: 22px;
41
+ }
42
+
43
+ &.selected {
44
+ background-color: var(--ps-fl-toolbar-btn-bg);
45
+
46
+ &:hover {
47
+ background-color: var(--ps-fl-toolbar-btn-bg);
48
+ }
49
+
50
+ svg {
51
+ color: white;
52
+ }
53
+ }
54
+ }
55
+
56
+ .fitModeButton {
57
+ @extend .toggleViewButton;
58
+ }
59
+
60
+ .collapseNodeButton {
61
+ min-width: initial;
62
+ width: 40px;
63
+ height: $buttonHeight;
64
+ margin: 0 2px;
65
+ padding: 0;
66
+ background-color: transparent;
67
+ border-color: transparent;
68
+ }
69
+
70
+ .resetViewButton {
71
+ @extend .collapseNodeButton;
72
+ width: 40px;
73
+ min-width: initial;
74
+ margin: 0 2px;
75
+ padding: 0;
76
+ }
77
+
78
+ .divider {
79
+ width: 1px;
80
+ margin: 0 2px;
81
+ height: $buttonHeight;
82
+ background-color: var(--ps-ui-border);
83
+ }
84
+
85
+ .itemsContainer,
86
+ .item {
87
+ display: flex;
88
+ }
89
+
90
+ .moreButton {
91
+ border-radius: 4px;
92
+ border: none;
93
+ padding: 0 5px;
94
+ height: $buttonHeight;
95
+
96
+ &.active,
97
+ &.active:hover {
98
+ background-color: var(--ps-fl-toolbar-btn-bg);
99
+ }
100
+
101
+ &:hover {
102
+ background-color: var(--ps-ui-element-bg-highlight);
103
+ cursor: pointer;
104
+ }
105
+ }
106
+
107
+ .navbarCollapsedItems {
108
+ display: flex;
109
+ position: absolute;
110
+ right: 0;
111
+ top: 50px;
112
+ height: 47px;
113
+ background-color: var(--ps-fl-toolbar-bg);
114
+ border: 1px solid var(--ps-ui-border);
115
+ padding: 4px;
116
+ z-index: 1;
117
+ }
@@ -0,0 +1,217 @@
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+ import userEvent from '@testing-library/user-event';
4
+ import { Maybe } from 'true-myth';
5
+ import Toolbar from './Toolbar';
6
+ import { HeadMode, TailMode } from './fitMode/fitMode';
7
+
8
+ // since 'react-debounce-input' uses lodash.debounce under the hood
9
+ jest.mock('lodash.debounce', () =>
10
+ jest.fn((fn) => {
11
+ fn.flush = () => {};
12
+ return fn;
13
+ })
14
+ );
15
+
16
+ describe('ProfileHeader', () => {
17
+ beforeAll(() => {
18
+ window.HTMLElement.prototype.getBoundingClientRect = function () {
19
+ return {
20
+ x: 0,
21
+ y: 0,
22
+ bottom: 0,
23
+ right: 0,
24
+ toJSON: () => {},
25
+ height: 0,
26
+ top: 0,
27
+ left: 0,
28
+ width: 900,
29
+ };
30
+ };
31
+ });
32
+
33
+ it('should render toolbar correctly', () => {
34
+ const { asFragment } = render(
35
+ <Toolbar
36
+ view="both"
37
+ flamegraphType="single"
38
+ handleSearchChange={() => {}}
39
+ reset={() => {}}
40
+ updateFitMode={() => {}}
41
+ fitMode={HeadMode}
42
+ updateView={() => {}}
43
+ isFlamegraphDirty={false}
44
+ selectedNode={Maybe.nothing()}
45
+ onFocusOnSubtree={() => {}}
46
+ highlightQuery=""
47
+ />
48
+ );
49
+
50
+ expect(screen.getByRole('toolbar')).toBeInTheDocument();
51
+ expect(asFragment()).toMatchSnapshot();
52
+ });
53
+
54
+ describe('Reset button', () => {
55
+ const onReset = jest.fn();
56
+
57
+ beforeEach(() => {});
58
+
59
+ afterEach(() => {
60
+ jest.clearAllMocks();
61
+ });
62
+
63
+ it('renders as disabled when flamegraph is not dirty', () => {
64
+ const component = (
65
+ <Toolbar
66
+ view="both"
67
+ flamegraphType="single"
68
+ isFlamegraphDirty={false}
69
+ handleSearchChange={() => {}}
70
+ reset={onReset}
71
+ updateFitMode={() => {}}
72
+ fitMode={HeadMode}
73
+ updateView={() => {}}
74
+ selectedNode={Maybe.nothing()}
75
+ onFocusOnSubtree={() => {}}
76
+ highlightQuery=""
77
+ />
78
+ );
79
+ render(component);
80
+ expect(screen.getByRole('button', { name: /Reset/ })).toBeDisabled();
81
+ });
82
+
83
+ it('calls onReset when clicked (and enabled)', () => {
84
+ const component = (
85
+ <Toolbar
86
+ view="both"
87
+ flamegraphType="single"
88
+ isFlamegraphDirty
89
+ handleSearchChange={() => {}}
90
+ reset={onReset}
91
+ updateFitMode={() => {}}
92
+ fitMode={HeadMode}
93
+ updateView={() => {}}
94
+ selectedNode={Maybe.nothing()}
95
+ onFocusOnSubtree={() => {}}
96
+ highlightQuery=""
97
+ />
98
+ );
99
+ render(component);
100
+ expect(screen.getByRole('button', { name: /Reset/ })).not.toBeDisabled();
101
+ screen.getByRole('button', { name: /Reset/ }).click();
102
+
103
+ expect(onReset).toHaveBeenCalled();
104
+ });
105
+ });
106
+
107
+ describe('HighlightSearch', () => {
108
+ it('calls callback when typed', () => {
109
+ const onChange = jest.fn();
110
+
111
+ const component = (
112
+ <Toolbar
113
+ view="both"
114
+ flamegraphType="single"
115
+ isFlamegraphDirty
116
+ handleSearchChange={onChange}
117
+ reset={() => {}}
118
+ updateFitMode={() => {}}
119
+ fitMode={HeadMode}
120
+ updateView={() => {}}
121
+ selectedNode={Maybe.nothing()}
122
+ onFocusOnSubtree={() => {}}
123
+ highlightQuery=""
124
+ />
125
+ );
126
+
127
+ render(component);
128
+ userEvent.type(screen.getByRole('searchbox'), 'foobar');
129
+ expect(onChange).toHaveBeenCalledWith('foobar');
130
+ });
131
+ });
132
+
133
+ describe('FitMode', () => {
134
+ const updateFitMode = jest.fn();
135
+ const component = (
136
+ <Toolbar
137
+ view="both"
138
+ flamegraphType="single"
139
+ handleSearchChange={() => {}}
140
+ reset={() => {}}
141
+ updateFitMode={updateFitMode}
142
+ fitMode={HeadMode}
143
+ updateView={() => {}}
144
+ isFlamegraphDirty={false}
145
+ selectedNode={Maybe.nothing()}
146
+ onFocusOnSubtree={() => {}}
147
+ highlightQuery=""
148
+ />
149
+ );
150
+
151
+ beforeEach(() => {
152
+ render(component);
153
+ });
154
+
155
+ afterEach(() => {
156
+ jest.clearAllMocks();
157
+ });
158
+
159
+ it('updates to HEAD first', () => {
160
+ screen.getByRole('button', { name: 'Head first' }).click();
161
+
162
+ expect(updateFitMode).toHaveBeenCalledWith(HeadMode);
163
+ });
164
+
165
+ it('updates to TAIL first', () => {
166
+ screen.getByRole('button', { name: 'Tail first' }).click();
167
+
168
+ expect(updateFitMode).toHaveBeenCalledWith(TailMode);
169
+ });
170
+ });
171
+
172
+ describe('Focus on subtree', () => {
173
+ it('renders as disabled when theres no selected node', () => {
174
+ const component = (
175
+ <Toolbar
176
+ view="both"
177
+ flamegraphType="single"
178
+ isFlamegraphDirty={false}
179
+ handleSearchChange={() => {}}
180
+ reset={() => {}}
181
+ updateFitMode={() => {}}
182
+ fitMode={HeadMode}
183
+ updateView={() => {}}
184
+ selectedNode={Maybe.nothing()}
185
+ onFocusOnSubtree={() => {}}
186
+ highlightQuery=""
187
+ />
188
+ );
189
+ render(component);
190
+ expect(screen.getByRole('button', { name: /Collapse/ })).toBeDisabled();
191
+ });
192
+
193
+ it('calls callback when clicked', () => {
194
+ const onFocusOnSubtree = jest.fn();
195
+ const component = (
196
+ <Toolbar
197
+ view="both"
198
+ flamegraphType="single"
199
+ isFlamegraphDirty={false}
200
+ handleSearchChange={() => {}}
201
+ reset={() => {}}
202
+ updateFitMode={() => {}}
203
+ fitMode={HeadMode}
204
+ updateView={() => {}}
205
+ selectedNode={Maybe.just({ i: 999, j: 999 })}
206
+ onFocusOnSubtree={onFocusOnSubtree}
207
+ highlightQuery=""
208
+ />
209
+ );
210
+
211
+ render(component);
212
+ screen.getByRole('button', { name: /Collapse/ }).click();
213
+
214
+ expect(onFocusOnSubtree).toHaveBeenCalledWith(999, 999);
215
+ });
216
+ });
217
+ });