1import React from 'react'; 2import { css } from '@emotion/css'; 3import { GrafanaTheme2 } from '@grafana/data'; 4import { Modal, useStyles2 } from '@grafana/ui'; 5 6const shortcuts = { 7 Global: [ 8 { keys: ['g', 'h'], description: 'Go to Home Dashboard' }, 9 { keys: ['g', 'p'], description: 'Go to Profile' }, 10 { keys: ['s', 'o'], description: 'Open search' }, 11 { keys: ['esc'], description: 'Exit edit/setting views' }, 12 ], 13 Dashboard: [ 14 { keys: ['mod+s'], description: 'Save dashboard' }, 15 { keys: ['d', 'r'], description: 'Refresh all panels' }, 16 { keys: ['d', 's'], description: 'Dashboard settings' }, 17 { keys: ['d', 'v'], description: 'Toggle in-active / view mode' }, 18 { keys: ['d', 'k'], description: 'Toggle kiosk mode (hides top nav)' }, 19 { keys: ['d', 'E'], description: 'Expand all rows' }, 20 { keys: ['d', 'C'], description: 'Collapse all rows' }, 21 { keys: ['d', 'a'], description: 'Toggle auto fit panels (experimental feature)' }, 22 { keys: ['mod+o'], description: 'Toggle shared graph crosshair' }, 23 { keys: ['d', 'l'], description: 'Toggle all panel legends' }, 24 ], 25 'Focused Panel': [ 26 { keys: ['e'], description: 'Toggle panel edit view' }, 27 { keys: ['v'], description: 'Toggle panel fullscreen view' }, 28 { keys: ['p', 's'], description: 'Open Panel Share Modal' }, 29 { keys: ['p', 'd'], description: 'Duplicate Panel' }, 30 { keys: ['p', 'r'], description: 'Remove Panel' }, 31 { keys: ['p', 'l'], description: 'Toggle panel legend' }, 32 ], 33 'Time Range': [ 34 { keys: ['t', 'z'], description: 'Zoom out time range' }, 35 { 36 keys: ['t', '←'], 37 description: 'Move time range back', 38 }, 39 { 40 keys: ['t', '→'], 41 description: 'Move time range forward', 42 }, 43 ], 44}; 45 46export interface HelpModalProps { 47 onDismiss: () => void; 48} 49 50export const HelpModal = ({ onDismiss }: HelpModalProps): JSX.Element => { 51 const styles = useStyles2(getStyles); 52 return ( 53 <Modal title="Shortcuts" isOpen onDismiss={onDismiss} onClickBackdrop={onDismiss}> 54 <div className={styles.titleDescription}> 55 <span className={styles.shortcutTableKey}>mod</span> =<span> CTRL on windows or linux and CMD key on Mac</span> 56 </div> 57 <div className={styles.categories}> 58 {Object.entries(shortcuts).map(([category, shortcuts], i) => ( 59 <div className={styles.shortcutCategory} key={i}> 60 <table className={styles.shortcutTable}> 61 <tbody> 62 <tr> 63 <th className={styles.shortcutTableCategoryHeader} colSpan={2}> 64 {category} 65 </th> 66 </tr> 67 {shortcuts.map((shortcut, j) => ( 68 <tr key={`${i}-${j}`}> 69 <td className={styles.shortcutTableKeys}> 70 {shortcut.keys.map((key, k) => ( 71 <span className={styles.shortcutTableKey} key={`${i}-${j}-${k}`}> 72 {key} 73 </span> 74 ))} 75 </td> 76 <td className={styles.shortcutTableDescription}>{shortcut.description}</td> 77 </tr> 78 ))} 79 </tbody> 80 </table> 81 </div> 82 ))} 83 </div> 84 </Modal> 85 ); 86}; 87 88function getStyles(theme: GrafanaTheme2) { 89 return { 90 titleDescription: css` 91 font-size: ${theme.typography.bodySmall.fontSize}; 92 font-weight: ${theme.typography.bodySmall.fontWeight}; 93 color: ${theme.colors.text.disabled}; 94 padding-bottom: ${theme.spacing(2)}; 95 `, 96 categories: css` 97 font-size: ${theme.typography.bodySmall.fontSize}; 98 display: flex; 99 flex-flow: row wrap; 100 justify-content: space-between; 101 align-items: flex-start; 102 `, 103 shortcutCategory: css` 104 width: 50%; 105 font-size: ${theme.typography.bodySmall.fontSize}; 106 `, 107 shortcutTable: css` 108 margin-bottom: ${theme.spacing(2)}; 109 `, 110 shortcutTableCategoryHeader: css` 111 font-weight: normal; 112 font-size: ${theme.typography.h6.fontSize}; 113 text-align: left; 114 `, 115 shortcutTableDescription: css` 116 text-align: left; 117 color: ${theme.colors.text.disabled}; 118 width: 99%; 119 padding: ${theme.spacing(1, 2)}; 120 `, 121 shortcutTableKeys: css` 122 white-space: nowrap; 123 width: 1%; 124 text-align: right; 125 color: ${theme.colors.text.primary}; 126 `, 127 shortcutTableKey: css` 128 display: inline-block; 129 text-align: center; 130 margin-right: ${theme.spacing(0.5)}; 131 padding: 3px 5px; 132 font: 11px Consolas, 'Liberation Mono', Menlo, Courier, monospace; 133 line-height: 10px; 134 vertical-align: middle; 135 border: solid 1px ${theme.colors.border.medium}; 136 border-radius: ${theme.shape.borderRadius(3)}; 137 color: ${theme.colors.text.primary}; 138 background-color: ${theme.colors.background.secondary}; 139 `, 140 }; 141} 142