@@ -12,10 +12,6 @@ | |||
{ | |||
"link": "/documentation/instance-administration/quality-profiles/", | |||
"text": "Quality Profiles" | |||
}, | |||
{ | |||
"link": "/documentation/user-guide/keyboard-shortcuts/", | |||
"text": "Keyboard Shortcuts" | |||
} | |||
], | |||
"component_measures": [ | |||
@@ -26,10 +22,6 @@ | |||
{ | |||
"link": "/documentation/user-guide/metric-definitions/", | |||
"text": "Metric Definitions" | |||
}, | |||
{ | |||
"link": "/documentation/user-guide/keyboard-shortcuts/", | |||
"text": "Keyboard Shortcuts" | |||
} | |||
], | |||
"custom_measures": [ | |||
@@ -58,12 +50,7 @@ | |||
"scope": "sonarcloud" | |||
} | |||
], | |||
"issues": [ | |||
{ | |||
"link": "/documentation/user-guide/keyboard-shortcuts/", | |||
"text": "Keyboard Shortcuts" | |||
} | |||
], | |||
"issues": [], | |||
"marketplace": [], | |||
"organization_members": [ | |||
{ |
@@ -20,11 +20,9 @@ | |||
import * as React from 'react'; | |||
import { connect } from 'react-redux'; | |||
import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent'; | |||
import { fetchMyOrganizations } from '../../apps/account/organizations/actions'; | |||
import { isSonarCloud } from '../../helpers/system'; | |||
import { isLoggedIn } from '../../helpers/users'; | |||
import { fetchLanguages } from '../../store/rootActions'; | |||
import { getAppState, getCurrentUser, getGlobalSettingValue, Store } from '../../store/rootReducer'; | |||
import KeyboardShortcutsModal from './KeyboardShortcutsModal'; | |||
const PageTracker = lazyLoadComponent(() => import('./PageTracker')); | |||
@@ -37,7 +35,6 @@ interface StateProps { | |||
interface DispatchProps { | |||
fetchLanguages: () => Promise<void>; | |||
fetchMyOrganizations: () => Promise<void>; | |||
} | |||
interface OwnProps { | |||
@@ -53,10 +50,6 @@ class App extends React.PureComponent<Props> { | |||
this.mounted = true; | |||
this.props.fetchLanguages(); | |||
this.setScrollbarWidth(); | |||
const { appState, currentUser } = this.props; | |||
if (appState && isSonarCloud() && currentUser && isLoggedIn(currentUser)) { | |||
this.props.fetchMyOrganizations(); | |||
} | |||
} | |||
componentWillUnmount() { | |||
@@ -103,6 +96,7 @@ class App extends React.PureComponent<Props> { | |||
<> | |||
<PageTracker>{this.props.enableGravatar && this.renderPreconnectLink()}</PageTracker> | |||
{this.props.children} | |||
<KeyboardShortcutsModal /> | |||
</> | |||
); | |||
} | |||
@@ -120,8 +114,7 @@ const mapStateToProps = (state: Store): StateProps => { | |||
}; | |||
const mapDispatchToProps = ({ | |||
fetchLanguages, | |||
fetchMyOrganizations | |||
fetchLanguages | |||
} as any) as DispatchProps; | |||
export default connect(mapStateToProps, mapDispatchToProps)(App); |
@@ -0,0 +1,152 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { Button } from 'sonar-ui-common/components/controls/buttons'; | |||
import Modal from 'sonar-ui-common/components/controls/Modal'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
const CATEGORIES = [ | |||
{ | |||
category: 'global', | |||
shortcuts: [ | |||
{ keys: ['s'], action: 'search' }, | |||
{ keys: ['?'], action: 'open_shortcuts' } | |||
] | |||
}, | |||
{ | |||
category: 'code_page', | |||
shortcuts: [ | |||
{ keys: ['↑', '↓'], action: 'select_files' }, | |||
{ keys: ['→'], action: 'open_file' }, | |||
{ keys: ['←'], action: 'back' } | |||
] | |||
}, | |||
{ | |||
category: 'issues_page', | |||
shortcuts: [ | |||
{ keys: ['↑', '↓'], action: 'navigate' }, | |||
{ keys: ['→'], action: 'source_code' }, | |||
{ keys: ['←'], action: 'back' }, | |||
{ keys: ['alt', '+', '↑', '↓'], action: 'navigate_locations' }, | |||
{ keys: ['alt', '+', '←', '→'], action: 'switch_flows' }, | |||
{ keys: ['f'], action: 'transition' }, | |||
{ keys: ['a'], action: 'assign' }, | |||
{ keys: ['m'], action: 'assign_to_me' }, | |||
{ keys: ['i'], action: 'severity' }, | |||
{ keys: ['c'], action: 'comment' }, | |||
{ keys: ['ctrl', '+', 'enter'], action: 'submit_comment' }, | |||
{ keys: ['t'], action: 'tags' } | |||
] | |||
}, | |||
{ | |||
category: 'measures_page', | |||
shortcuts: [ | |||
{ keys: ['↑', '↓'], action: 'select_files' }, | |||
{ keys: ['→'], action: 'open_file' }, | |||
{ keys: ['←'], action: 'back' } | |||
] | |||
}, | |||
{ | |||
category: 'rules_page', | |||
shortcuts: [ | |||
{ keys: ['↑', '↓'], action: 'navigate' }, | |||
{ keys: ['→'], action: 'rule_details' }, | |||
{ keys: ['←'], action: 'back' } | |||
] | |||
} | |||
]; | |||
export default function KeyboardShortcutsModal() { | |||
const [display, setDisplay] = React.useState(false); | |||
React.useEffect(() => { | |||
const handleKeyPress = (event: KeyboardEvent) => { | |||
const { tagName } = event.target as HTMLElement; | |||
if (['INPUT', 'SELECT', 'TEXTAREA'].includes(tagName)) { | |||
return; // Ignore keys when typed in an input | |||
} | |||
if (event.key === '?') { | |||
setDisplay(d => !d); | |||
} | |||
}; | |||
window.addEventListener('keypress', handleKeyPress); | |||
return () => { | |||
window.removeEventListener('keypress', handleKeyPress); | |||
}; | |||
}, [setDisplay]); | |||
if (!display) { | |||
return null; | |||
} | |||
const title = translate('keyboard_shortcuts.title'); | |||
return ( | |||
<Modal contentLabel={title} onRequestClose={() => setDisplay(false)} size="medium"> | |||
<div className="modal-head"> | |||
<h2>{title}</h2> | |||
</div> | |||
<div className="modal-body modal-container markdown display-flex-wrap display-flex-space-between"> | |||
{CATEGORIES.map(({ category, shortcuts }) => ( | |||
<div key={category} className="spacer-right"> | |||
<h3>{translate('keyboard_shortcuts', category, 'title')}</h3> | |||
<table> | |||
<thead> | |||
<tr> | |||
<th>{translate('keyboard_shortcuts.shortcut')}</th> | |||
<th>{translate('keyboard_shortcuts.action')}</th> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
{shortcuts.map(({ action, keys }) => ( | |||
<tr key={action}> | |||
<td> | |||
{keys.map(k => | |||
k === '+' ? ( | |||
<span key={k} className="little-spacer-right"> | |||
{k} | |||
</span> | |||
) : ( | |||
<code key={k} className="little-spacer-right"> | |||
{k} | |||
</code> | |||
) | |||
)} | |||
</td> | |||
<td>{translate('keyboard_shortcuts', category, action)}</td> | |||
</tr> | |||
))} | |||
</tbody> | |||
</table> | |||
</div> | |||
))} | |||
</div> | |||
<div className="modal-foot"> | |||
<Button onClick={() => setDisplay(false)}>{translate('close')}</Button> | |||
</div> | |||
</Modal> | |||
); | |||
} |
@@ -0,0 +1,79 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import Modal from 'sonar-ui-common/components/controls/Modal'; | |||
import { mockEvent } from '../../../helpers/testMocks'; | |||
import KeyboardShortcutsModal from '../KeyboardShortcutsModal'; | |||
let handle: void | (() => void); | |||
beforeEach(() => { | |||
jest.spyOn(React, 'useEffect').mockImplementationOnce(f => { | |||
handle = f(); | |||
}); | |||
}); | |||
afterEach(() => { | |||
if (handle) { | |||
handle(); | |||
} | |||
}); | |||
it('should render correctly', () => { | |||
const wrapper = shallowRender(); | |||
expect(wrapper).toMatchSnapshot('hidden'); | |||
window.dispatchEvent(new KeyboardEvent('keypress', { key: '?' })); | |||
expect(wrapper).toMatchSnapshot('visible'); | |||
}); | |||
it('should close correctly', () => { | |||
const wrapper = shallowRender(); | |||
window.dispatchEvent(new KeyboardEvent('keypress', { key: '?' })); | |||
wrapper.find(Modal).props().onRequestClose!(mockEvent()); | |||
expect(wrapper.type()).toBeNull(); | |||
}); | |||
it('should ignore other keypresses', () => { | |||
const wrapper = shallowRender(); | |||
window.dispatchEvent(new KeyboardEvent('keypress', { key: '!' })); | |||
expect(wrapper.type()).toBeNull(); | |||
}); | |||
it.each([['input'], ['select'], ['textarea']])('should ignore events on a %s', type => { | |||
const wrapper = shallowRender(); | |||
const fakeEvent = new KeyboardEvent('keypress', { key: '!' }); | |||
Object.defineProperty(fakeEvent, 'target', { | |||
value: document.createElement(type) | |||
}); | |||
window.dispatchEvent(fakeEvent); | |||
expect(wrapper.type()).toBeNull(); | |||
}); | |||
function shallowRender() { | |||
return shallow(<KeyboardShortcutsModal />); | |||
} |
@@ -0,0 +1,559 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly: hidden 1`] = `""`; | |||
exports[`should render correctly: visible 1`] = ` | |||
<Modal | |||
contentLabel="keyboard_shortcuts.title" | |||
onRequestClose={[Function]} | |||
size="medium" | |||
> | |||
<div | |||
className="modal-head" | |||
> | |||
<h2> | |||
keyboard_shortcuts.title | |||
</h2> | |||
</div> | |||
<div | |||
className="modal-body modal-container markdown display-flex-wrap display-flex-space-between" | |||
> | |||
<div | |||
className="spacer-right" | |||
key="global" | |||
> | |||
<h3> | |||
keyboard_shortcuts.global.title | |||
</h3> | |||
<table> | |||
<thead> | |||
<tr> | |||
<th> | |||
keyboard_shortcuts.shortcut | |||
</th> | |||
<th> | |||
keyboard_shortcuts.action | |||
</th> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<tr | |||
key="search" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="s" | |||
> | |||
s | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.global.search | |||
</td> | |||
</tr> | |||
<tr | |||
key="open_shortcuts" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="?" | |||
> | |||
? | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.global.open_shortcuts | |||
</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</div> | |||
<div | |||
className="spacer-right" | |||
key="code_page" | |||
> | |||
<h3> | |||
keyboard_shortcuts.code_page.title | |||
</h3> | |||
<table> | |||
<thead> | |||
<tr> | |||
<th> | |||
keyboard_shortcuts.shortcut | |||
</th> | |||
<th> | |||
keyboard_shortcuts.action | |||
</th> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<tr | |||
key="select_files" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="↑" | |||
> | |||
↑ | |||
</code> | |||
<code | |||
className="little-spacer-right" | |||
key="↓" | |||
> | |||
↓ | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.code_page.select_files | |||
</td> | |||
</tr> | |||
<tr | |||
key="open_file" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="→" | |||
> | |||
→ | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.code_page.open_file | |||
</td> | |||
</tr> | |||
<tr | |||
key="back" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="←" | |||
> | |||
← | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.code_page.back | |||
</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</div> | |||
<div | |||
className="spacer-right" | |||
key="issues_page" | |||
> | |||
<h3> | |||
keyboard_shortcuts.issues_page.title | |||
</h3> | |||
<table> | |||
<thead> | |||
<tr> | |||
<th> | |||
keyboard_shortcuts.shortcut | |||
</th> | |||
<th> | |||
keyboard_shortcuts.action | |||
</th> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<tr | |||
key="navigate" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="↑" | |||
> | |||
↑ | |||
</code> | |||
<code | |||
className="little-spacer-right" | |||
key="↓" | |||
> | |||
↓ | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.issues_page.navigate | |||
</td> | |||
</tr> | |||
<tr | |||
key="source_code" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="→" | |||
> | |||
→ | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.issues_page.source_code | |||
</td> | |||
</tr> | |||
<tr | |||
key="back" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="←" | |||
> | |||
← | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.issues_page.back | |||
</td> | |||
</tr> | |||
<tr | |||
key="navigate_locations" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="alt" | |||
> | |||
alt | |||
</code> | |||
<span | |||
className="little-spacer-right" | |||
key="+" | |||
> | |||
+ | |||
</span> | |||
<code | |||
className="little-spacer-right" | |||
key="↑" | |||
> | |||
↑ | |||
</code> | |||
<code | |||
className="little-spacer-right" | |||
key="↓" | |||
> | |||
↓ | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.issues_page.navigate_locations | |||
</td> | |||
</tr> | |||
<tr | |||
key="switch_flows" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="alt" | |||
> | |||
alt | |||
</code> | |||
<span | |||
className="little-spacer-right" | |||
key="+" | |||
> | |||
+ | |||
</span> | |||
<code | |||
className="little-spacer-right" | |||
key="←" | |||
> | |||
← | |||
</code> | |||
<code | |||
className="little-spacer-right" | |||
key="→" | |||
> | |||
→ | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.issues_page.switch_flows | |||
</td> | |||
</tr> | |||
<tr | |||
key="transition" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="f" | |||
> | |||
f | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.issues_page.transition | |||
</td> | |||
</tr> | |||
<tr | |||
key="assign" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="a" | |||
> | |||
a | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.issues_page.assign | |||
</td> | |||
</tr> | |||
<tr | |||
key="assign_to_me" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="m" | |||
> | |||
m | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.issues_page.assign_to_me | |||
</td> | |||
</tr> | |||
<tr | |||
key="severity" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="i" | |||
> | |||
i | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.issues_page.severity | |||
</td> | |||
</tr> | |||
<tr | |||
key="comment" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="c" | |||
> | |||
c | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.issues_page.comment | |||
</td> | |||
</tr> | |||
<tr | |||
key="submit_comment" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="ctrl" | |||
> | |||
ctrl | |||
</code> | |||
<span | |||
className="little-spacer-right" | |||
key="+" | |||
> | |||
+ | |||
</span> | |||
<code | |||
className="little-spacer-right" | |||
key="enter" | |||
> | |||
enter | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.issues_page.submit_comment | |||
</td> | |||
</tr> | |||
<tr | |||
key="tags" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="t" | |||
> | |||
t | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.issues_page.tags | |||
</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</div> | |||
<div | |||
className="spacer-right" | |||
key="measures_page" | |||
> | |||
<h3> | |||
keyboard_shortcuts.measures_page.title | |||
</h3> | |||
<table> | |||
<thead> | |||
<tr> | |||
<th> | |||
keyboard_shortcuts.shortcut | |||
</th> | |||
<th> | |||
keyboard_shortcuts.action | |||
</th> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<tr | |||
key="select_files" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="↑" | |||
> | |||
↑ | |||
</code> | |||
<code | |||
className="little-spacer-right" | |||
key="↓" | |||
> | |||
↓ | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.measures_page.select_files | |||
</td> | |||
</tr> | |||
<tr | |||
key="open_file" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="→" | |||
> | |||
→ | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.measures_page.open_file | |||
</td> | |||
</tr> | |||
<tr | |||
key="back" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="←" | |||
> | |||
← | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.measures_page.back | |||
</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</div> | |||
<div | |||
className="spacer-right" | |||
key="rules_page" | |||
> | |||
<h3> | |||
keyboard_shortcuts.rules_page.title | |||
</h3> | |||
<table> | |||
<thead> | |||
<tr> | |||
<th> | |||
keyboard_shortcuts.shortcut | |||
</th> | |||
<th> | |||
keyboard_shortcuts.action | |||
</th> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<tr | |||
key="navigate" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="↑" | |||
> | |||
↑ | |||
</code> | |||
<code | |||
className="little-spacer-right" | |||
key="↓" | |||
> | |||
↓ | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.rules_page.navigate | |||
</td> | |||
</tr> | |||
<tr | |||
key="rule_details" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="→" | |||
> | |||
→ | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.rules_page.rule_details | |||
</td> | |||
</tr> | |||
<tr | |||
key="back" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="←" | |||
> | |||
← | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.rules_page.back | |||
</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</div> | |||
</div> | |||
<div | |||
className="modal-foot" | |||
> | |||
<Button | |||
onClick={[Function]} | |||
> | |||
close | |||
</Button> | |||
</div> | |||
</Modal> | |||
`; |
@@ -34,24 +34,6 @@ export default class EmbedDocsPopupHelper extends React.PureComponent<{}, State> | |||
mounted = false; | |||
state: State = { helpOpen: false }; | |||
componentDidMount() { | |||
window.addEventListener('keypress', this.onKeyPress); | |||
} | |||
componentWillUnmount() { | |||
window.removeEventListener('keypress', this.onKeyPress); | |||
} | |||
onKeyPress = (event: KeyboardEvent) => { | |||
const { tagName } = event.target as HTMLElement; | |||
const code = event.keyCode || event.which; | |||
const isInput = tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA'; | |||
const isTriggerKey = code === 63; | |||
if (!isInput && isTriggerKey) { | |||
this.toggleHelp(); | |||
} | |||
}; | |||
setHelpDisplay = (helpOpen: boolean) => { | |||
this.setState({ helpOpen }); | |||
}; |
@@ -2473,6 +2473,45 @@ permission_templates.delete_selected=Delete all selected items | |||
#------------------------------------------------------------------------------ | |||
markdown.helplink=Markdown Help | |||
#------------------------------------------------------------------------------ | |||
# | |||
# KEYBOARD SHORTCUTS | |||
# | |||
#------------------------------------------------------------------------------ | |||
keyboard_shortcuts.title=Keyboard Shortcuts | |||
keyboard_shortcuts.shortcut=Shortcut | |||
keyboard_shortcuts.action=Action | |||
keyboard_shortcuts.global.title=Global | |||
keyboard_shortcuts.global.search=Open the search bar | |||
keyboard_shortcuts.global.open_shortcuts=Open this panel | |||
keyboard_shortcuts.code_page.title=Code Page | |||
keyboard_shortcuts.code_page.select_files=Select files | |||
keyboard_shortcuts.code_page.open_file=Open the selected file | |||
keyboard_shortcuts.code_page.back=Return back to the list | |||
keyboard_shortcuts.issues_page.title=Issues Page | |||
keyboard_shortcuts.issues_page.navigate=navigate between issues | |||
keyboard_shortcuts.issues_page.source_code=go from the list of issues to the source code | |||
keyboard_shortcuts.issues_page.back=return back to the list | |||
keyboard_shortcuts.issues_page.navigate_locations=to navigate issue locations | |||
keyboard_shortcuts.issues_page.switch_flows=to switch flows | |||
keyboard_shortcuts.issues_page.transition=do an issue transition | |||
keyboard_shortcuts.issues_page.assign=assign issue | |||
keyboard_shortcuts.issues_page.assign_to_me=assign issue to the current user | |||
keyboard_shortcuts.issues_page.severity=change severity of issue | |||
keyboard_shortcuts.issues_page.comment=comment issue | |||
keyboard_shortcuts.issues_page.submit_comment=submit comment | |||
keyboard_shortcuts.issues_page.tags=change tags of issue | |||
keyboard_shortcuts.measures_page.title=Measures Page | |||
keyboard_shortcuts.measures_page.select_files=Select files | |||
keyboard_shortcuts.measures_page.open_file=Open the selected file | |||
keyboard_shortcuts.measures_page.back=Return back to the list | |||
keyboard_shortcuts.rules_page.title=Rules Page | |||
keyboard_shortcuts.rules_page.navigate=navigate between rules | |||
keyboard_shortcuts.rules_page.rule_details=go from the list of rules to the rule details | |||
keyboard_shortcuts.rules_page.back=Return back to the list | |||
#------------------------------------------------------------------------------ | |||
# | |||
# DURATION |