useDetailState.ts 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import { TraceLog, TraceSpanReference } from '@jaegertracing/jaeger-ui-components/src/types/trace';
  2. import { useCallback, useState, useEffect } from 'react';
  3. import { DataFrame } from '@grafana/data';
  4. import { DetailState } from '@jaegertracing/jaeger-ui-components';
  5. /**
  6. * Keeps state of the span detail. This means whether span details are open but also state of each detail subitem
  7. * like logs or tags.
  8. */
  9. export function useDetailState(frame: DataFrame) {
  10. const [detailStates, setDetailStates] = useState(new Map<string, DetailState>());
  11. // Clear detail state when new trace arrives
  12. useEffect(() => {
  13. setDetailStates(new Map<string, DetailState>());
  14. }, [frame, setDetailStates]);
  15. const toggleDetail = useCallback(
  16. function toggleDetail(spanID: string) {
  17. const newDetailStates = new Map(detailStates);
  18. if (newDetailStates.has(spanID)) {
  19. newDetailStates.delete(spanID);
  20. } else {
  21. newDetailStates.set(spanID, new DetailState());
  22. }
  23. setDetailStates(newDetailStates);
  24. },
  25. [detailStates]
  26. );
  27. const detailLogItemToggle = useCallback(
  28. function detailLogItemToggle(spanID: string, log: TraceLog) {
  29. const old = detailStates.get(spanID);
  30. if (!old) {
  31. return;
  32. }
  33. const detailState = old.toggleLogItem(log);
  34. const newDetailStates = new Map(detailStates);
  35. newDetailStates.set(spanID, detailState);
  36. return setDetailStates(newDetailStates);
  37. },
  38. [detailStates]
  39. );
  40. const detailReferenceItemToggle = useCallback(
  41. function detailReferenceItemToggle(spanID: string, reference: TraceSpanReference) {
  42. const old = detailStates.get(spanID);
  43. if (!old) {
  44. return;
  45. }
  46. const detailState = old.toggleReferenceItem(reference);
  47. const newDetailStates = new Map(detailStates);
  48. newDetailStates.set(spanID, detailState);
  49. return setDetailStates(newDetailStates);
  50. },
  51. [detailStates]
  52. );
  53. return {
  54. detailStates,
  55. toggleDetail,
  56. detailLogItemToggle,
  57. detailLogsToggle: useCallback(
  58. (spanID: string) => makeDetailSubsectionToggle('logs', detailStates, setDetailStates)(spanID),
  59. [detailStates]
  60. ),
  61. detailWarningsToggle: useCallback(
  62. (spanID: string) => makeDetailSubsectionToggle('warnings', detailStates, setDetailStates)(spanID),
  63. [detailStates]
  64. ),
  65. detailStackTracesToggle: useCallback(
  66. (spanID: string) => makeDetailSubsectionToggle('stackTraces', detailStates, setDetailStates)(spanID),
  67. [detailStates]
  68. ),
  69. detailReferenceItemToggle,
  70. detailReferencesToggle: useCallback(
  71. (spanID: string) => makeDetailSubsectionToggle('references', detailStates, setDetailStates)(spanID),
  72. [detailStates]
  73. ),
  74. detailProcessToggle: useCallback(
  75. (spanID: string) => makeDetailSubsectionToggle('process', detailStates, setDetailStates)(spanID),
  76. [detailStates]
  77. ),
  78. detailTagsToggle: useCallback(
  79. (spanID: string) => makeDetailSubsectionToggle('tags', detailStates, setDetailStates)(spanID),
  80. [detailStates]
  81. ),
  82. };
  83. }
  84. function makeDetailSubsectionToggle(
  85. subSection: 'tags' | 'process' | 'logs' | 'warnings' | 'references' | 'stackTraces',
  86. detailStates: Map<string, DetailState>,
  87. setDetailStates: (detailStates: Map<string, DetailState>) => void
  88. ) {
  89. return (spanID: string) => {
  90. const old = detailStates.get(spanID);
  91. if (!old) {
  92. return;
  93. }
  94. let detailState;
  95. if (subSection === 'tags') {
  96. detailState = old.toggleTags();
  97. } else if (subSection === 'process') {
  98. detailState = old.toggleProcess();
  99. } else if (subSection === 'warnings') {
  100. detailState = old.toggleWarnings();
  101. } else if (subSection === 'references') {
  102. detailState = old.toggleReferences();
  103. } else if (subSection === 'stackTraces') {
  104. detailState = old.toggleStackTraces();
  105. } else {
  106. detailState = old.toggleLogs();
  107. }
  108. const newDetailStates = new Map(detailStates);
  109. newDetailStates.set(spanID, detailState);
  110. setDetailStates(newDetailStates);
  111. };
  112. }