diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-04-24 18:15:38 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-04-24 18:15:38 +0300 |
commit | efbf661c4224d481c57d0346e26983a805e5ec93 (patch) | |
tree | 4736f287350884cb49d84a09c52c8c2e1b851080 /app/assets/javascripts | |
parent | 4720346c2e10e1ff62a20b39dfc9866eb88858e6 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts')
45 files changed, 386 insertions, 360 deletions
diff --git a/app/assets/javascripts/add_context_commits_modal/components/add_context_commits_modal_wrapper.vue b/app/assets/javascripts/add_context_commits_modal/components/add_context_commits_modal_wrapper.vue index a5f8f369604..a9fb692b299 100644 --- a/app/assets/javascripts/add_context_commits_modal/components/add_context_commits_modal_wrapper.vue +++ b/app/assets/javascripts/add_context_commits_modal/components/add_context_commits_modal_wrapper.vue @@ -18,6 +18,7 @@ import { removeIfPresent, } from '../utils'; import Token from './token.vue'; +import DateOption from './date_option.vue'; export default { components: { @@ -73,6 +74,7 @@ export default { operators: OPERATORS_IS, token: Token, unique: true, + optionComponent: DateOption, }, { formattedKey: __('Committed-after'), @@ -86,6 +88,7 @@ export default { operators: OPERATORS_IS, token: Token, unique: true, + optionComponent: DateOption, }, ], }; @@ -317,16 +320,7 @@ export default { :available-tokens="availableTokens" @clear="handleSearchCommits" @submit="handleSearchCommits" - > - <template #title="{ value }"> - <div> - {{ value }} - <span v-if="shouldShowInputDateFormat(value)" class="title-hint-text"> - <{{ __('yyyy-mm-dd') }}> - </span> - </div> - </template> - </gl-filtered-search> + /> <review-tab-container :is-loading="isLoadingCommits" diff --git a/app/assets/javascripts/add_context_commits_modal/components/date_option.vue b/app/assets/javascripts/add_context_commits_modal/components/date_option.vue new file mode 100644 index 00000000000..1945e048029 --- /dev/null +++ b/app/assets/javascripts/add_context_commits_modal/components/date_option.vue @@ -0,0 +1,17 @@ +<script> +export default { + props: { + option: { + type: Object, + required: true, + }, + }, +}; +</script> + +<template> + <span + >{{ option.title }} + <span class="title-hint-text"><{{ __('yyyy-mm-dd') }}></span> + </span> +</template> diff --git a/app/assets/javascripts/admin/broadcast_messages/components/message_form.vue b/app/assets/javascripts/admin/broadcast_messages/components/message_form.vue index 3168d693234..08aec58e89d 100644 --- a/app/assets/javascripts/admin/broadcast_messages/components/message_form.vue +++ b/app/assets/javascripts/admin/broadcast_messages/components/message_form.vue @@ -15,7 +15,6 @@ import axios from '~/lib/utils/axios_utils'; import { s__ } from '~/locale'; import { createAlert, VARIANT_DANGER } from '~/alert'; import { redirectTo } from '~/lib/utils/url_utility'; -import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants'; import SafeHtml from '~/vue_shared/directives/safe_html'; import { THEMES, TYPES, TYPE_BANNER } from '../constants'; @@ -42,7 +41,6 @@ export default { directives: { SafeHtml, }, - mixins: [glFeatureFlagsMixin()], inject: { targetAccessLevelOptions: { default: [[]], @@ -226,11 +224,7 @@ export default { </gl-form-group> </template> - <gl-form-group - v-if="glFeatures.roleTargetedBroadcastMessages" - :label="$options.i18n.targetRoles" - data-testid="target-roles-checkboxes" - > + <gl-form-group :label="$options.i18n.targetRoles" data-testid="target-roles-checkboxes"> <gl-form-checkbox-group v-model="targetAccessLevels" :options="targetAccessLevelOptions" /> <gl-form-text> {{ $options.i18n.targetRolesDescription }} diff --git a/app/assets/javascripts/admin/broadcast_messages/components/messages_table.vue b/app/assets/javascripts/admin/broadcast_messages/components/messages_table.vue index a523dd3b391..2e8ecbd3a5d 100644 --- a/app/assets/javascripts/admin/broadcast_messages/components/messages_table.vue +++ b/app/assets/javascripts/admin/broadcast_messages/components/messages_table.vue @@ -3,7 +3,6 @@ import { GlButton, GlTableLite } from '@gitlab/ui'; import SafeHtml from '~/vue_shared/directives/safe_html'; import { __ } from '~/locale'; import { formatDate } from '~/lib/utils/datetime/date_format_utility'; -import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; const DEFAULT_TD_CLASSES = 'gl-vertical-align-middle!'; @@ -16,7 +15,6 @@ export default { directives: { SafeHtml, }, - mixins: [glFeatureFlagsMixin()], i18n: { edit: __('Edit'), delete: __('Delete'), @@ -27,13 +25,7 @@ export default { required: true, }, }, - computed: { - fields() { - if (this.glFeatures.roleTargetedBroadcastMessages) return this.$options.allFields; - return this.$options.allFields.filter((f) => f.key !== 'target_roles'); - }, - }, - allFields: [ + fields: [ { key: 'status', label: __('Status'), @@ -89,7 +81,7 @@ export default { <template> <gl-table-lite :items="messages" - :fields="fields" + :fields="$options.fields" :tbody-tr-attr="{ 'data-testid': 'message-row' }" stacked="md" > diff --git a/app/assets/javascripts/authentication/two_factor_auth/components/recovery_codes.vue b/app/assets/javascripts/authentication/two_factor_auth/components/recovery_codes.vue index 9cf41750efe..f23a6fbcaa0 100644 --- a/app/assets/javascripts/authentication/two_factor_auth/components/recovery_codes.vue +++ b/app/assets/javascripts/authentication/two_factor_auth/components/recovery_codes.vue @@ -1,6 +1,6 @@ <script> import { GlSprintf, GlButton, GlAlert, GlCard } from '@gitlab/ui'; -import Mousetrap from 'mousetrap'; +import { Mousetrap } from '~/lib/mousetrap'; import { __ } from '~/locale'; import Tracking from '~/tracking'; import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; diff --git a/app/assets/javascripts/behaviors/shortcuts/keybindings.js b/app/assets/javascripts/behaviors/shortcuts/keybindings.js index d173703f172..cc8a9baf69e 100644 --- a/app/assets/javascripts/behaviors/shortcuts/keybindings.js +++ b/app/assets/javascripts/behaviors/shortcuts/keybindings.js @@ -698,8 +698,8 @@ export const keybindingGroups = [ /** * Gets keyboard shortcuts associated with a command * - * @param {string} command The command object. All command - * objects are available as imports from this file. + * @param {Object} command The command object. All command objects are + * available as imports from this file. * * @returns {string[]} An array of keyboard shortcut strings bound to the command * diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts.js index 301dd1c5669..5c6e4665a5c 100644 --- a/app/assets/javascripts/behaviors/shortcuts/shortcuts.js +++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts.js @@ -1,7 +1,7 @@ import $ from 'jquery'; import { flatten } from 'lodash'; -import Mousetrap from 'mousetrap'; import Vue from 'vue'; +import { Mousetrap, addStopCallback } from '~/lib/mousetrap'; import { getCookie, setCookie, parseBoolean } from '~/lib/utils/common_utils'; import findAndFollowLink from '~/lib/utils/navigation_utility'; @@ -28,20 +28,11 @@ import { } from './keybindings'; import { disableShortcuts, shouldDisableShortcuts } from './shortcuts_toggle'; -const defaultStopCallback = Mousetrap.prototype.stopCallback; -Mousetrap.prototype.stopCallback = function customStopCallback(e, element, combo) { - if (keysFor(TOGGLE_MARKDOWN_PREVIEW).indexOf(combo) !== -1) { - return false; - } - - return defaultStopCallback.call(this, e, element, combo); -}; - /** * The key used to save and fetch the local Mousetrap instance * attached to a `<textarea>` element using `jQuery.data` */ -const LOCAL_MOUSETRAP_DATA_KEY = 'local-mousetrap-instance'; +export const LOCAL_MOUSETRAP_DATA_KEY = 'local-mousetrap-instance'; /** * Gets a mapping of toolbar button => keyboard shortcuts @@ -76,54 +67,38 @@ export default class Shortcuts { this.helpModalElement = null; this.helpModalVueInstance = null; - Mousetrap.bind(keysFor(TOGGLE_KEYBOARD_SHORTCUTS_DIALOG), this.onToggleHelp); - Mousetrap.bind(keysFor(START_SEARCH), Shortcuts.focusSearch); - Mousetrap.bind(keysFor(FOCUS_FILTER_BAR), this.focusFilter.bind(this)); - Mousetrap.bind(keysFor(TOGGLE_PERFORMANCE_BAR), Shortcuts.onTogglePerfBar); - Mousetrap.bind(keysFor(HIDE_APPEARING_CONTENT), Shortcuts.hideAppearingContent); - Mousetrap.bind(keysFor(TOGGLE_CANARY), Shortcuts.onToggleCanary); - - const findFileURL = document.body.dataset.findFile; - - Mousetrap.bind(keysFor(GO_TO_YOUR_TODO_LIST), () => findAndFollowLink('.shortcuts-todos')); - Mousetrap.bind(keysFor(GO_TO_ACTIVITY_FEED), () => - findAndFollowLink('.dashboard-shortcuts-activity'), - ); - Mousetrap.bind(keysFor(GO_TO_YOUR_ISSUES), () => - findAndFollowLink('.dashboard-shortcuts-issues'), + this.bindCommands([ + [TOGGLE_KEYBOARD_SHORTCUTS_DIALOG, this.onToggleHelp], + [START_SEARCH, Shortcuts.focusSearch], + [FOCUS_FILTER_BAR, this.focusFilter.bind(this)], + [TOGGLE_PERFORMANCE_BAR, Shortcuts.onTogglePerfBar], + [HIDE_APPEARING_CONTENT, Shortcuts.hideAppearingContent], + [TOGGLE_CANARY, Shortcuts.onToggleCanary], + + [GO_TO_YOUR_TODO_LIST, () => findAndFollowLink('.shortcuts-todos')], + [GO_TO_ACTIVITY_FEED, () => findAndFollowLink('.dashboard-shortcuts-activity')], + [GO_TO_YOUR_ISSUES, () => findAndFollowLink('.dashboard-shortcuts-issues')], + [GO_TO_YOUR_MERGE_REQUESTS, () => findAndFollowLink('.dashboard-shortcuts-merge_requests')], + [GO_TO_YOUR_REVIEW_REQUESTS, () => findAndFollowLink('.dashboard-shortcuts-review_requests')], + [GO_TO_YOUR_PROJECTS, () => findAndFollowLink('.dashboard-shortcuts-projects')], + [GO_TO_YOUR_GROUPS, () => findAndFollowLink('.dashboard-shortcuts-groups')], + [GO_TO_MILESTONE_LIST, () => findAndFollowLink('.dashboard-shortcuts-milestones')], + [GO_TO_YOUR_SNIPPETS, () => findAndFollowLink('.dashboard-shortcuts-snippets')], + + [TOGGLE_MARKDOWN_PREVIEW, Shortcuts.toggleMarkdownPreview], + ]); + + addStopCallback((e, element, combo) => + keysFor(TOGGLE_MARKDOWN_PREVIEW).includes(combo) ? false : undefined, ); - Mousetrap.bind(keysFor(GO_TO_YOUR_MERGE_REQUESTS), () => - findAndFollowLink('.dashboard-shortcuts-merge_requests'), - ); - Mousetrap.bind(keysFor(GO_TO_YOUR_REVIEW_REQUESTS), () => - findAndFollowLink('.dashboard-shortcuts-review_requests'), - ); - Mousetrap.bind(keysFor(GO_TO_YOUR_PROJECTS), () => - findAndFollowLink('.dashboard-shortcuts-projects'), - ); - Mousetrap.bind(keysFor(GO_TO_YOUR_GROUPS), () => - findAndFollowLink('.dashboard-shortcuts-groups'), - ); - Mousetrap.bind(keysFor(GO_TO_MILESTONE_LIST), () => - findAndFollowLink('.dashboard-shortcuts-milestones'), - ); - Mousetrap.bind(keysFor(GO_TO_YOUR_SNIPPETS), () => - findAndFollowLink('.dashboard-shortcuts-snippets'), - ); - - Mousetrap.bind(keysFor(TOGGLE_MARKDOWN_PREVIEW), Shortcuts.toggleMarkdownPreview); + const findFileURL = document.body.dataset.findFile; if (typeof findFileURL !== 'undefined' && findFileURL !== null) { - Mousetrap.bind(keysFor(GO_TO_PROJECT_FIND_FILE), () => { + this.bindCommand(GO_TO_PROJECT_FIND_FILE, () => { visitUrl(findFileURL); }); } - $(document).on('click.more_help', '.js-more-help-button', function clickMoreHelp(e) { - $(this).remove(); - e.preventDefault(); - }); - const shortcutsModalTriggerEvent = 'click.shortcutsModalTrigger'; // eslint-disable-next-line @gitlab/no-global-event-off $(document) @@ -135,6 +110,32 @@ export default class Shortcuts { } } + /** + * Bind the keyboard shortcut(s) defined by the given command to the given + * callback. + * + * @param {Object} command A command object. + * @param {Function} callback The callback to call when the command's key + * combo has been pressed. + * @returns {void} + */ + // eslint-disable-next-line class-methods-use-this + bindCommand(command, callback) { + Mousetrap.bind(keysFor(command), callback); + } + + /** + * Bind the keyboard shortcut(s) defined by the given commands to the given + * callbacks. + * + * @param {Array<[Object, Function]>} commandsAndCallbacks An array of + * command/callback pairs. + * @returns {void} + */ + bindCommands(commandsAndCallbacks) { + commandsAndCallbacks.forEach((commandAndCallback) => this.bindCommand(...commandAndCallback)); + } + onToggleHelp(e) { if (e?.preventDefault) { e.preventDefault(); diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts_blob.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts_blob.js index ab7fcbb35f1..65ae67d156f 100644 --- a/app/assets/javascripts/behaviors/shortcuts/shortcuts_blob.js +++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts_blob.js @@ -1,5 +1,4 @@ -import Mousetrap from 'mousetrap'; -import { keysFor, PROJECT_FILES_GO_TO_PERMALINK } from '~/behaviors/shortcuts/keybindings'; +import { PROJECT_FILES_GO_TO_PERMALINK } from '~/behaviors/shortcuts/keybindings'; import { getLocationHash, updateHistory, @@ -11,7 +10,6 @@ import { updateRefPortionOfTitle } from '~/repository/utils/title'; import Shortcuts from './shortcuts'; const defaults = { - skipResetBindings: false, fileBlobPermalinkUrl: null, fileBlobPermalinkUrlElement: null, }; @@ -24,12 +22,12 @@ function eventHasModifierKeys(event) { export default class ShortcutsBlob extends Shortcuts { constructor(opts) { const options = { ...defaults, ...opts }; - super(options.skipResetBindings); + super(); this.options = options; this.shortcircuitPermalinkButton(); - Mousetrap.bind(keysFor(PROJECT_FILES_GO_TO_PERMALINK), this.moveToFilePermalink.bind(this)); + this.bindCommand(PROJECT_FILES_GO_TO_PERMALINK, this.moveToFilePermalink.bind(this)); } moveToFilePermalink() { diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts_find_file.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts_find_file.js index 992e571e596..f26878cf161 100644 --- a/app/assets/javascripts/behaviors/shortcuts/shortcuts_find_file.js +++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts_find_file.js @@ -1,4 +1,3 @@ -import Mousetrap from 'mousetrap'; import { keysFor, PROJECT_FILES_MOVE_SELECTION_UP, @@ -6,15 +5,14 @@ import { PROJECT_FILES_OPEN_SELECTION, PROJECT_FILES_GO_BACK, } from '~/behaviors/shortcuts/keybindings'; +import { addStopCallback } from '~/lib/mousetrap'; import ShortcutsNavigation from './shortcuts_navigation'; export default class ShortcutsFindFile extends ShortcutsNavigation { constructor(projectFindFile) { super(); - const oldStopCallback = Mousetrap.prototype.stopCallback; - - Mousetrap.prototype.stopCallback = function customStopCallback(e, element, combo) { + addStopCallback((e, element, combo) => { if ( element === projectFindFile.inputElement[0] && (keysFor(PROJECT_FILES_MOVE_SELECTION_UP).includes(combo) || @@ -27,12 +25,14 @@ export default class ShortcutsFindFile extends ShortcutsNavigation { return false; } - return oldStopCallback.call(this, e, element, combo); - }; + return undefined; + }); - Mousetrap.bind(keysFor(PROJECT_FILES_MOVE_SELECTION_UP), projectFindFile.selectRowUp); - Mousetrap.bind(keysFor(PROJECT_FILES_MOVE_SELECTION_DOWN), projectFindFile.selectRowDown); - Mousetrap.bind(keysFor(PROJECT_FILES_GO_BACK), projectFindFile.goToTree); - Mousetrap.bind(keysFor(PROJECT_FILES_OPEN_SELECTION), projectFindFile.goToBlob); + this.bindCommands([ + [PROJECT_FILES_MOVE_SELECTION_UP, projectFindFile.selectRowUp], + [PROJECT_FILES_MOVE_SELECTION_DOWN, projectFindFile.selectRowDown], + [PROJECT_FILES_GO_BACK, projectFindFile.goToTree], + [PROJECT_FILES_OPEN_SELECTION, projectFindFile.goToBlob], + ]); } } diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts_issuable.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts_issuable.js index 64297da39cd..0c882ff9ea2 100644 --- a/app/assets/javascripts/behaviors/shortcuts/shortcuts_issuable.js +++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts_issuable.js @@ -1,6 +1,5 @@ import $ from 'jquery'; import ClipboardJS from 'clipboard'; -import Mousetrap from 'mousetrap'; import { getSelectedFragment } from '~/lib/utils/common_utils'; import { isElementVisible } from '~/lib/utils/dom_utils'; import { DEBOUNCE_DROPDOWN_DELAY } from '~/sidebar/components/labels/labels_select_widget/constants'; @@ -9,7 +8,6 @@ import { s__ } from '~/locale'; import Sidebar from '~/right_sidebar'; import { CopyAsGFM } from '../markdown/copy_as_gfm'; import { - keysFor, ISSUE_MR_CHANGE_ASSIGNEE, ISSUE_MR_CHANGE_MILESTONE, ISSUABLE_CHANGE_LABEL, @@ -32,18 +30,14 @@ export default class ShortcutsIssuable extends Shortcuts { toast(s__('GlobalShortcuts|Unable to copy the source branch name at this time.')); }); - Mousetrap.bind(keysFor(ISSUE_MR_CHANGE_ASSIGNEE), () => - ShortcutsIssuable.openSidebarDropdown('assignee'), - ); - Mousetrap.bind(keysFor(ISSUE_MR_CHANGE_MILESTONE), () => - ShortcutsIssuable.openSidebarDropdown('milestone'), - ); - Mousetrap.bind(keysFor(ISSUABLE_CHANGE_LABEL), () => - ShortcutsIssuable.openSidebarDropdown('labels'), - ); - Mousetrap.bind(keysFor(ISSUABLE_COMMENT_OR_REPLY), ShortcutsIssuable.replyWithSelectedText); - Mousetrap.bind(keysFor(ISSUABLE_EDIT_DESCRIPTION), ShortcutsIssuable.editIssue); - Mousetrap.bind(keysFor(MR_COPY_SOURCE_BRANCH_NAME), () => this.copyBranchName()); + this.bindCommands([ + [ISSUE_MR_CHANGE_ASSIGNEE, () => ShortcutsIssuable.openSidebarDropdown('assignee')], + [ISSUE_MR_CHANGE_MILESTONE, () => ShortcutsIssuable.openSidebarDropdown('milestone')], + [ISSUABLE_CHANGE_LABEL, () => ShortcutsIssuable.openSidebarDropdown('labels')], + [ISSUABLE_COMMENT_OR_REPLY, ShortcutsIssuable.replyWithSelectedText], + [ISSUABLE_EDIT_DESCRIPTION, ShortcutsIssuable.editIssue], + [MR_COPY_SOURCE_BRANCH_NAME, () => this.copyBranchName()], + ]); /** * We're attaching a global focus event listener on document for diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts_navigation.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts_navigation.js index 33a71c3a65b..bd08dc28f7a 100644 --- a/app/assets/javascripts/behaviors/shortcuts/shortcuts_navigation.js +++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts_navigation.js @@ -1,8 +1,6 @@ -import Mousetrap from 'mousetrap'; import { visitUrl, constructWebIDEPath } from '~/lib/utils/url_utility'; import findAndFollowLink from '~/lib/utils/navigation_utility'; import { - keysFor, GO_TO_PROJECT_OVERVIEW, GO_TO_PROJECT_ACTIVITY_FEED, GO_TO_PROJECT_RELEASES, @@ -28,40 +26,26 @@ export default class ShortcutsNavigation extends Shortcuts { constructor() { super(); - Mousetrap.bind(keysFor(GO_TO_PROJECT_OVERVIEW), () => findAndFollowLink('.shortcuts-project')); - Mousetrap.bind(keysFor(GO_TO_PROJECT_ACTIVITY_FEED), () => - findAndFollowLink('.shortcuts-project-activity'), - ); - Mousetrap.bind(keysFor(GO_TO_PROJECT_RELEASES), () => - findAndFollowLink('.shortcuts-deployments-releases'), - ); - Mousetrap.bind(keysFor(GO_TO_PROJECT_FILES), () => findAndFollowLink('.shortcuts-tree')); - Mousetrap.bind(keysFor(GO_TO_PROJECT_COMMITS), () => findAndFollowLink('.shortcuts-commits')); - Mousetrap.bind(keysFor(GO_TO_PROJECT_JOBS), () => findAndFollowLink('.shortcuts-builds')); - Mousetrap.bind(keysFor(GO_TO_PROJECT_REPO_GRAPH), () => - findAndFollowLink('.shortcuts-network'), - ); - Mousetrap.bind(keysFor(GO_TO_PROJECT_REPO_CHARTS), () => - findAndFollowLink('.shortcuts-repository-charts'), - ); - Mousetrap.bind(keysFor(GO_TO_PROJECT_ISSUES), () => findAndFollowLink('.shortcuts-issues')); - Mousetrap.bind(keysFor(GO_TO_PROJECT_ISSUE_BOARDS), () => - findAndFollowLink('.shortcuts-issue-boards'), - ); - Mousetrap.bind(keysFor(GO_TO_PROJECT_MERGE_REQUESTS), () => - findAndFollowLink('.shortcuts-merge_requests'), - ); - Mousetrap.bind(keysFor(GO_TO_PROJECT_WIKI), () => findAndFollowLink('.shortcuts-wiki')); - Mousetrap.bind(keysFor(GO_TO_PROJECT_SNIPPETS), () => findAndFollowLink('.shortcuts-snippets')); - Mousetrap.bind(keysFor(GO_TO_PROJECT_KUBERNETES), () => - findAndFollowLink('.shortcuts-kubernetes'), - ); - Mousetrap.bind(keysFor(GO_TO_PROJECT_ENVIRONMENTS), () => - findAndFollowLink('.shortcuts-environments'), - ); - Mousetrap.bind(keysFor(GO_TO_PROJECT_METRICS), () => findAndFollowLink('.shortcuts-metrics')); - Mousetrap.bind(keysFor(GO_TO_PROJECT_WEBIDE), ShortcutsNavigation.navigateToWebIDE); - Mousetrap.bind(keysFor(NEW_ISSUE), () => findAndFollowLink('.shortcuts-new-issue')); + this.bindCommands([ + [GO_TO_PROJECT_OVERVIEW, () => findAndFollowLink('.shortcuts-project')], + [GO_TO_PROJECT_ACTIVITY_FEED, () => findAndFollowLink('.shortcuts-project-activity')], + [GO_TO_PROJECT_RELEASES, () => findAndFollowLink('.shortcuts-deployments-releases')], + [GO_TO_PROJECT_FILES, () => findAndFollowLink('.shortcuts-tree')], + [GO_TO_PROJECT_COMMITS, () => findAndFollowLink('.shortcuts-commits')], + [GO_TO_PROJECT_JOBS, () => findAndFollowLink('.shortcuts-builds')], + [GO_TO_PROJECT_REPO_GRAPH, () => findAndFollowLink('.shortcuts-network')], + [GO_TO_PROJECT_REPO_CHARTS, () => findAndFollowLink('.shortcuts-repository-charts')], + [GO_TO_PROJECT_ISSUES, () => findAndFollowLink('.shortcuts-issues')], + [GO_TO_PROJECT_ISSUE_BOARDS, () => findAndFollowLink('.shortcuts-issue-boards')], + [GO_TO_PROJECT_MERGE_REQUESTS, () => findAndFollowLink('.shortcuts-merge_requests')], + [GO_TO_PROJECT_WIKI, () => findAndFollowLink('.shortcuts-wiki')], + [GO_TO_PROJECT_SNIPPETS, () => findAndFollowLink('.shortcuts-snippets')], + [GO_TO_PROJECT_KUBERNETES, () => findAndFollowLink('.shortcuts-kubernetes')], + [GO_TO_PROJECT_ENVIRONMENTS, () => findAndFollowLink('.shortcuts-environments')], + [GO_TO_PROJECT_METRICS, () => findAndFollowLink('.shortcuts-metrics')], + [GO_TO_PROJECT_WEBIDE, ShortcutsNavigation.navigateToWebIDE], + [NEW_ISSUE, () => findAndFollowLink('.shortcuts-new-issue')], + ]); } static navigateToWebIDE() { diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts_network.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts_network.js index c33c092b009..02c6af53fc2 100644 --- a/app/assets/javascripts/behaviors/shortcuts/shortcuts_network.js +++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts_network.js @@ -1,6 +1,4 @@ -import Mousetrap from 'mousetrap'; import { - keysFor, REPO_GRAPH_SCROLL_BOTTOM, REPO_GRAPH_SCROLL_DOWN, REPO_GRAPH_SCROLL_LEFT, @@ -14,11 +12,13 @@ export default class ShortcutsNetwork extends ShortcutsNavigation { constructor(graph) { super(); - Mousetrap.bind(keysFor(REPO_GRAPH_SCROLL_LEFT), graph.scrollLeft); - Mousetrap.bind(keysFor(REPO_GRAPH_SCROLL_RIGHT), graph.scrollRight); - Mousetrap.bind(keysFor(REPO_GRAPH_SCROLL_UP), graph.scrollUp); - Mousetrap.bind(keysFor(REPO_GRAPH_SCROLL_DOWN), graph.scrollDown); - Mousetrap.bind(keysFor(REPO_GRAPH_SCROLL_TOP), graph.scrollTop); - Mousetrap.bind(keysFor(REPO_GRAPH_SCROLL_BOTTOM), graph.scrollBottom); + this.bindCommands([ + [REPO_GRAPH_SCROLL_LEFT, graph.scrollLeft], + [REPO_GRAPH_SCROLL_RIGHT, graph.scrollRight], + [REPO_GRAPH_SCROLL_UP, graph.scrollUp], + [REPO_GRAPH_SCROLL_DOWN, graph.scrollDown], + [REPO_GRAPH_SCROLL_TOP, graph.scrollTop], + [REPO_GRAPH_SCROLL_BOTTOM, graph.scrollBottom], + ]); } } diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.js index 66aa1b752ae..3f3e0c51de5 100644 --- a/app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.js +++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.js @@ -1,4 +1,4 @@ -import Mousetrap from 'mousetrap'; +import { Mousetrap } from '~/lib/mousetrap'; import 'mousetrap/plugins/pause/mousetrap-pause'; const shorcutsDisabledKey = 'shortcutsDisabled'; diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts_wiki.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts_wiki.js index b2801f9118d..62d612cfa6d 100644 --- a/app/assets/javascripts/behaviors/shortcuts/shortcuts_wiki.js +++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts_wiki.js @@ -1,12 +1,12 @@ -import Mousetrap from 'mousetrap'; import findAndFollowLink from '~/lib/utils/navigation_utility'; -import { keysFor, EDIT_WIKI_PAGE } from './keybindings'; +import { EDIT_WIKI_PAGE } from './keybindings'; import ShortcutsNavigation from './shortcuts_navigation'; export default class ShortcutsWiki extends ShortcutsNavigation { constructor() { super(); - Mousetrap.bind(keysFor(EDIT_WIKI_PAGE), ShortcutsWiki.editWiki); + + this.bindCommand(EDIT_WIKI_PAGE, ShortcutsWiki.editWiki); } static editWiki() { diff --git a/app/assets/javascripts/ci/pipeline_new/components/refs_dropdown.vue b/app/assets/javascripts/ci/pipeline_new/components/refs_dropdown.vue index 9b57f135a40..429f8e78dbe 100644 --- a/app/assets/javascripts/ci/pipeline_new/components/refs_dropdown.vue +++ b/app/assets/javascripts/ci/pipeline_new/components/refs_dropdown.vue @@ -1,11 +1,10 @@ <script> import { __ } from '~/locale'; import RefSelector from '~/ref/components/ref_selector.vue'; -import { BRANCH_REF_TYPE, REF_TYPE_BRANCHES, REF_TYPE_TAGS } from '~/ref/constants'; +import { REF_TYPE_BRANCHES, REF_TYPE_TAGS } from '~/ref/constants'; import { formatToShortName } from '../utils/format_refs'; export default { - BRANCH_REF_TYPE, ENABLED_TYPE_REFS: [REF_TYPE_BRANCHES, REF_TYPE_TAGS], i18n: { /** @@ -49,7 +48,6 @@ export default { <ref-selector :value="refShortName" :enabled-ref-types="$options.ENABLED_TYPE_REFS" - :ref-type="$options.BRANCH_REF_TYPE" :project-id="projectId" :translations="$options.i18n" :use-symbolic-ref-names="true" diff --git a/app/assets/javascripts/ci/runner/admin_new_runner/admin_new_runner_app.vue b/app/assets/javascripts/ci/runner/admin_new_runner/admin_new_runner_app.vue index 43d0dae6e78..fbfd03d2716 100644 --- a/app/assets/javascripts/ci/runner/admin_new_runner/admin_new_runner_app.vue +++ b/app/assets/javascripts/ci/runner/admin_new_runner/admin_new_runner_app.vue @@ -1,9 +1,9 @@ <script> -import { GlSprintf, GlLink, GlModalDirective } from '@gitlab/ui'; import { createAlert, VARIANT_SUCCESS } from '~/alert'; import { redirectTo, setUrlParams } from '~/lib/utils/url_utility'; import { s__ } from '~/locale'; -import RunnerInstructionsModal from '~/vue_shared/components/runner_instructions/runner_instructions_modal.vue'; + +import RegistrationCompatibilityAlert from '~/ci/runner/components/registration/registration_compatibility_alert.vue'; import RunnerPlatformsRadioGroup from '~/ci/runner/components/runner_platforms_radio_group.vue'; import RunnerCreateForm from '~/ci/runner/components/runner_create_form.vue'; import { DEFAULT_PLATFORM, PARAM_KEY_PLATFORM, INSTANCE_TYPE } from '../constants'; @@ -12,21 +12,10 @@ import { saveAlertToLocalStorage } from '../local_storage_alert/save_alert_to_lo export default { name: 'AdminNewRunnerApp', components: { - GlLink, - GlSprintf, - RunnerInstructionsModal, + RegistrationCompatibilityAlert, RunnerPlatformsRadioGroup, RunnerCreateForm, }, - directives: { - GlModal: GlModalDirective, - }, - props: { - legacyRegistrationToken: { - type: String, - required: true, - }, - }, data() { return { platform: DEFAULT_PLATFORM, @@ -47,7 +36,6 @@ export default { createAlert({ message: error.message }); }, }, - modalId: 'runners-legacy-registration-instructions-modal', INSTANCE_TYPE, }; </script> @@ -55,24 +43,15 @@ export default { <template> <div> <h1 class="gl-font-size-h2">{{ s__('Runners|New instance runner') }}</h1> + + <registration-compatibility-alert /> + <p> - <gl-sprintf - :message=" - s__( - 'Runners|Create an instance runner to generate a command that registers the runner with all its configurations. %{linkStart}Prefer to use a registration token to create a runner?%{linkEnd}', - ) - " - > - <template #link="{ content }"> - <gl-link v-gl-modal="$options.modalId" data-testid="legacy-instructions-link">{{ - content - }}</gl-link> - <runner-instructions-modal - :modal-id="$options.modalId" - :registration-token="legacyRegistrationToken" - /> - </template> - </gl-sprintf> + {{ + s__( + 'Runners|Create an instance runner to generate a command that registers the runner with all its configurations.', + ) + }} </p> <hr aria-hidden="true" /> diff --git a/app/assets/javascripts/ci/runner/admin_new_runner/index.js b/app/assets/javascripts/ci/runner/admin_new_runner/index.js index 502d9d33b4d..434c1197f71 100644 --- a/app/assets/javascripts/ci/runner/admin_new_runner/index.js +++ b/app/assets/javascripts/ci/runner/admin_new_runner/index.js @@ -12,8 +12,6 @@ export const initAdminNewRunner = (selector = '#js-admin-new-runner') => { return null; } - const { legacyRegistrationToken } = el.dataset; - const apolloProvider = new VueApollo({ defaultClient: createDefaultClient(), }); @@ -22,11 +20,7 @@ export const initAdminNewRunner = (selector = '#js-admin-new-runner') => { el, apolloProvider, render(h) { - return h(AdminNewRunnerApp, { - props: { - legacyRegistrationToken, - }, - }); + return h(AdminNewRunnerApp); }, }); }; diff --git a/app/assets/javascripts/ci/runner/admin_runners/admin_runners_app.vue b/app/assets/javascripts/ci/runner/admin_runners/admin_runners_app.vue index d452adb34d9..24225acfd08 100644 --- a/app/assets/javascripts/ci/runner/admin_runners/admin_runners_app.vue +++ b/app/assets/javascripts/ci/runner/admin_runners/admin_runners_app.vue @@ -193,16 +193,17 @@ export default { nav-class="gl-border-none!" /> - <gl-button v-if="shouldShowCreateRunnerWorkflow" :href="newRunnerPath" variant="confirm"> - {{ s__('Runners|New instance runner') }} - </gl-button> - <registration-dropdown - v-else - class="gl-w-full gl-sm-w-auto gl-mr-auto" - :registration-token="registrationToken" - :type="$options.INSTANCE_TYPE" - right - /> + <div class="gl-w-full gl-md-w-auto gl-display-flex"> + <gl-button v-if="shouldShowCreateRunnerWorkflow" :href="newRunnerPath" variant="confirm"> + {{ s__('Runners|New instance runner') }} + </gl-button> + <registration-dropdown + class="gl-ml-3" + :registration-token="registrationToken" + :type="$options.INSTANCE_TYPE" + right + /> + </div> </div> <runner-filtered-search-bar diff --git a/app/assets/javascripts/ci/runner/components/registration/registration_compatibility_alert.vue b/app/assets/javascripts/ci/runner/components/registration/registration_compatibility_alert.vue new file mode 100644 index 00000000000..0b6716c5082 --- /dev/null +++ b/app/assets/javascripts/ci/runner/components/registration/registration_compatibility_alert.vue @@ -0,0 +1,33 @@ +<script> +import { GlAlert, GlLink, GlSprintf } from '@gitlab/ui'; +import { s__ } from '~/locale'; +import { CHANGELOG_URL } from '../../constants'; + +export default { + name: 'RegistrationCompatibilityAlert', + components: { + GlAlert, + GlLink, + GlSprintf, + }, + CHANGELOG_URL, + i18n: { + title: s__( + 'Runners|This registration process is only supported in GitLab Runner 15.10 or later', + ), + message: s__( + 'Runners|This registration process is not supported in GitLab Runner 15.9 or earlier and only available as an experimental feature in GitLab Runner 15.10 and 15.11. You should upgrade to %{linkStart}GitLab Runner 16.0%{linkEnd} or later to use a stable version of this registration process.', + ), + }, +}; +</script> + +<template> + <gl-alert class="gl-mb-4" variant="warning" :dismissible="false" :title="$options.i18n.title"> + <gl-sprintf :message="$options.i18n.message"> + <template #link="{ content }"> + <gl-link :href="$options.CHANGELOG_URL" target="_blank">{{ content }}</gl-link> + </template> + </gl-sprintf> + </gl-alert> +</template> diff --git a/app/assets/javascripts/ci/runner/components/registration/registration_dropdown.vue b/app/assets/javascripts/ci/runner/components/registration/registration_dropdown.vue index 212ad5fa5a0..c1e862f6fa8 100644 --- a/app/assets/javascripts/ci/runner/components/registration/registration_dropdown.vue +++ b/app/assets/javascripts/ci/runner/components/registration/registration_dropdown.vue @@ -1,6 +1,7 @@ <script> -import { GlDropdown, GlDropdownForm, GlDropdownItem, GlDropdownDivider } from '@gitlab/ui'; +import { GlDropdown, GlDropdownForm, GlDropdownItem, GlDropdownDivider, GlIcon } from '@gitlab/ui'; import { s__ } from '~/locale'; +import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import RunnerInstructionsModal from '~/vue_shared/components/runner_instructions/runner_instructions_modal.vue'; import { INSTANCE_TYPE, GROUP_TYPE, PROJECT_TYPE } from '../../constants'; import RegistrationToken from './registration_token.vue'; @@ -17,10 +18,12 @@ export default { GlDropdownForm, GlDropdownItem, GlDropdownDivider, + GlIcon, RegistrationToken, RunnerInstructionsModal, RegistrationTokenResetDropdownItem, }, + mixins: [glFeatureFlagMixin()], props: { registrationToken: { type: String, @@ -40,7 +43,18 @@ export default { }; }, computed: { + isDeprecated() { + // Show a compact version when used as secondary option + // create_runner_workflow_for_admin or create_runner_workflow_for_namespace + return ( + this.glFeatures?.createRunnerWorkflowForAdmin || + this.glFeatures?.createRunnerWorkflowForNamespace + ); + }, dropdownText() { + if (this.isDeprecated) { + return ''; + } switch (this.type) { case INSTANCE_TYPE: return s__('Runners|Register an instance runner'); @@ -52,6 +66,24 @@ export default { return s__('Runners|Register a runner'); } }, + dropdownToggleClass() { + if (this.isDeprecated) { + return ['gl-px-3!']; + } + return []; + }, + dropdownCategory() { + if (this.isDeprecated) { + return 'tertiary'; + } + return 'primary'; + }, + dropdownVariant() { + if (this.isDeprecated) { + return 'default'; + } + return 'confirm'; + }, }, methods: { onShowInstructionsClick() { @@ -71,9 +103,25 @@ export default { ref="runnerRegistrationDropdown" menu-class="gl-w-auto!" :text="dropdownText" - variant="confirm" + :toggle-class="dropdownToggleClass" + :variant="dropdownVariant" + :category="dropdownCategory" v-bind="$attrs" > + <template v-if="isDeprecated" #button-content> + <gl-icon name="ellipsis_v" /> + </template> + <gl-dropdown-form class="gl-p-4!"> + <registration-token input-id="token-value" :value="currentRegistrationToken"> + <template v-if="isDeprecated" #label-description> + <gl-icon name="warning" class="gl-text-orange-500" /> + <span class="gl-text-secondary"> + {{ s__('Runners|Support for registration tokens is deprecated') }} + </span> + </template> + </registration-token> + </gl-dropdown-form> + <gl-dropdown-divider /> <gl-dropdown-item @click.capture.native.stop="onShowInstructionsClick"> {{ $options.i18n.showInstallationInstructions }} <runner-instructions-modal @@ -83,10 +131,6 @@ export default { /> </gl-dropdown-item> <gl-dropdown-divider /> - <gl-dropdown-form class="gl-p-4!"> - <registration-token input-id="token-value" :value="currentRegistrationToken" /> - </gl-dropdown-form> - <gl-dropdown-divider /> <registration-token-reset-dropdown-item :type="type" @tokenReset="onTokenReset" /> </gl-dropdown> </template> diff --git a/app/assets/javascripts/ci/runner/components/registration/registration_token.vue b/app/assets/javascripts/ci/runner/components/registration/registration_token.vue index 6b4e6a929b7..b196bccf66f 100644 --- a/app/assets/javascripts/ci/runner/components/registration/registration_token.vue +++ b/app/assets/javascripts/ci/runner/components/registration/registration_token.vue @@ -45,5 +45,9 @@ export default { :copy-button-title="$options.I18N_COPY_BUTTON_TITLE" :form-input-group-props="formInputGroupProps" @copy="onCopy" - /> + > + <template v-for="slot in Object.keys($scopedSlots)" #[slot]> + <slot :name="slot"></slot> + </template> + </input-copy-toggle-visibility> </template> diff --git a/app/assets/javascripts/ci/runner/constants.js b/app/assets/javascripts/ci/runner/constants.js index 1cae9df713b..84b2ed010e6 100644 --- a/app/assets/javascripts/ci/runner/constants.js +++ b/app/assets/javascripts/ci/runner/constants.js @@ -248,5 +248,6 @@ export const INSTALL_HELP_URL = 'https://docs.gitlab.com/runner/install'; export const EXECUTORS_HELP_URL = 'https://docs.gitlab.com/runner/executors/'; export const SERVICE_COMMANDS_HELP_URL = 'https://docs.gitlab.com/runner/commands/#service-related-commands'; +export const CHANGELOG_URL = 'https://gitlab.com/gitlab-org/gitlab-runner/blob/main/CHANGELOG.md'; export const DOCKER_HELP_URL = 'https://docs.gitlab.com/runner/install/docker.html'; export const KUBERNETES_HELP_URL = 'https://docs.gitlab.com/runner/install/kubernetes.html'; diff --git a/app/assets/javascripts/ci/runner/group_new_runner/group_new_runner_app.vue b/app/assets/javascripts/ci/runner/group_new_runner/group_new_runner_app.vue index 35c75a917c7..ea702cd770a 100644 --- a/app/assets/javascripts/ci/runner/group_new_runner/group_new_runner_app.vue +++ b/app/assets/javascripts/ci/runner/group_new_runner/group_new_runner_app.vue @@ -1,9 +1,9 @@ <script> -import { GlSprintf, GlLink, GlModalDirective } from '@gitlab/ui'; import { createAlert, VARIANT_SUCCESS } from '~/alert'; import { redirectTo, setUrlParams } from '~/lib/utils/url_utility'; import { s__ } from '~/locale'; -import RunnerInstructionsModal from '~/vue_shared/components/runner_instructions/runner_instructions_modal.vue'; + +import RegistrationCompatibilityAlert from '~/ci/runner/components/registration/registration_compatibility_alert.vue'; import RunnerPlatformsRadioGroup from '~/ci/runner/components/runner_platforms_radio_group.vue'; import RunnerCreateForm from '~/ci/runner/components/runner_create_form.vue'; import { DEFAULT_PLATFORM, GROUP_TYPE, PARAM_KEY_PLATFORM } from '../constants'; @@ -12,24 +12,15 @@ import { saveAlertToLocalStorage } from '../local_storage_alert/save_alert_to_lo export default { name: 'GroupNewRunnerApp', components: { - GlLink, - GlSprintf, - RunnerInstructionsModal, + RegistrationCompatibilityAlert, RunnerPlatformsRadioGroup, RunnerCreateForm, }, - directives: { - GlModal: GlModalDirective, - }, props: { groupId: { type: String, required: true, }, - legacyRegistrationToken: { - type: String, - required: true, - }, }, data() { return { @@ -51,7 +42,6 @@ export default { createAlert({ message: error.message }); }, }, - modalId: 'runners-legacy-registration-instructions-modal', GROUP_TYPE, }; </script> @@ -59,24 +49,15 @@ export default { <template> <div> <h1 class="gl-font-size-h2">{{ s__('Runners|New group runner') }}</h1> + + <registration-compatibility-alert /> + <p> - <gl-sprintf - :message=" - s__( - 'Runners|Create a group runner to generate a command that registers the runner with all its configurations. %{linkStart}Prefer to use a registration token to create a runner?%{linkEnd}', - ) - " - > - <template #link="{ content }"> - <gl-link v-gl-modal="$options.modalId" data-testid="legacy-instructions-link">{{ - content - }}</gl-link> - <runner-instructions-modal - :modal-id="$options.modalId" - :registration-token="legacyRegistrationToken" - /> - </template> - </gl-sprintf> + {{ + s__( + 'Runners|Create a group runner to generate a command that registers the runner with all its configurations.', + ) + }} </p> <hr aria-hidden="true" /> diff --git a/app/assets/javascripts/ci/runner/group_new_runner/index.js b/app/assets/javascripts/ci/runner/group_new_runner/index.js index b314c3aa1e7..9e056081e03 100644 --- a/app/assets/javascripts/ci/runner/group_new_runner/index.js +++ b/app/assets/javascripts/ci/runner/group_new_runner/index.js @@ -12,7 +12,7 @@ export const initGroupNewRunner = (selector = '#js-group-new-runner') => { return null; } - const { legacyRegistrationToken, groupId } = el.dataset; + const { groupId } = el.dataset; const apolloProvider = new VueApollo({ defaultClient: createDefaultClient(), @@ -25,7 +25,6 @@ export const initGroupNewRunner = (selector = '#js-group-new-runner') => { return h(GroupNewRunnerApp, { props: { groupId, - legacyRegistrationToken, }, }); }, diff --git a/app/assets/javascripts/ci/runner/group_runners/group_runners_app.vue b/app/assets/javascripts/ci/runner/group_runners/group_runners_app.vue index f8386214698..9f3e6f247d7 100644 --- a/app/assets/javascripts/ci/runner/group_runners/group_runners_app.vue +++ b/app/assets/javascripts/ci/runner/group_runners/group_runners_app.vue @@ -217,7 +217,9 @@ export default { <template> <div> - <div class="gl-display-flex gl-align-items-center"> + <div + class="gl-display-flex gl-align-items-center gl-flex-direction-column-reverse gl-md-flex-direction-row gl-mt-3 gl-md-mt-0" + > <runner-type-tabs ref="runner-type-tabs" v-model="search" @@ -229,20 +231,23 @@ export default { nav-class="gl-border-none!" /> - <template v-if="shouldShowCreateRunnerWorkflow"> - <gl-button v-if="newRunnerPath" :href="newRunnerPath" variant="confirm"> + <div class="gl-w-full gl-md-w-auto gl-display-flex"> + <gl-button + v-if="shouldShowCreateRunnerWorkflow && newRunnerPath" + :href="newRunnerPath" + variant="confirm" + > {{ s__('Runners|New group runner') }} </gl-button> - </template> - <registration-dropdown - v-else-if="registrationToken" - class="gl-ml-auto" - :registration-token="registrationToken" - :type="$options.GROUP_TYPE" - right - /> + <registration-dropdown + v-if="registrationToken" + class="gl-ml-3" + :registration-token="registrationToken" + :type="$options.GROUP_TYPE" + right + /> + </div> </div> - <div class="gl-display-flex gl-flex-direction-column gl-md-flex-direction-row gl-gap-3" :class="$options.FILTER_CSS_CLASSES" diff --git a/app/assets/javascripts/ci/runner/project_new_runner/index.js b/app/assets/javascripts/ci/runner/project_new_runner/index.js index 5236f28752a..44f1a0ffdab 100644 --- a/app/assets/javascripts/ci/runner/project_new_runner/index.js +++ b/app/assets/javascripts/ci/runner/project_new_runner/index.js @@ -12,7 +12,7 @@ export const initProjectNewRunner = (selector = '#js-project-new-runner') => { return null; } - const { legacyRegistrationToken, projectId } = el.dataset; + const { projectId } = el.dataset; const apolloProvider = new VueApollo({ defaultClient: createDefaultClient(), @@ -25,7 +25,6 @@ export const initProjectNewRunner = (selector = '#js-project-new-runner') => { return h(ProjectNewRunnerApp, { props: { projectId, - legacyRegistrationToken, }, }); }, diff --git a/app/assets/javascripts/ci/runner/project_new_runner/project_new_runner_app.vue b/app/assets/javascripts/ci/runner/project_new_runner/project_new_runner_app.vue index 94d3e949e86..abc2eca38f4 100644 --- a/app/assets/javascripts/ci/runner/project_new_runner/project_new_runner_app.vue +++ b/app/assets/javascripts/ci/runner/project_new_runner/project_new_runner_app.vue @@ -1,8 +1,6 @@ <script> -import { GlSprintf, GlLink, GlModalDirective } from '@gitlab/ui'; import { createAlert, VARIANT_SUCCESS } from '~/alert'; import { s__ } from '~/locale'; -import RunnerInstructionsModal from '~/vue_shared/components/runner_instructions/runner_instructions_modal.vue'; import RunnerPlatformsRadioGroup from '~/ci/runner/components/runner_platforms_radio_group.vue'; import RunnerCreateForm from '~/ci/runner/components/runner_create_form.vue'; import { DEFAULT_PLATFORM, PROJECT_TYPE } from '../constants'; @@ -10,24 +8,14 @@ import { DEFAULT_PLATFORM, PROJECT_TYPE } from '../constants'; export default { name: 'ProjectNewRunnerApp', components: { - GlLink, - GlSprintf, - RunnerInstructionsModal, RunnerPlatformsRadioGroup, RunnerCreateForm, }, - directives: { - GlModal: GlModalDirective, - }, props: { projectId: { type: String, required: true, }, - legacyRegistrationToken: { - type: String, - required: true, - }, }, data() { return { @@ -45,7 +33,6 @@ export default { createAlert({ message: error.message }); }, }, - modalId: 'runners-legacy-registration-instructions-modal', PROJECT_TYPE, }; </script> @@ -54,23 +41,11 @@ export default { <div> <h1 class="gl-font-size-h2">{{ s__('Runners|New project runner') }}</h1> <p> - <gl-sprintf - :message=" - s__( - 'Runners|Create a project runner to generate a command that registers the runner with all its configurations. %{linkStart}Prefer to use a registration token to create a runner?%{linkEnd}', - ) - " - > - <template #link="{ content }"> - <gl-link v-gl-modal="$options.modalId" data-testid="legacy-instructions-link">{{ - content - }}</gl-link> - <runner-instructions-modal - :modal-id="$options.modalId" - :registration-token="legacyRegistrationToken" - /> - </template> - </gl-sprintf> + {{ + s__( + 'Runners|Create a project runner to generate a command that registers the runner with all its configurations.', + ) + }} </p> <hr aria-hidden="true" /> diff --git a/app/assets/javascripts/design_management/components/toolbar/design_navigation.vue b/app/assets/javascripts/design_management/components/toolbar/design_navigation.vue index 0bbbc795fff..e08eb853ad7 100644 --- a/app/assets/javascripts/design_management/components/toolbar/design_navigation.vue +++ b/app/assets/javascripts/design_management/components/toolbar/design_navigation.vue @@ -1,12 +1,11 @@ <script> -/* global Mousetrap */ -import 'mousetrap'; import { GlButton, GlButtonGroup, GlTooltipDirective } from '@gitlab/ui'; import { keysFor, ISSUE_PREVIOUS_DESIGN, ISSUE_NEXT_DESIGN, } from '~/behaviors/shortcuts/keybindings'; +import { Mousetrap } from '~/lib/mousetrap'; import { s__, sprintf } from '~/locale'; import allDesignsMixin from '../../mixins/all_designs'; import { DESIGN_ROUTE_NAME } from '../../router/constants'; diff --git a/app/assets/javascripts/design_management/pages/design/index.vue b/app/assets/javascripts/design_management/pages/design/index.vue index 2f2b2ed1a90..eeb36e59b89 100644 --- a/app/assets/javascripts/design_management/pages/design/index.vue +++ b/app/assets/javascripts/design_management/pages/design/index.vue @@ -1,7 +1,7 @@ <script> import { GlAlert } from '@gitlab/ui'; import { isNull } from 'lodash'; -import Mousetrap from 'mousetrap'; +import { Mousetrap } from '~/lib/mousetrap'; import { keysFor, ISSUE_CLOSE_DESIGN } from '~/behaviors/shortcuts/keybindings'; import { createAlert } from '~/alert'; import { fetchPolicies } from '~/lib/graphql'; diff --git a/app/assets/javascripts/diffs/components/app.vue b/app/assets/javascripts/diffs/components/app.vue index 9b3db78724d..dff95bde269 100644 --- a/app/assets/javascripts/diffs/components/app.vue +++ b/app/assets/javascripts/diffs/components/app.vue @@ -1,7 +1,6 @@ <script> import { GlLoadingIcon, GlPagination, GlSprintf, GlAlert } from '@gitlab/ui'; import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils'; -import Mousetrap from 'mousetrap'; import { mapState, mapGetters, mapActions } from 'vuex'; import api from '~/api'; import { @@ -15,6 +14,7 @@ import { createAlert } from '~/alert'; import { isSingleViewStyle } from '~/helpers/diffs_helper'; import { helpPagePath } from '~/helpers/help_page_helper'; import { parseBoolean } from '~/lib/utils/common_utils'; +import { Mousetrap } from '~/lib/mousetrap'; import { updateHistory } from '~/lib/utils/url_utility'; import { __ } from '~/locale'; import PanelResizer from '~/vue_shared/components/panel_resizer.vue'; diff --git a/app/assets/javascripts/docs/docs_bundle.js b/app/assets/javascripts/docs/docs_bundle.js index 897439f56b0..32aa4a22cba 100644 --- a/app/assets/javascripts/docs/docs_bundle.js +++ b/app/assets/javascripts/docs/docs_bundle.js @@ -1,4 +1,4 @@ -import Mousetrap from 'mousetrap'; +import { Mousetrap } from '~/lib/mousetrap'; function addMousetrapClick(el, key) { el.addEventListener('click', () => Mousetrap.trigger(key)); diff --git a/app/assets/javascripts/editor/schema/ci.json b/app/assets/javascripts/editor/schema/ci.json index 44944a4a205..70f1dddcac9 100644 --- a/app/assets/javascripts/editor/schema/ci.json +++ b/app/assets/javascripts/editor/schema/ci.json @@ -360,6 +360,9 @@ }, "rules": { "$ref": "#/definitions/rules" + }, + "inputs": { + "$ref": "#/definitions/inputs" } }, "required": [ @@ -395,6 +398,9 @@ } } ] + }, + "inputs": { + "$ref": "#/definitions/inputs" } }, "required": [ @@ -411,6 +417,9 @@ "type": "string", "format": "uri-reference", "pattern": "\\.ya?ml$" + }, + "inputs": { + "$ref": "#/definitions/inputs" } }, "required": [ @@ -425,6 +434,9 @@ "description": "Local path to component directory or full path to external component directory.", "type": "string", "format": "uri-reference" + }, + "inputs": { + "$ref": "#/definitions/inputs" } }, "required": [ @@ -440,6 +452,9 @@ "type": "string", "format": "uri-reference", "pattern": "^https?://.+\\.ya?ml$" + }, + "inputs": { + "$ref": "#/definitions/inputs" } }, "required": [ @@ -1252,6 +1267,10 @@ "markdownDescription": "Interruptible is used to indicate that a job should be canceled if made redundant by a newer pipeline run. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#interruptible).", "default": false }, + "inputs": { + "markdownDescription": "Used to pass input values to included templates or components. [Learn More](https://docs.gitlab.com/ee/ci/yaml/includes.html#set-input-parameter-values-with-includeinputs).", + "type": "object" + }, "job": { "allOf": [ { diff --git a/app/assets/javascripts/jobs/components/job/sidebar/stages_dropdown.vue b/app/assets/javascripts/jobs/components/job/sidebar/stages_dropdown.vue index e3afe9b7c67..28a17abb20b 100644 --- a/app/assets/javascripts/jobs/components/job/sidebar/stages_dropdown.vue +++ b/app/assets/javascripts/jobs/components/job/sidebar/stages_dropdown.vue @@ -1,7 +1,7 @@ <script> import { GlLink, GlDropdown, GlDropdownItem, GlSprintf } from '@gitlab/ui'; import { isEmpty } from 'lodash'; -import Mousetrap from 'mousetrap'; +import { Mousetrap } from '~/lib/mousetrap'; import { s__ } from '~/locale'; import CiIcon from '~/vue_shared/components/ci_icon.vue'; import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; diff --git a/app/assets/javascripts/lib/mousetrap.js b/app/assets/javascripts/lib/mousetrap.js new file mode 100644 index 00000000000..ef3f54ec314 --- /dev/null +++ b/app/assets/javascripts/lib/mousetrap.js @@ -0,0 +1,59 @@ +// This is the only file allowed to import directly from the package. +// eslint-disable-next-line no-restricted-imports +import Mousetrap from 'mousetrap'; + +const additionalStopCallbacks = []; +const originalStopCallback = Mousetrap.prototype.stopCallback; + +Mousetrap.prototype.stopCallback = function customStopCallback(e, element, combo) { + for (const callback of additionalStopCallbacks) { + const returnValue = callback.call(this, e, element, combo); + if (returnValue !== undefined) return returnValue; + } + + return originalStopCallback.call(this, e, element, combo); +}; + +/** + * Add a stop callback to Mousetrap. + * + * This allows overriding the default behaviour of Mousetrap#stopCallback, + * which is to stop the bound key handler/callback from being called if the key + * combo is pressed inside form fields (input, select, textareas, etc). See + * https://craig.is/killing/mice#api.stopCallback. + * + * The stopCallback registered here has the same signature as + * Mousetrap#stopCallback, with the one difference being that the callback + * should return `undefined` if it has no opinion on whether the current key + * combo should be stopped or not, and the next stop callback should be + * consulted instead. If a boolean is returned, no other stop callbacks are + * called. + * + * Note: This approach does not always work as expected when coupled with + * Mousetrap's pause plugin, which is used for enabling/disabling all keyboard + * shortcuts. That plugin assumes it's the first to execute and overwrite + * Mousetrap's `stopCallback` method, whereas to work correctly with this, it + * must execute last. This is not guaranteed or even attempted. + * + * To work correctly, we may need to reimplement the pause plugin here. + * + * @param {(e: Event, element: Element, combo: string) => boolean|undefined} + * stopCallback The additional stop callback function to add to the chain + * of stop callbacks. + * @returns {void} + */ +export const addStopCallback = (stopCallback) => { + // Unshift, since we want to iterate through them in reverse order, so that + // the most recently added handler is called first, and the original + // stopCallback method is called last. + additionalStopCallbacks.unshift(stopCallback); +}; + +/** + * Clear additionalStopCallbacks. Used only for tests. + */ +export const clearStopCallbacksForTests = () => { + additionalStopCallbacks.length = 0; +}; + +export { Mousetrap }; diff --git a/app/assets/javascripts/monitoring/components/dashboard.vue b/app/assets/javascripts/monitoring/components/dashboard.vue index ab2b713ac9f..100ef11409f 100644 --- a/app/assets/javascripts/monitoring/components/dashboard.vue +++ b/app/assets/javascripts/monitoring/components/dashboard.vue @@ -8,12 +8,12 @@ import { GlSprintf, GlLink, } from '@gitlab/ui'; -import Mousetrap from 'mousetrap'; import VueDraggable from 'vuedraggable'; import { mapActions, mapState, mapGetters } from 'vuex'; import { createAlert } from '~/alert'; import invalidUrl from '~/lib/utils/invalid_url'; import { ESC_KEY } from '~/lib/utils/keys'; +import { Mousetrap } from '~/lib/mousetrap'; import { mergeUrlParams, updateHistory } from '~/lib/utils/url_utility'; import { s__ } from '~/locale'; import { defaultTimeRange } from '~/vue_shared/constants'; diff --git a/app/assets/javascripts/notes/components/discussion_navigator.vue b/app/assets/javascripts/notes/components/discussion_navigator.vue index 03bdc7a2cc6..faef8595998 100644 --- a/app/assets/javascripts/notes/components/discussion_navigator.vue +++ b/app/assets/javascripts/notes/components/discussion_navigator.vue @@ -1,12 +1,11 @@ <script> -/* global Mousetrap */ -import 'mousetrap'; import { throttle } from 'lodash'; import { keysFor, MR_NEXT_UNRESOLVED_DISCUSSION, MR_PREVIOUS_UNRESOLVED_DISCUSSION, } from '~/behaviors/shortcuts/keybindings'; +import { Mousetrap } from '~/lib/mousetrap'; import eventHub from '~/notes/event_hub'; import discussionNavigation from '~/notes/mixins/discussion_navigation'; diff --git a/app/assets/javascripts/pages/projects/init_blob.js b/app/assets/javascripts/pages/projects/init_blob.js index 097b2f33aa9..244d1d5590e 100644 --- a/app/assets/javascripts/pages/projects/init_blob.js +++ b/app/assets/javascripts/pages/projects/init_blob.js @@ -22,7 +22,6 @@ export default () => { // eslint-disable-next-line no-new new ShortcutsBlob({ - skipResetBindings: true, fileBlobPermalinkUrl, fileBlobPermalinkUrlElement, }); diff --git a/app/assets/javascripts/projects/commits/index.js b/app/assets/javascripts/projects/commits/index.js index 3179fcb14fd..1a5681adb04 100644 --- a/app/assets/javascripts/projects/commits/index.js +++ b/app/assets/javascripts/projects/commits/index.js @@ -48,7 +48,6 @@ export const initCommitsRefSwitcher = () => { projectId, value: useSymbolicRefNames ? `refs/${refType}/${ref}` : ref, useSymbolicRefNames, - refType, }, on: { input(selected) { diff --git a/app/assets/javascripts/ref/components/ref_selector.vue b/app/assets/javascripts/ref/components/ref_selector.vue index 9a84726d42f..7f58b394547 100644 --- a/app/assets/javascripts/ref/components/ref_selector.vue +++ b/app/assets/javascripts/ref/components/ref_selector.vue @@ -47,11 +47,6 @@ export default { required: false, default: () => {}, }, - refType: { - type: String, - required: false, - default: null, - }, projectId: { type: String, required: true, diff --git a/app/assets/javascripts/repository/components/blob_controls.vue b/app/assets/javascripts/repository/components/blob_controls.vue index d3e306619bf..460db0fe2ae 100644 --- a/app/assets/javascripts/repository/components/blob_controls.vue +++ b/app/assets/javascripts/repository/components/blob_controls.vue @@ -101,7 +101,6 @@ export default { fileBlobPermalinkUrlElement && fileBlobPermalinkUrlElement.getAttribute('href'); // eslint-disable-next-line no-new new ShortcutsBlob({ - skipResetBindings: true, fileBlobPermalinkUrl, fileBlobPermalinkUrlElement, }); diff --git a/app/assets/javascripts/super_sidebar/components/super_sidebar.vue b/app/assets/javascripts/super_sidebar/components/super_sidebar.vue index 4f312c72de5..050b05a6324 100644 --- a/app/assets/javascripts/super_sidebar/components/super_sidebar.vue +++ b/app/assets/javascripts/super_sidebar/components/super_sidebar.vue @@ -1,6 +1,6 @@ <script> import { GlButton } from '@gitlab/ui'; -import Mousetrap from 'mousetrap'; +import { Mousetrap } from '~/lib/mousetrap'; import { keysFor, TOGGLE_SUPER_SIDEBAR } from '~/behaviors/shortcuts/keybindings'; import { __ } from '~/locale'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; diff --git a/app/assets/javascripts/vue_shared/components/file_finder/index.vue b/app/assets/javascripts/vue_shared/components/file_finder/index.vue index 5c892377f40..18f9d26a13d 100644 --- a/app/assets/javascripts/vue_shared/components/file_finder/index.vue +++ b/app/assets/javascripts/vue_shared/components/file_finder/index.vue @@ -1,8 +1,8 @@ <script> import { GlIcon, GlLoadingIcon } from '@gitlab/ui'; import fuzzaldrinPlus from 'fuzzaldrin-plus'; -import Mousetrap from 'mousetrap'; import VirtualList from 'vue-virtual-scroll-list'; +import { Mousetrap, addStopCallback } from '~/lib/mousetrap'; import { keysFor, MR_GO_TO_FILE } from '~/behaviors/shortcuts/keybindings'; import { UP_KEY_CODE, DOWN_KEY_CODE, ENTER_KEY_CODE, ESC_KEY_CODE } from '~/lib/utils/keycodes'; import Item from './item.vue'; @@ -10,8 +10,6 @@ import Item from './item.vue'; export const MAX_FILE_FINDER_RESULTS = 40; export const FILE_FINDER_ROW_HEIGHT = 55; -const originalStopCallback = Mousetrap.prototype.stopCallback; - export default { components: { GlIcon, @@ -140,7 +138,7 @@ export default { this.toggle(!this.visible); }); - Mousetrap.prototype.stopCallback = function customStopCallback(e, el, combo) { + addStopCallback(function fileFinderStopCallback(e, el, combo) { if ( (combo === 't' && el.classList.contains('dropdown-input-field')) || el.classList.contains('inputarea') @@ -150,8 +148,8 @@ export default { return false; } - return originalStopCallback.call(this, e, el, combo); - }; + return undefined; + }); }, methods: { toggle(visible) { diff --git a/app/assets/javascripts/work_items/components/work_item_detail.vue b/app/assets/javascripts/work_items/components/work_item_detail.vue index 155e983cbf6..c942278ba00 100644 --- a/app/assets/javascripts/work_items/components/work_item_detail.vue +++ b/app/assets/javascripts/work_items/components/work_item_detail.vue @@ -13,7 +13,6 @@ import { } from '@gitlab/ui'; import noAccessSvg from '@gitlab/svgs/dist/illustrations/analytics/no-access.svg'; import * as Sentry from '@sentry/browser'; -import { fetchPolicies } from '~/lib/graphql'; import { s__ } from '~/locale'; import { getParameterByName, updateHistory, setUrlParams } from '~/lib/utils/url_utility'; import { isPositiveInteger } from '~/lib/utils/number_utils'; @@ -149,8 +148,6 @@ export default { error() { this.setEmptyState(); }, - fetchPolicy: fetchPolicies.CACHE_AND_NETWORK, - notifyOnNetworkStatusChange: true, result(res) { // need to handle this when the res is loading: true, netWorkStatus: 1, partial: true if (!res.data) { @@ -331,7 +328,7 @@ export default { const widgetHierarchy = this.workItem.widgets.find( (widget) => widget.type === WIDGET_TYPE_HIERARCHY, ); - return widgetHierarchy.children.nodes; + return widgetHierarchy.children?.nodes; }, workItemBodyClass() { return { diff --git a/app/assets/javascripts/work_items/components/work_item_links/work_item_tree.vue b/app/assets/javascripts/work_items/components/work_item_links/work_item_tree.vue index 72efe3990d1..dd0d50861e4 100644 --- a/app/assets/javascripts/work_items/components/work_item_links/work_item_tree.vue +++ b/app/assets/javascripts/work_items/components/work_item_links/work_item_tree.vue @@ -1,9 +1,5 @@ <script> -import { isEmpty } from 'lodash'; -import { convertToGraphQLId } from '~/graphql_shared/utils'; -import { TYPENAME_WORK_ITEM } from '~/graphql_shared/constants'; import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants'; -import { getParameterByName } from '~/lib/utils/url_utility'; import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import { @@ -89,26 +85,6 @@ export default { ) .some((hierarchy) => hierarchy.hasChildren); }, - childUrlParams() { - const params = {}; - if (this.fetchByIid) { - const iid = getParameterByName('work_item_iid'); - if (iid) { - params.iid = iid; - } - } else { - const workItemId = getParameterByName('work_item_id'); - if (workItemId) { - params.id = convertToGraphQLId(TYPENAME_WORK_ITEM, workItemId); - } - } - return params; - }, - }, - mounted() { - if (!isEmpty(this.childUrlParams)) { - this.addWorkItemQuery(this.childUrlParams); - } }, methods: { showAddForm(formType, childType) { @@ -123,6 +99,19 @@ export default { hideAddForm() { this.isShownAddForm = false; }, + prefetchWorkItem({ id, iid }) { + if (this.workItemType !== WORK_ITEM_TYPE_VALUE_OBJECTIVE) { + this.prefetch = setTimeout( + () => this.addWorkItemQuery({ id, iid }), + DEFAULT_DEBOUNCE_AND_THROTTLE_MS, + ); + } + }, + clearPrefetching() { + if (this.prefetch) { + clearTimeout(this.prefetch); + } + }, addWorkItemQuery({ id, iid }) { const variables = this.fetchByIid ? { @@ -145,19 +134,6 @@ export default { }, }); }, - prefetchWorkItem({ id, iid }) { - if (this.workItemType !== WORK_ITEM_TYPE_VALUE_OBJECTIVE) { - this.prefetch = setTimeout( - () => this.addWorkItemQuery({ id, iid }), - DEFAULT_DEBOUNCE_AND_THROTTLE_MS, - ); - } - }, - clearPrefetching() { - if (this.prefetch) { - clearTimeout(this.prefetch); - } - }, }, }; </script> diff --git a/app/assets/javascripts/zen_mode.js b/app/assets/javascripts/zen_mode.js index ccb9d05bc90..6634d0cc617 100644 --- a/app/assets/javascripts/zen_mode.js +++ b/app/assets/javascripts/zen_mode.js @@ -6,7 +6,7 @@ import autosize from 'autosize'; import Dropzone from 'dropzone'; import $ from 'jquery'; -import Mousetrap from 'mousetrap'; +import { Mousetrap } from '~/lib/mousetrap'; import 'mousetrap/plugins/pause/mousetrap-pause'; import { scrollToElement } from '~/lib/utils/common_utils'; |