From 2b1e7f7dac0fa5d7bb3bdf415cec1b3c67ed77b0 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Tue, 27 Oct 2020 15:08:39 +0000 Subject: [PATCH] Add latest changes from gitlab-org/gitlab@master --- .../behaviors/copy_to_clipboard.js | 30 + .../behaviors/shortcuts/shortcuts_issuable.js | 17 + .../ci_variable_list/ajax_variable_list.js | 128 ---- .../components/ci_environments_dropdown.vue | 4 +- .../components/ci_variable_modal.vue | 8 +- .../ide/components/terminal/empty_state.vue | 15 +- app/assets/javascripts/lib/utils/dom_utils.js | 22 + app/assets/javascripts/main.js | 11 +- .../pages/groups/settings/ci_cd/show/index.js | 16 +- .../projects/settings/ci_cd/show/index.js | 15 +- .../popovers/components/popovers.vue | 92 +++ app/assets/javascripts/popovers/index.js | 51 ++ .../components/mr_widget_header.vue | 13 - app/assets/stylesheets/framework/flash.scss | 8 +- .../stylesheets/pages/merge_requests.scss | 6 - .../groups/settings/ci_cd_controller.rb | 3 - .../projects/imports_controller.rb | 2 +- .../merge_requests/diffs_controller.rb | 5 +- .../projects/settings/ci_cd_controller.rb | 1 - app/finders/environment_names_finder.rb | 14 +- app/helpers/page_layout_helper.rb | 5 +- app/models/merge_request_diff_file.rb | 4 + app/serializers/paginated_diff_entity.rb | 9 +- app/views/ci/variables/_index.html.haml | 48 +- app/views/projects/pipelines/_info.html.haml | 2 +- .../273142-fj-enable-avatar-with-full-url.yml | 5 + .../36837-fj-fix-bug-robots-git-suffix.yml | 5 + ...fix-bug-when-user-anonymous-and-import.yml | 5 + ...remove-ci-variables-table-feature-flag.yml | 5 + .../nfriend-move-copy-branch-shortcut.yml | 5 + changelogs/unreleased/psi-mr-space.yml | 5 + .../development/avatar_with_host.yml | 7 - .../development/new_variables_ui.yml | 7 - doc/user/group/saml_sso/scim_setup.md | 72 +-- .../merge_request_diff_batch.rb | 16 +- locale/gitlab.pot | 9 - public/robots.txt | 2 +- .../projects/imports_controller_spec.rb | 13 +- .../merge_requests/diffs_controller_spec.rb | 25 + spec/features/group_variables_spec.rb | 2 +- spec/features/project_group_variables_spec.rb | 9 +- spec/features/project_variables_spec.rb | 27 +- .../settings/registry_settings_spec.rb | 1 - spec/finders/environment_names_finder_spec.rb | 184 ++++-- spec/frontend/__mocks__/@gitlab/ui.js | 10 +- .../shortcuts/shortcuts_issuable_spec.js | 98 +++- .../ajax_variable_list_spec.js | 203 ------- .../ci_variable_list/ci_variable_list_spec.js | 120 ---- spec/frontend/fixtures/groups.rb | 9 - spec/frontend/fixtures/projects.rb | 24 - .../components/terminal/empty_state_spec.js | 21 +- spec/frontend/lib/utils/dom_utils_spec.js | 33 ++ .../popovers/components/popovers_spec.js | 129 +++++ spec/frontend/popovers/index_spec.js | 104 ++++ .../components/mr_widget_header_spec.js | 35 -- spec/helpers/page_layout_helper_spec.rb | 10 - ...152703_migrate_issue_trackers_data_spec.rb | 2 +- ..._code_owner_approval_from_projects_spec.rb | 2 +- spec/requests/robots_txt_spec.rb | 6 +- spec/support/helpers/require_migration.rb | 23 +- .../features/variable_list_shared_examples.rb | 546 ++++++++---------- 61 files changed, 1178 insertions(+), 1130 deletions(-) delete mode 100644 app/assets/javascripts/ci_variable_list/ajax_variable_list.js create mode 100644 app/assets/javascripts/popovers/components/popovers.vue create mode 100644 app/assets/javascripts/popovers/index.js create mode 100644 changelogs/unreleased/273142-fj-enable-avatar-with-full-url.yml create mode 100644 changelogs/unreleased/36837-fj-fix-bug-robots-git-suffix.yml create mode 100644 changelogs/unreleased/fj-fix-bug-when-user-anonymous-and-import.yml create mode 100644 changelogs/unreleased/jivanvl-remove-ci-variables-table-feature-flag.yml create mode 100644 changelogs/unreleased/nfriend-move-copy-branch-shortcut.yml create mode 100644 changelogs/unreleased/psi-mr-space.yml delete mode 100644 config/feature_flags/development/avatar_with_host.yml delete mode 100644 config/feature_flags/development/new_variables_ui.yml delete mode 100644 spec/frontend/ci_variable_list/ci_variable_list/ajax_variable_list_spec.js create mode 100644 spec/frontend/popovers/components/popovers_spec.js create mode 100644 spec/frontend/popovers/index_spec.js diff --git a/app/assets/javascripts/behaviors/copy_to_clipboard.js b/app/assets/javascripts/behaviors/copy_to_clipboard.js index 430a8c38387..e822072d669 100644 --- a/app/assets/javascripts/behaviors/copy_to_clipboard.js +++ b/app/assets/javascripts/behaviors/copy_to_clipboard.js @@ -79,3 +79,33 @@ export default function initCopyToClipboard() { clipboardData.setData('text/x-gfm', json.gfm); }); } + +/** + * Programmatically triggers a click event on a + * "copy to clipboard" button, causing its + * contents to be copied. Handles some of the messiniess + * around managing the button's tooltip. + * @param {HTMLElement} btnElement + */ +export function clickCopyToClipboardButton(btnElement) { + const $btnElement = $(btnElement); + + // Ensure the button has already been tooltip'd. + // If the use hasn't yet interacted (i.e. hovered or clicked) + // with the button, Bootstrap hasn't yet initialized + // the tooltip, and its `data-original-title` will be `undefined`. + // This value is used in the functions above. + $btnElement.tooltip(); + btnElement.dispatchEvent(new MouseEvent('mouseover')); + + btnElement.click(); + + // Manually trigger the necessary events to hide the + // button's tooltip and allow the button to perform its + // tooltip cleanup (updating the title from "Copied" back + // to its original title, "Copy branch name"). + setTimeout(() => { + btnElement.dispatchEvent(new MouseEvent('mouseout')); + $btnElement.tooltip('hide'); + }, 2000); +} diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts_issuable.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts_issuable.js index f7b327b2af1..5a5a67334d3 100644 --- a/app/assets/javascripts/behaviors/shortcuts/shortcuts_issuable.js +++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts_issuable.js @@ -4,6 +4,8 @@ import Sidebar from '../../right_sidebar'; import Shortcuts from './shortcuts'; import { CopyAsGFM } from '../markdown/copy_as_gfm'; import { getSelectedFragment } from '~/lib/utils/common_utils'; +import { isElementVisible } from '~/lib/utils/dom_utils'; +import { clickCopyToClipboardButton } from '~/behaviors/copy_to_clipboard'; export default class ShortcutsIssuable extends Shortcuts { constructor() { @@ -14,6 +16,7 @@ export default class ShortcutsIssuable extends Shortcuts { Mousetrap.bind('l', () => ShortcutsIssuable.openSidebarDropdown('labels')); Mousetrap.bind('r', ShortcutsIssuable.replyWithSelectedText); Mousetrap.bind('e', ShortcutsIssuable.editIssue); + Mousetrap.bind('b', ShortcutsIssuable.copyBranchName); } static replyWithSelectedText() { @@ -98,4 +101,18 @@ export default class ShortcutsIssuable extends Shortcuts { Sidebar.instance.openDropdown(name); return false; } + + static copyBranchName() { + // There are two buttons - one that is shown when the sidebar + // is expanded, and one that is shown when it's collapsed. + const allCopyBtns = Array.from(document.querySelectorAll('.sidebar-source-branch button')); + + // Select whichever button is currently visible so that + // the "Copied" tooltip is shown when a click is simulated. + const visibleBtn = allCopyBtns.find(isElementVisible); + + if (visibleBtn) { + clickCopyToClipboardButton(visibleBtn); + } + } } diff --git a/app/assets/javascripts/ci_variable_list/ajax_variable_list.js b/app/assets/javascripts/ci_variable_list/ajax_variable_list.js deleted file mode 100644 index b8bf363fc9d..00000000000 --- a/app/assets/javascripts/ci_variable_list/ajax_variable_list.js +++ /dev/null @@ -1,128 +0,0 @@ -import { escape } from 'lodash'; -import axios from '../lib/utils/axios_utils'; -import { s__ } from '../locale'; -import { deprecatedCreateFlash as Flash } from '../flash'; -import { parseBoolean } from '../lib/utils/common_utils'; -import statusCodes from '../lib/utils/http_status'; -import VariableList from './ci_variable_list'; - -function generateErrorBoxContent(errors) { - const errorList = [].concat(errors).map( - errorString => ` -
  • - ${escape(errorString)} -
  • - `, - ); - - return ` -

    - ${s__('CiVariable|Validation failed')} -

    - - `; -} - -// Used for the variable list on CI/CD projects/groups settings page -export default class AjaxVariableList { - constructor({ - container, - saveButton, - errorBox, - formField = 'variables', - saveEndpoint, - maskableRegex, - }) { - this.container = container; - this.saveButton = saveButton; - this.errorBox = errorBox; - this.saveEndpoint = saveEndpoint; - this.maskableRegex = maskableRegex; - - this.variableList = new VariableList({ - container: this.container, - formField, - maskableRegex, - }); - - this.bindEvents(); - this.variableList.init(); - } - - bindEvents() { - this.saveButton.addEventListener('click', this.onSaveClicked.bind(this)); - } - - onSaveClicked() { - const loadingIcon = this.saveButton.querySelector('.js-ci-variables-save-loading-icon'); - loadingIcon.classList.toggle('hide', false); - this.errorBox.classList.toggle('hide', true); - // We use this to prevent a user from changing a key before we have a chance - // to match it up in `updateRowsWithPersistedVariables` - this.variableList.toggleEnableRow(false); - - return axios - .patch( - this.saveEndpoint, - { - variables_attributes: this.variableList.getAllData(), - }, - { - // We want to be able to process the `res.data` from a 400 error response - // and print the validation messages such as duplicate variable keys - validateStatus: status => - (status >= statusCodes.OK && status < statusCodes.MULTIPLE_CHOICES) || - status === statusCodes.BAD_REQUEST, - }, - ) - .then(res => { - loadingIcon.classList.toggle('hide', true); - this.variableList.toggleEnableRow(true); - - if (res.status === statusCodes.OK && res.data) { - this.updateRowsWithPersistedVariables(res.data.variables); - this.variableList.hideValues(); - } else if (res.status === statusCodes.BAD_REQUEST) { - // Validation failed - this.errorBox.innerHTML = generateErrorBoxContent(res.data); - this.errorBox.classList.toggle('hide', false); - } - }) - .catch(() => { - loadingIcon.classList.toggle('hide', true); - this.variableList.toggleEnableRow(true); - Flash(s__('CiVariable|Error occurred while saving variables')); - }); - } - - updateRowsWithPersistedVariables(persistedVariables = []) { - const persistedVariableMap = [].concat(persistedVariables).reduce( - (variableMap, variable) => ({ - ...variableMap, - [variable.key]: variable, - }), - {}, - ); - - this.container.querySelectorAll('.js-row').forEach(row => { - // If we submitted a row that was destroyed, remove it so we don't try - // to destroy it again which would cause a BE error - const destroyInput = row.querySelector('.js-ci-variable-input-destroy'); - if (parseBoolean(destroyInput.value)) { - row.remove(); - // Update the ID input so any future edits and `_destroy` will apply on the BE - } else { - const key = row.querySelector('.js-ci-variable-input-key').value; - const persistedVariable = persistedVariableMap[key]; - - if (persistedVariable) { - // eslint-disable-next-line no-param-reassign - row.querySelector('.js-ci-variable-input-id').value = persistedVariable.id; - row.setAttribute('data-is-persisted', 'true'); - } - } - }); - } -} diff --git a/app/assets/javascripts/ci_variable_list/components/ci_environments_dropdown.vue b/app/assets/javascripts/ci_variable_list/components/ci_environments_dropdown.vue index ceb94b1f0f8..83e9717041f 100644 --- a/app/assets/javascripts/ci_variable_list/components/ci_environments_dropdown.vue +++ b/app/assets/javascripts/ci_variable_list/components/ci_environments_dropdown.vue @@ -60,7 +60,7 @@ export default {