Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-05-19 18:44:42 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-05-19 18:44:42 +0300
commit4555e1b21c365ed8303ffb7a3325d773c9b8bf31 (patch)
tree5423a1c7516cffe36384133ade12572cf709398d /app/assets/javascripts/behaviors
parente570267f2f6b326480d284e0164a6464ba4081bc (diff)
Add latest changes from gitlab-org/gitlab@13-12-stable-eev13.12.0-rc42
Diffstat (limited to 'app/assets/javascripts/behaviors')
-rw-r--r--app/assets/javascripts/behaviors/date_picker.js33
-rw-r--r--app/assets/javascripts/behaviors/markdown/render_math.js6
-rw-r--r--app/assets/javascripts/behaviors/markdown/render_mermaid.js19
-rw-r--r--app/assets/javascripts/behaviors/shortcuts/keybindings.js2
-rw-r--r--app/assets/javascripts/behaviors/shortcuts/shortcut.vue80
-rw-r--r--app/assets/javascripts/behaviors/shortcuts/shortcuts_help.vue574
-rw-r--r--app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.vue6
7 files changed, 213 insertions, 507 deletions
diff --git a/app/assets/javascripts/behaviors/date_picker.js b/app/assets/javascripts/behaviors/date_picker.js
new file mode 100644
index 00000000000..efd89ec4330
--- /dev/null
+++ b/app/assets/javascripts/behaviors/date_picker.js
@@ -0,0 +1,33 @@
+import $ from 'jquery';
+import Pikaday from 'pikaday';
+import { parsePikadayDate, pikadayToString } from '~/lib/utils/datetime_utility';
+
+export default function initDatePickers() {
+ $('.datepicker').each(function initPikaday() {
+ const $datePicker = $(this);
+ const datePickerVal = $datePicker.val();
+
+ const calendar = new Pikaday({
+ field: $datePicker.get(0),
+ theme: 'gitlab-theme animate-picker',
+ format: 'yyyy-mm-dd',
+ container: $datePicker.parent().get(0),
+ parse: (dateString) => parsePikadayDate(dateString),
+ toString: (date) => pikadayToString(date),
+ onSelect(dateText) {
+ $datePicker.val(calendar.toString(dateText));
+ },
+ firstDay: gon.first_day_of_week,
+ });
+
+ calendar.setDate(parsePikadayDate(datePickerVal));
+
+ $datePicker.data('pikaday', calendar);
+ });
+
+ $('.js-clear-due-date,.js-clear-start-date').on('click', (e) => {
+ e.preventDefault();
+ const calendar = $(e.target).siblings('.datepicker').data('pikaday');
+ calendar.setDate(null);
+ });
+}
diff --git a/app/assets/javascripts/behaviors/markdown/render_math.js b/app/assets/javascripts/behaviors/markdown/render_math.js
index 8238f5523f3..12f47255bdf 100644
--- a/app/assets/javascripts/behaviors/markdown/render_math.js
+++ b/app/assets/javascripts/behaviors/markdown/render_math.js
@@ -114,6 +114,12 @@ class SafeMathRenderer {
throwOnError: true,
maxSize: 20,
maxExpand: 20,
+ trust: (context) =>
+ // this config option restores the KaTeX pre-v0.11.0
+ // behavior of allowing certain commands and protocols
+ // eslint-disable-next-line @gitlab/require-i18n-strings
+ ['\\url', '\\href'].includes(context.command) &&
+ ['http', 'https', 'mailto', '_relative'].includes(context.protocol),
});
} catch (e) {
// Don't show a flash for now because it would override an existing flash message
diff --git a/app/assets/javascripts/behaviors/markdown/render_mermaid.js b/app/assets/javascripts/behaviors/markdown/render_mermaid.js
index 5b5148a850b..f5b2d266c18 100644
--- a/app/assets/javascripts/behaviors/markdown/render_mermaid.js
+++ b/app/assets/javascripts/behaviors/markdown/render_mermaid.js
@@ -1,5 +1,5 @@
import $ from 'jquery';
-import { once } from 'lodash';
+import { once, countBy } from 'lodash';
import { deprecatedCreateFlash as flash } from '~/flash';
import { darkModeEnabled } from '~/lib/utils/color_utils';
import { __, sprintf } from '~/locale';
@@ -22,6 +22,8 @@ import { __, sprintf } from '~/locale';
const MAX_CHAR_LIMIT = 2000;
// Max # of mermaid blocks that can be rendered in a page.
const MAX_MERMAID_BLOCK_LIMIT = 50;
+// Max # of `&` allowed in Chaining of links syntax
+const MAX_CHAINING_OF_LINKS_LIMIT = 30;
// Keep a map of mermaid blocks we've already rendered.
const elsProcessingMap = new WeakMap();
let renderedMermaidBlocks = 0;
@@ -64,6 +66,18 @@ function importMermaidModule() {
});
}
+function shouldLazyLoadMermaidBlock(source) {
+ /**
+ * If source contains `&`, which means that it might
+ * contain Chaining of links a new syntax in Mermaid.
+ */
+ if (countBy(source)['&'] > MAX_CHAINING_OF_LINKS_LIMIT) {
+ return true;
+ }
+
+ return false;
+}
+
function fixElementSource(el) {
// Mermaid doesn't like `<br />` tags, so collapse all like tags into `<br>`, which is parsed correctly.
const source = el.textContent.replace(/<br\s*\/>/g, '<br>');
@@ -128,7 +142,8 @@ function renderMermaids($els) {
if (
(source && source.length > MAX_CHAR_LIMIT) ||
renderedChars > MAX_CHAR_LIMIT ||
- renderedMermaidBlocks >= MAX_MERMAID_BLOCK_LIMIT
+ renderedMermaidBlocks >= MAX_MERMAID_BLOCK_LIMIT ||
+ shouldLazyLoadMermaidBlock(source)
) {
const html = `
<div class="alert gl-alert gl-alert-warning alert-dismissible lazy-render-mermaid-container js-lazy-render-mermaid-container fade show" role="alert">
diff --git a/app/assets/javascripts/behaviors/shortcuts/keybindings.js b/app/assets/javascripts/behaviors/shortcuts/keybindings.js
index 6abbd7f3243..c63dba05f10 100644
--- a/app/assets/javascripts/behaviors/shortcuts/keybindings.js
+++ b/app/assets/javascripts/behaviors/shortcuts/keybindings.js
@@ -375,7 +375,7 @@ export const MR_PREVIOUS_FILE_IN_DIFF = {
export const MR_GO_TO_FILE = {
id: 'mergeRequests.goToFile',
description: __('Go to file'),
- defaultKeys: ['t', 'mod+p'],
+ defaultKeys: ['mod+p', 't'],
customizable: false,
};
diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcut.vue b/app/assets/javascripts/behaviors/shortcuts/shortcut.vue
new file mode 100644
index 00000000000..e5992779a99
--- /dev/null
+++ b/app/assets/javascripts/behaviors/shortcuts/shortcut.vue
@@ -0,0 +1,80 @@
+<script>
+import { __, s__ } from '~/locale';
+
+// Map some keys to their proper representation depending on the system
+// See also: https://craig.is/killing/mice#keys
+const getKeyMap = () => {
+ const keyMap = {
+ up: '↑',
+ down: '↓',
+ left: '←',
+ right: '→',
+ ctrl: s__('KeyboardKey|Ctrl'),
+ shift: s__('KeyboardKey|Shift'),
+ enter: s__('KeyboardKey|Enter'),
+ esc: s__('KeyboardKey|Esc'),
+ command: '⌘',
+ option: window.gl?.client?.isMac ? '⌥' : s__('KeyboardKey|Alt'),
+ };
+
+ // Meta and alt are aliases
+ keyMap.meta = keyMap.command;
+ keyMap.alt = keyMap.option;
+
+ // Mod is Command on Mac, and Ctrl on Windows/Linux
+ keyMap.mod = window.gl?.client?.isMac ? keyMap.command : keyMap.ctrl;
+
+ return keyMap;
+};
+
+export default {
+ functional: true,
+ props: {
+ shortcuts: {
+ type: Array,
+ required: true,
+ },
+ },
+
+ render(createElement, context) {
+ const keyMap = getKeyMap();
+
+ const { staticClass } = context.data;
+
+ const shortcuts = context.props.shortcuts.reduce((acc, shortcut, i) => {
+ if (
+ !window.gl?.client?.isMac &&
+ (shortcut.includes('command') || shortcut.includes('meta'))
+ ) {
+ return acc;
+ }
+ const keys = shortcut.split(/([ +])/);
+
+ if (i !== 0 && acc.length) {
+ acc.push(` ${__('or')} `);
+ // If there are multiple alternative shortcuts,
+ // we keep them on the same line if they are single-key, e.g. `]` or `j`
+ // but if they consist of multiple keys, we insert a line break, e.g.:
+ // `shift` + `]` <br> or `shift` + `j`
+ if (keys.length > 1) {
+ acc.push(createElement('br'));
+ }
+ }
+
+ keys.forEach((key) => {
+ if (key === '+') {
+ acc.push(' + ');
+ } else if (key === ' ') {
+ acc.push(` ${__('then')} `);
+ } else {
+ acc.push(createElement('kbd', {}, [keyMap[key] ?? key]));
+ }
+ });
+
+ return acc;
+ }, []);
+
+ return createElement('div', { staticClass }, shortcuts);
+ },
+};
+</script>
diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts_help.vue b/app/assets/javascripts/behaviors/shortcuts/shortcuts_help.vue
index 49216cc4aa0..cb7c6f9f6bc 100644
--- a/app/assets/javascripts/behaviors/shortcuts/shortcuts_help.vue
+++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts_help.vue
@@ -1,525 +1,99 @@
<script>
-/* eslint-disable @gitlab/vue-require-i18n-strings */
-import { GlIcon, GlModal } from '@gitlab/ui';
+import { GlModal, GlSearchBoxByType } from '@gitlab/ui';
+import { s__, __ } from '~/locale';
+import { keybindingGroups } from './keybindings';
+import Shortcut from './shortcut.vue';
import ShortcutsToggle from './shortcuts_toggle.vue';
export default {
components: {
- GlIcon,
GlModal,
+ GlSearchBoxByType,
ShortcutsToggle,
+ Shortcut,
+ },
+ data() {
+ return {
+ searchTerm: '',
+ };
},
computed: {
- ctrlCharacter() {
- return window.gl.client.isMac ? '⌘' : 'ctrl';
- },
- onDotCom() {
- return window.gon.dot_com;
+ filteredKeybindings() {
+ if (!this.searchTerm) {
+ return keybindingGroups;
+ }
+
+ const search = this.searchTerm.toLocaleLowerCase();
+
+ const mapped = keybindingGroups.map((group) => {
+ if (group.name.toLocaleLowerCase().includes(search)) {
+ return group;
+ }
+ return {
+ ...group,
+ keybindings: group.keybindings.filter((binding) =>
+ binding.description.toLocaleLowerCase().includes(search),
+ ),
+ };
+ });
+
+ return mapped.filter((group) => group.keybindings.length);
},
},
+ i18n: {
+ title: __(`Keyboard shortcuts`),
+ search: s__(`KeyboardShortcuts|Search keyboard shortcuts`),
+ noMatch: s__(`KeyboardShortcuts|No shortcuts matched your search`),
+ },
};
</script>
<template>
<gl-modal
modal-id="keyboard-shortcut-modal"
size="lg"
+ :title="$options.i18n.title"
data-testid="modal-shortcuts"
+ body-class="shortcut-help-body gl-p-0!"
:visible="true"
:hide-footer="true"
@hidden="$emit('hidden')"
>
- <template #modal-title>
- <shortcuts-toggle />
- </template>
- <div class="row">
- <div class="col-lg-4">
- <table class="shortcut-mappings text-2">
- <tbody>
- <tr>
- <th></th>
- <th>{{ __('Global Shortcuts') }}</th>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>?</kbd>
- </td>
- <td>{{ __('Toggle this dialog') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>shift p</kbd>
- </td>
- <td>{{ __('Go to your projects') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>shift g</kbd>
- </td>
- <td>{{ __('Go to your groups') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>shift a</kbd>
- </td>
- <td>{{ __('Go to the activity feed') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>shift l</kbd>
- </td>
- <td>{{ __('Go to the milestone list') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>shift s</kbd>
- </td>
- <td>{{ __('Go to your snippets') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>s</kbd>
- /
- <kbd>/</kbd>
- </td>
- <td>{{ __('Start search') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>shift i</kbd>
- </td>
- <td>{{ __('Go to your issues') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>shift m</kbd>
- </td>
- <td>{{ __('Go to your merge requests') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>shift t</kbd>
- </td>
- <td>{{ __('Go to your To-Do list') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>p</kbd>
- <kbd>b</kbd>
- </td>
- <td>{{ __('Toggle the Performance Bar') }}</td>
- </tr>
- <tr v-if="onDotCom">
- <td class="shortcut">
- <kbd>g</kbd>
- <kbd>x</kbd>
- </td>
- <td>{{ __('Toggle GitLab Next') }}</td>
- </tr>
- </tbody>
- <tbody>
- <tr>
- <th></th>
- <th>{{ __('Editing') }}</th>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>{{ ctrlCharacter }} shift p</kbd>
- </td>
- <td>{{ __('Toggle Markdown preview') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>
- <gl-icon name="arrow-up" />
- </kbd>
- </td>
- <td>
- {{ __('Edit your most recent comment in a thread (from an empty textarea)') }}
- </td>
- </tr>
- </tbody>
- <tbody>
- <tr>
- <th></th>
- <th>{{ __('Wiki') }}</th>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>e</kbd>
- </td>
- <td>{{ __('Edit wiki page') }}</td>
- </tr>
- </tbody>
- <tbody>
- <tr>
- <th></th>
- <th>{{ __('Repository Graph') }}</th>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>
- <gl-icon name="arrow-left" />
- </kbd>
- /
- <kbd>h</kbd>
- </td>
- <td>{{ __('Scroll left') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>
- <gl-icon name="arrow-right" />
- </kbd>
- /
- <kbd>l</kbd>
- </td>
- <td>{{ __('Scroll right') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>
- <gl-icon name="arrow-up" />
- </kbd>
- /
- <kbd>k</kbd>
- </td>
- <td>{{ __('Scroll up') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>
- <gl-icon name="arrow-down" />
- </kbd>
- /
- <kbd>j</kbd>
- </td>
- <td>{{ __('Scroll down') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>
- shift
- <gl-icon name="arrow-up" />
- / k
- </kbd>
- </td>
- <td>{{ __('Scroll to top') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>
- shift
- <gl-icon name="arrow-down" />
- / j
- </kbd>
- </td>
- <td>{{ __('Scroll to bottom') }}</td>
- </tr>
- </tbody>
- </table>
- </div>
- <div class="col-lg-4">
- <table class="shortcut-mappings text-2">
- <tbody>
- <tr>
- <th></th>
- <th>{{ __('Project') }}</th>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>g</kbd>
- <kbd>p</kbd>
- </td>
- <td>{{ __("Go to the project's overview page") }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>g</kbd>
- <kbd>v</kbd>
- </td>
- <td>{{ __("Go to the project's activity feed") }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>g</kbd>
- <kbd>r</kbd>
- </td>
- <td>{{ __('Go to releases') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>g</kbd>
- <kbd>f</kbd>
- </td>
- <td>{{ __('Go to files') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>t</kbd>
- </td>
- <td>{{ __('Go to find file') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>g</kbd>
- <kbd>c</kbd>
- </td>
- <td>{{ __('Go to commits') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>g</kbd>
- <kbd>n</kbd>
- </td>
- <td>{{ __('Go to repository graph') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>g</kbd>
- <kbd>d</kbd>
- </td>
- <td>{{ __('Go to repository charts') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>g</kbd>
- <kbd>i</kbd>
- </td>
- <td>{{ __('Go to issues') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>i</kbd>
- </td>
- <td>{{ __('New issue') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>g</kbd>
- <kbd>b</kbd>
- </td>
- <td>{{ __('Go to issue boards') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>g</kbd>
- <kbd>m</kbd>
- </td>
- <td>{{ __('Go to merge requests') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>g</kbd>
- <kbd>j</kbd>
- </td>
- <td>{{ __('Go to jobs') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>g</kbd>
- <kbd>l</kbd>
- </td>
- <td>{{ __('Go to metrics') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>g</kbd>
- <kbd>e</kbd>
- </td>
- <td>{{ __('Go to environments') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>g</kbd>
- <kbd>k</kbd>
- </td>
- <td>{{ __('Go to kubernetes') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>g</kbd>
- <kbd>s</kbd>
- </td>
- <td>{{ __('Go to snippets') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>g</kbd>
- <kbd>w</kbd>
- </td>
- <td>{{ __('Go to wiki') }}</td>
- </tr>
- </tbody>
- <tbody>
- <tr>
- <th></th>
- <th>{{ __('Project Files') }}</th>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>
- <gl-icon name="arrow-up" />
- </kbd>
- </td>
- <td>{{ __('Move selection up') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>
- <gl-icon name="arrow-down" />
- </kbd>
- </td>
- <td>{{ __('Move selection down') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>enter</kbd>
- </td>
- <td>{{ __('Open Selection') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>esc</kbd>
- </td>
- <td>{{ __('Go back (while searching for files)') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>y</kbd>
- </td>
- <td>{{ __('Go to file permalink (while viewing a file)') }}</td>
- </tr>
- </tbody>
- </table>
- </div>
- <div class="col-lg-4">
- <table class="shortcut-mappings text-2">
- <tbody>
- <tr>
- <th></th>
- <th>{{ __('Epics, issues, and merge requests') }}</th>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>r</kbd>
- </td>
- <td>{{ __('Comment/Reply (quoting selected text)') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>e</kbd>
- </td>
- <td>{{ __('Edit description') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>l</kbd>
- </td>
- <td>{{ __('Change label') }}</td>
- </tr>
- </tbody>
- <tbody>
- <tr>
- <th></th>
- <th>{{ __('Issues and merge requests') }}</th>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>a</kbd>
- </td>
- <td>{{ __('Change assignee') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>m</kbd>
- </td>
- <td>{{ __('Change milestone') }}</td>
- </tr>
- </tbody>
- <tbody>
- <tr>
- <th></th>
- <th>{{ __('Merge requests') }}</th>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>]</kbd>
- /
- <kbd>j</kbd>
- </td>
- <td>{{ __('Next file in diff') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>[</kbd>
- /
- <kbd>k</kbd>
- </td>
- <td>{{ __('Previous file in diff') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>{{ ctrlCharacter }} p</kbd>
- </td>
- <td>{{ __('Go to file') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>n</kbd>
- </td>
- <td>{{ __('Next unresolved discussion') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>p</kbd>
- </td>
- <td>{{ __('Previous unresolved discussion') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>b</kbd>
- </td>
- <td>{{ __('Copy source branch name') }}</td>
- </tr>
- </tbody>
- <tbody>
- <tr>
- <th></th>
- <th>{{ __('Merge request commits') }}</th>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>c</kbd>
- </td>
- <td>{{ __('Next commit') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>x</kbd>
- </td>
- <td>{{ __('Previous commit') }}</td>
- </tr>
- </tbody>
- <tbody>
- <tr>
- <th></th>
- <th>{{ __('Web IDE') }}</th>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>{{ ctrlCharacter }} p</kbd>
- </td>
- <td>{{ __('Go to file') }}</td>
- </tr>
- <tr>
- <td class="shortcut">
- <kbd>{{ ctrlCharacter }} enter</kbd>
- </td>
- <td>{{ __('Commit (when editing commit message)') }}</td>
- </tr>
- </tbody>
- </table>
- </div>
+ <div
+ class="gl-sticky gl-top-0 gl-py-5 gl-px-5 gl-display-flex gl-align-items-center gl-bg-white"
+ >
+ <gl-search-box-by-type
+ v-model.trim="searchTerm"
+ :aria-label="$options.i18n.search"
+ class="gl-w-half gl-mr-3"
+ />
+ <shortcuts-toggle class="gl-w-half gl-ml-3" />
+ </div>
+ <div v-if="filteredKeybindings.length === 0" class="gl-px-5">
+ {{ $options.i18n.noMatch }}
+ </div>
+ <div v-else class="shortcut-help-container gl-mt-8 gl-px-5 gl-pb-5">
+ <section
+ v-for="group in filteredKeybindings"
+ :key="group.id"
+ class="shortcut-help-mapping gl-mb-4"
+ >
+ <strong class="shortcut-help-mapping-title gl-w-half gl-display-inline-block">
+ {{ group.name }}
+ </strong>
+ <div
+ v-for="keybinding in group.keybindings"
+ :key="keybinding.id"
+ class="gl-display-flex gl-align-items-center"
+ >
+ <shortcut
+ class="gl-w-40p gl-flex-shrink-0 gl-text-right gl-pr-4"
+ :shortcuts="keybinding.defaultKeys"
+ />
+ <div class="gl-w-half gl-flex-shrink-0 gl-flex-grow-1">
+ {{ keybinding.description }}
+ </div>
+ </div>
+ </section>
</div>
</gl-modal>
</template>
diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.vue b/app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.vue
index 6cbe443062a..8f1518a1c9c 100644
--- a/app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.vue
+++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.vue
@@ -6,7 +6,7 @@ import { disableShortcuts, enableShortcuts, shouldDisableShortcuts } from './sho
export default {
i18n: {
- toggleLabel: __('Keyboard shortcuts'),
+ toggleLabel: __('Toggle shortcuts'),
},
components: {
GlToggle,
@@ -31,14 +31,12 @@ export default {
</script>
<template>
- <div v-if="localStorageUsable" class="d-inline-flex align-items-center js-toggle-shortcuts">
+ <div v-if="localStorageUsable" class="js-toggle-shortcuts">
<gl-toggle
v-model="shortcutsEnabled"
- aria-describedby="shortcutsToggle"
:label="$options.i18n.toggleLabel"
label-position="left"
@change="onChange"
/>
- <div id="shortcutsToggle" class="sr-only">{{ __('Enable or disable keyboard shortcuts') }}</div>
</div>
</template>