traceShortcutsModal.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import {Fragment, useCallback} from 'react';
  2. import styled from '@emotion/styled';
  3. import tracingKeyboardShortcuts from 'sentry-images/spot/tracing-keyboard-shortcuts.svg';
  4. import {type ModalRenderProps, openModal} from 'sentry/actionCreators/modal';
  5. import {Button} from 'sentry/components/button';
  6. import {t} from 'sentry/locale';
  7. import {space} from 'sentry/styles/space';
  8. import useOrganization from 'sentry/utils/useOrganization';
  9. import {traceAnalytics} from 'sentry/views/performance/newTraceDetails/traceAnalytics';
  10. export function TraceShortcuts() {
  11. const organization = useOrganization();
  12. const onOpenShortcutsClick = useCallback(() => {
  13. traceAnalytics.trackViewShortcuts(organization);
  14. openModal(props => <TraceShortcutsModal {...props} />);
  15. }, [organization]);
  16. return (
  17. <Button size="xs" onClick={onOpenShortcutsClick} aria-label={t('Trace Shortcuts')}>
  18. </Button>
  19. );
  20. }
  21. const KEYBOARD_SHORTCUTS: [string, string][] = [
  22. ['\u2191 / \u2193', t('Navigate up or down')],
  23. ['\u2190 / \u2192', t('Collapse or expand')],
  24. [t('Shift') + ' + \u2191 / \u2193', t('Jump to first/last element')],
  25. ];
  26. const TIMELINE_SHORTCUTS: [string, string][] = [
  27. [t('Cmd / Ctrl + Scroll'), t('Zoom in/out at cursor')],
  28. [t('Shift + Scroll'), t('Scroll horizontally')],
  29. [t('Double click'), t('Zoom to fill')],
  30. ];
  31. function TraceShortcutsModal({Header, Body}: ModalRenderProps) {
  32. return (
  33. <Fragment>
  34. <Header closeButton>
  35. <h2>{t('Keyboard controls')}</h2>
  36. </Header>
  37. <Body>
  38. <ShortcutsLayout>
  39. <div>
  40. <Shortcuts>
  41. {KEYBOARD_SHORTCUTS.map(([key, description]) => (
  42. <Shortcut key={key}>
  43. <strong>{key}</strong>
  44. <div>{description}</div>
  45. </Shortcut>
  46. ))}
  47. {TIMELINE_SHORTCUTS.map(([key, description]) => (
  48. <Shortcut key={key}>
  49. <strong>{key}</strong>
  50. <div>{description}</div>
  51. </Shortcut>
  52. ))}
  53. </Shortcuts>
  54. </div>
  55. <div>
  56. <img src={tracingKeyboardShortcuts} alt={t('Sentry cant fix this')} />
  57. </div>
  58. </ShortcutsLayout>
  59. </Body>
  60. </Fragment>
  61. );
  62. }
  63. const ShortcutsLayout = styled('div')`
  64. display: grid;
  65. grid-template-columns: 1fr 38%;
  66. gap: ${space(2)};
  67. img {
  68. width: 100%;
  69. height: 100%;
  70. object-fit: cover;
  71. }
  72. `;
  73. const Shortcuts = styled('ul')`
  74. list-style-type: none;
  75. margin-bottom: 0;
  76. padding: 0;
  77. font-size: ${p => p.theme.fontSizeSmall};
  78. &:not(:last-child) {
  79. margin: 0 0 ${space(3)} 0;
  80. }
  81. `;
  82. const Shortcut = styled('li')`
  83. height: 28px;
  84. display: grid;
  85. grid-template-columns: min-content 1fr;
  86. strong {
  87. display: inline-block;
  88. min-width: 130px;
  89. color: ${p => p.theme.purple300};
  90. }
  91. `;