diff --git a/app/assets/javascripts/environments/components/kubernetes_overview.vue b/app/assets/javascripts/environments/components/kubernetes_overview.vue index b9e6548f640..a1efeaac359 100644 --- a/app/assets/javascripts/environments/components/kubernetes_overview.vue +++ b/app/assets/javascripts/environments/components/kubernetes_overview.vue @@ -54,6 +54,7 @@ export default { basePath: this.kasTunnelUrl, baseOptions: { headers: { 'GitLab-Agent-Id': this.gitlabAgentId, ...csrf.headers }, + withCredentials: true, }, }; }, diff --git a/app/assets/javascripts/invite_members/components/members_token_select.vue b/app/assets/javascripts/invite_members/components/members_token_select.vue index 68602068699..e0bfa1111e8 100644 --- a/app/assets/javascripts/invite_members/components/members_token_select.vue +++ b/app/assets/javascripts/invite_members/components/members_token_select.vue @@ -114,11 +114,11 @@ export default { }, }, methods: { - handleTextInput(query) { + handleTextInput(inputQuery) { this.hideDropdownWithNoItems = false; - this.query = query; + this.query = inputQuery.trim(); this.loading = true; - this.retrieveUsers(query); + this.retrieveUsers(); }, updateTokenClasses() { this.selectedTokens = this.selectedTokens.map((token) => ({ diff --git a/app/assets/javascripts/pages/profiles/show/index.js b/app/assets/javascripts/pages/profiles/show/index.js index 96ea7329e6e..69457adf94e 100644 --- a/app/assets/javascripts/pages/profiles/show/index.js +++ b/app/assets/javascripts/pages/profiles/show/index.js @@ -1,8 +1,11 @@ import emojiRegex from 'emoji-regex'; import { __ } from '~/locale'; import { initSetStatusForm } from '~/profile/profile'; +import { initProfileEdit } from '~/profile/edit'; initSetStatusForm(); +// It will do nothing for now when the feature flag is turned off +initProfileEdit(); const userNameInput = document.getElementById('user_name'); if (userNameInput) { diff --git a/app/assets/javascripts/profile/edit/components/profile_edit_app.vue b/app/assets/javascripts/profile/edit/components/profile_edit_app.vue new file mode 100644 index 00000000000..ab29d94c41c --- /dev/null +++ b/app/assets/javascripts/profile/edit/components/profile_edit_app.vue @@ -0,0 +1,10 @@ + + + diff --git a/app/assets/javascripts/profile/edit/index.js b/app/assets/javascripts/profile/edit/index.js new file mode 100644 index 00000000000..b46a395d6f5 --- /dev/null +++ b/app/assets/javascripts/profile/edit/index.js @@ -0,0 +1,16 @@ +import Vue from 'vue'; +import ProfileEditApp from './components/profile_edit_app.vue'; + +export const initProfileEdit = () => { + const mountEl = document.querySelector('.js-user-profile'); + + if (!mountEl) return false; + + return new Vue({ + el: mountEl, + name: 'ProfileEditRoot', + render(createElement) { + return createElement(ProfileEditApp); + }, + }); +}; diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml index 930f4f5c397..1a932ed7b35 100644 --- a/app/views/profiles/show.html.haml +++ b/app/views/profiles/show.html.haml @@ -4,195 +4,198 @@ - gravatar_link = link_to Gitlab.config.gravatar.host, 'https://' + Gitlab.config.gravatar.host - @force_desktop_expanded_sidebar = true -= gitlab_ui_form_for @user, url: profile_path, method: :put, html: { multipart: true, class: 'edit-user js-edit-user gl-mt-3 js-quick-submit gl-show-field-errors js-password-prompt-form', remote: true }, authenticity_token: true do |f| - .row.js-search-settings-section - .col-lg-4.profile-settings-sidebar - %h4.gl-mt-0 - = s_("Profiles|Public avatar") - %p +- if Feature.enabled?(:edit_user_profile_vue, current_user) + .js-user-profile +- else + = gitlab_ui_form_for @user, url: profile_path, method: :put, html: { multipart: true, class: 'edit-user js-edit-user gl-mt-3 js-quick-submit gl-show-field-errors js-password-prompt-form', remote: true }, authenticity_token: true do |f| + .row.js-search-settings-section + .col-lg-4.profile-settings-sidebar + %h4.gl-mt-0 + = s_("Profiles|Public avatar") + %p + - if @user.avatar? + - if gravatar_enabled? + = s_("Profiles|You can change your avatar here or remove the current avatar to revert to %{gravatar_link}").html_safe % { gravatar_link: gravatar_link } + - else + = s_("Profiles|You can change your avatar here") + - else + - if gravatar_enabled? + = s_("Profiles|You can upload your avatar here or change it at %{gravatar_link}").html_safe % { gravatar_link: gravatar_link } + - else + = s_("Profiles|You can upload your avatar here") + - if current_appearance&.profile_image_guidelines? + .md + = brand_profile_image_guidelines + .col-lg-8 + .avatar-image + = link_to avatar_icon_for_user(@user, 400), target: '_blank', rel: 'noopener noreferrer' do + = render Pajamas::AvatarComponent.new(@user, size: 96, alt: "", class: 'gl-float-left gl-mr-5') + %h5.gl-mt-0= s_("Profiles|Upload new avatar") + .gl-display-flex.gl-align-items-center.gl-my-3 + = render Pajamas::ButtonComponent.new(button_options: { class: 'js-choose-user-avatar-button' }) do + = s_("Profiles|Choose file...") + %span.gl-ml-3.js-avatar-filename= s_("Profiles|No file chosen.") + = f.file_field :avatar, class: 'js-user-avatar-input hidden', accept: 'image/*' + .gl-text-gray-500= s_("Profiles|The maximum file size allowed is 200KB.") - if @user.avatar? - - if gravatar_enabled? - = s_("Profiles|You can change your avatar here or remove the current avatar to revert to %{gravatar_link}").html_safe % { gravatar_link: gravatar_link } - - else - = s_("Profiles|You can change your avatar here") - - else - - if gravatar_enabled? - = s_("Profiles|You can upload your avatar here or change it at %{gravatar_link}").html_safe % { gravatar_link: gravatar_link } - - else - = s_("Profiles|You can upload your avatar here") - - if current_appearance&.profile_image_guidelines? - .md - = brand_profile_image_guidelines - .col-lg-8 - .avatar-image - = link_to avatar_icon_for_user(@user, 400), target: '_blank', rel: 'noopener noreferrer' do - = render Pajamas::AvatarComponent.new(@user, size: 96, alt: "", class: 'gl-float-left gl-mr-5') - %h5.gl-mt-0= s_("Profiles|Upload new avatar") - .gl-display-flex.gl-align-items-center.gl-my-3 - = render Pajamas::ButtonComponent.new(button_options: { class: 'js-choose-user-avatar-button' }) do - = s_("Profiles|Choose file...") - %span.gl-ml-3.js-avatar-filename= s_("Profiles|No file chosen.") - = f.file_field :avatar, class: 'js-user-avatar-input hidden', accept: 'image/*' - .gl-text-gray-500= s_("Profiles|The maximum file size allowed is 200KB.") - - if @user.avatar? - = render Pajamas::ButtonComponent.new(variant: :danger, - category: :secondary, - href: profile_avatar_path, - button_options: { class: 'gl-mt-3', data: { confirm: s_("Profiles|Avatar will be removed. Are you sure?") } }, - method: :delete) do - = s_("Profiles|Remove avatar") - .col-lg-12 - %hr - .row.js-search-settings-section - .col-lg-4.profile-settings-sidebar - %h4.gl-mt-0= s_("Profiles|Current status") - %p= s_("Profiles|This emoji and message will appear on your profile and throughout the interface.") - .col-lg-8 - #js-user-profile-set-status-form - = f.fields_for :status, @user.status do |status_form| - = status_form.hidden_field :emoji, data: { js_name: 'emoji' } - = status_form.hidden_field :message, data: { js_name: 'message' } - = status_form.hidden_field :availability, data: { js_name: 'availability' } - = status_form.hidden_field :clear_status_after, - value: user_clear_status_at(@user), - data: { js_name: 'clearStatusAfter' } - .col-lg-12 - %hr - .row.user-time-preferences.js-search-settings-section - .col-lg-4.profile-settings-sidebar - %h4.gl-mt-0= s_("Profiles|Time settings") - %p= s_("Profiles|Set your local time zone.") - .col-lg-8 - = f.label :user_timezone, _("Time zone") - .js-timezone-dropdown{ data: { timezone_data: timezone_data.to_json, initial_value: @user.timezone, name: 'user[timezone]' } } - .col-lg-12 - %hr - .row.js-search-settings-section - .col-lg-4.profile-settings-sidebar - %h4.gl-mt-0 - = s_("Profiles|Main settings") - %p - = s_("Profiles|This information will appear on your profile.") - - if current_user.ldap_user? - = s_("Profiles|Some options are unavailable for LDAP accounts") - .col-lg-8 - .row - .form-group.gl-form-group.col-md-9.rspec-full-name - = render 'profiles/name', form: f, user: @user - .form-group.gl-form-group.col-md-3 - = f.label :id, s_('Profiles|User ID') - = f.text_field :id, class: 'gl-form-input form-control', readonly: true - .form-group.gl-form-group - = f.label :pronouns, s_('Profiles|Pronouns') - = f.text_field :pronouns, class: 'gl-form-input form-control gl-md-form-input-lg' - %small.form-text.text-gl-muted - = s_("Profiles|Enter your pronouns to let people know how to refer to you.") - .form-group.gl-form-group - = f.label :pronunciation, s_('Profiles|Pronunciation') - = f.text_field :pronunciation, class: 'gl-form-input form-control gl-md-form-input-lg' - %small.form-text.text-gl-muted - = s_("Profiles|Enter how your name is pronounced to help people address you correctly.") - = render_if_exists 'profiles/extra_settings', form: f - = render_if_exists 'profiles/email_settings', form: f - .form-group.gl-form-group - = f.label :skype - = f.text_field :skype, class: 'gl-form-input form-control gl-md-form-input-lg', placeholder: s_("Profiles|username") - .form-group.gl-form-group - = f.label :linkedin - = f.text_field :linkedin, class: 'gl-form-input form-control gl-md-form-input-lg' - %small.form-text.text-gl-muted - = s_("Profiles|Your LinkedIn profile name from linkedin.com/in/profilename") - .form-group.gl-form-group - = f.label :twitter - = f.text_field :twitter, class: 'gl-form-input form-control gl-md-form-input-lg', placeholder: s_("Profiles|@username") - .form-group.gl-form-group - - external_accounts_help_url = help_page_path('user/profile/index', anchor: 'add-external-accounts-to-your-user-profile-page') - - external_accounts_link_start = ''.html_safe % { url: external_accounts_help_url } - - external_accounts_docs_link = s_('Profiles|Your Discord user ID. %{external_accounts_link_start}Learn more.%{external_accounts_link_end}').html_safe % { external_accounts_link_start: external_accounts_link_start, external_accounts_link_end: ''.html_safe } - - min_discord_length = 17 - - max_discord_length = 20 - = f.label :discord - = f.text_field :discord, - class: 'gl-form-input form-control gl-md-form-input-lg js-validate-length', - placeholder: s_("Profiles|User ID"), - data: { min_length: min_discord_length, - min_length_message: s_('Profiles|Discord ID is too short (minimum is %{min_length} characters).') % { min_length: min_discord_length }, - max_length: max_discord_length, - max_length_message: s_('Profiles|Discord ID is too long (maximum is %{max_length} characters).') % { max_length: max_discord_length }, - allow_empty: true} - %small.form-text.text-gl-muted - = external_accounts_docs_link - - .form-group.gl-form-group - = f.label :website_url, s_('Profiles|Website url') - = f.text_field :website_url, class: 'gl-form-input form-control gl-md-form-input-lg', placeholder: s_("Profiles|https://website.com") - .form-group.gl-form-group - = f.label :location, s_('Profiles|Location') - - if @user.read_only_attribute?(:location) - = f.text_field :location, class: 'gl-form-input form-control gl-md-form-input-lg', readonly: true + = render Pajamas::ButtonComponent.new(variant: :danger, + category: :secondary, + href: profile_avatar_path, + button_options: { class: 'gl-mt-3', data: { confirm: s_("Profiles|Avatar will be removed. Are you sure?") } }, + method: :delete) do + = s_("Profiles|Remove avatar") + .col-lg-12 + %hr + .row.js-search-settings-section + .col-lg-4.profile-settings-sidebar + %h4.gl-mt-0= s_("Profiles|Current status") + %p= s_("Profiles|This emoji and message will appear on your profile and throughout the interface.") + .col-lg-8 + #js-user-profile-set-status-form + = f.fields_for :status, @user.status do |status_form| + = status_form.hidden_field :emoji, data: { js_name: 'emoji' } + = status_form.hidden_field :message, data: { js_name: 'message' } + = status_form.hidden_field :availability, data: { js_name: 'availability' } + = status_form.hidden_field :clear_status_after, + value: user_clear_status_at(@user), + data: { js_name: 'clearStatusAfter' } + .col-lg-12 + %hr + .row.user-time-preferences.js-search-settings-section + .col-lg-4.profile-settings-sidebar + %h4.gl-mt-0= s_("Profiles|Time settings") + %p= s_("Profiles|Set your local time zone.") + .col-lg-8 + = f.label :user_timezone, _("Time zone") + .js-timezone-dropdown{ data: { timezone_data: timezone_data.to_json, initial_value: @user.timezone, name: 'user[timezone]' } } + .col-lg-12 + %hr + .row.js-search-settings-section + .col-lg-4.profile-settings-sidebar + %h4.gl-mt-0 + = s_("Profiles|Main settings") + %p + = s_("Profiles|This information will appear on your profile.") + - if current_user.ldap_user? + = s_("Profiles|Some options are unavailable for LDAP accounts") + .col-lg-8 + .row + .form-group.gl-form-group.col-md-9.rspec-full-name + = render 'profiles/name', form: f, user: @user + .form-group.gl-form-group.col-md-3 + = f.label :id, s_('Profiles|User ID') + = f.text_field :id, class: 'gl-form-input form-control', readonly: true + .form-group.gl-form-group + = f.label :pronouns, s_('Profiles|Pronouns') + = f.text_field :pronouns, class: 'gl-form-input form-control gl-md-form-input-lg' %small.form-text.text-gl-muted - = s_("Profiles|Your location was automatically set based on your %{provider_label} account") % { provider_label: attribute_provider_label(:location) } - - else - = f.text_field :location, class: 'gl-form-input form-control gl-md-form-input-lg', placeholder: s_("Profiles|City, country") - .form-group.gl-form-group - = f.label :job_title, s_('Profiles|Job title') - = f.text_field :job_title, class: 'gl-form-input form-control gl-md-form-input-lg' - .form-group.gl-form-group - = f.label :organization, s_('Profiles|Organization') - = f.text_field :organization, class: 'gl-form-input form-control gl-md-form-input-lg' - %small.form-text.text-gl-muted - = s_("Profiles|Who you represent or work for.") - .form-group.gl-form-group - = f.label :bio, s_('Profiles|Bio') - = f.text_area :bio, class: 'gl-form-input gl-form-textarea form-control', rows: 4, maxlength: 250 - %small.form-text.text-gl-muted - = s_("Profiles|Tell us about yourself in fewer than 250 characters.") - %hr - %fieldset.form-group.gl-form-group - %legend.col-form-label.col-form-label - = _('Private profile') - - private_profile_label = s_("Profiles|Don't display activity-related personal information on your profile.") - - private_profile_help_link = link_to sprite_icon('question-o'), help_page_path('user/profile/index.md', anchor: 'make-your-user-profile-page-private') - = f.gitlab_ui_checkbox_component :private_profile, '%{private_profile_label} %{private_profile_help_link}'.html_safe % { private_profile_label: private_profile_label, private_profile_help_link: private_profile_help_link.html_safe } - %fieldset.form-group.gl-form-group - %legend.col-form-label.col-form-label - = s_("Profiles|Private contributions") - = f.gitlab_ui_checkbox_component :include_private_contributions, - s_('Profiles|Include private contributions on your profile'), - help_text: s_("Profiles|Choose to show contributions of private projects on your public profile without any project, repository or organization information.") - %fieldset.form-group.gl-form-group - %legend.col-form-label.col-form-label - = s_("Profiles|Achievements") - = f.gitlab_ui_checkbox_component :achievements_enabled, - s_('Profiles|Display achievements on your profile') - .row.js-hide-when-nothing-matches-search - .col-lg-12 - %hr - = f.submit s_("Profiles|Update profile settings"), class: 'gl-mr-3 js-password-prompt-btn', pajamas_button: true - = render Pajamas::ButtonComponent.new(href: user_path(current_user)) do - = s_('TagsPage|Cancel') + = s_("Profiles|Enter your pronouns to let people know how to refer to you.") + .form-group.gl-form-group + = f.label :pronunciation, s_('Profiles|Pronunciation') + = f.text_field :pronunciation, class: 'gl-form-input form-control gl-md-form-input-lg' + %small.form-text.text-gl-muted + = s_("Profiles|Enter how your name is pronounced to help people address you correctly.") + = render_if_exists 'profiles/extra_settings', form: f + = render_if_exists 'profiles/email_settings', form: f + .form-group.gl-form-group + = f.label :skype + = f.text_field :skype, class: 'gl-form-input form-control gl-md-form-input-lg', placeholder: s_("Profiles|username") + .form-group.gl-form-group + = f.label :linkedin + = f.text_field :linkedin, class: 'gl-form-input form-control gl-md-form-input-lg' + %small.form-text.text-gl-muted + = s_("Profiles|Your LinkedIn profile name from linkedin.com/in/profilename") + .form-group.gl-form-group + = f.label :twitter + = f.text_field :twitter, class: 'gl-form-input form-control gl-md-form-input-lg', placeholder: s_("Profiles|@username") + .form-group.gl-form-group + - external_accounts_help_url = help_page_path('user/profile/index', anchor: 'add-external-accounts-to-your-user-profile-page') + - external_accounts_link = link_to '', external_accounts_help_url, target: "_blank", rel: "noopener noreferrer" + - external_accounts_docs_link = safe_format(s_('Profiles|Your Discord user ID. %{external_accounts_link_start}Learn more.%{external_accounts_link_end}'), tag_pair(external_accounts_link, :external_accounts_link_start, :external_accounts_link_end)) + - min_discord_length = 17 + - max_discord_length = 20 + = f.label :discord + = f.text_field :discord, + class: 'gl-form-input form-control gl-md-form-input-lg js-validate-length', + placeholder: s_("Profiles|User ID"), + data: { min_length: min_discord_length, + min_length_message: s_('Profiles|Discord ID is too short (minimum is %{min_length} characters).') % { min_length: min_discord_length }, + max_length: max_discord_length, + max_length_message: s_('Profiles|Discord ID is too long (maximum is %{max_length} characters).') % { max_length: max_discord_length }, + allow_empty: true} + %small.form-text.text-gl-muted + = external_accounts_docs_link -#password-prompt-modal + .form-group.gl-form-group + = f.label :website_url, s_('Profiles|Website url') + = f.text_field :website_url, class: 'gl-form-input form-control gl-md-form-input-lg', placeholder: s_("Profiles|https://website.com") + .form-group.gl-form-group + = f.label :location, s_('Profiles|Location') + - if @user.read_only_attribute?(:location) + = f.text_field :location, class: 'gl-form-input form-control gl-md-form-input-lg', readonly: true + %small.form-text.text-gl-muted + = s_("Profiles|Your location was automatically set based on your %{provider_label} account") % { provider_label: attribute_provider_label(:location) } + - else + = f.text_field :location, class: 'gl-form-input form-control gl-md-form-input-lg', placeholder: s_("Profiles|City, country") + .form-group.gl-form-group + = f.label :job_title, s_('Profiles|Job title') + = f.text_field :job_title, class: 'gl-form-input form-control gl-md-form-input-lg' + .form-group.gl-form-group + = f.label :organization, s_('Profiles|Organization') + = f.text_field :organization, class: 'gl-form-input form-control gl-md-form-input-lg' + %small.form-text.text-gl-muted + = s_("Profiles|Who you represent or work for.") + .form-group.gl-form-group + = f.label :bio, s_('Profiles|Bio') + = f.text_area :bio, class: 'gl-form-input gl-form-textarea form-control', rows: 4, maxlength: 250 + %small.form-text.text-gl-muted + = s_("Profiles|Tell us about yourself in fewer than 250 characters.") + %hr + %fieldset.form-group.gl-form-group + %legend.col-form-label.col-form-label + = _('Private profile') + - private_profile_label = s_("Profiles|Don't display activity-related personal information on your profile.") + - private_profile_help_link = link_to sprite_icon('question-o'), help_page_path('user/profile/index.md', anchor: 'make-your-user-profile-page-private') + = f.gitlab_ui_checkbox_component :private_profile, '%{private_profile_label} %{private_profile_help_link}'.html_safe % { private_profile_label: private_profile_label, private_profile_help_link: private_profile_help_link.html_safe } + %fieldset.form-group.gl-form-group + %legend.col-form-label.col-form-label + = s_("Profiles|Private contributions") + = f.gitlab_ui_checkbox_component :include_private_contributions, + s_('Profiles|Include private contributions on your profile'), + help_text: s_("Profiles|Choose to show contributions of private projects on your public profile without any project, repository or organization information.") + %fieldset.form-group.gl-form-group + %legend.col-form-label.col-form-label + = s_("Profiles|Achievements") + = f.gitlab_ui_checkbox_component :achievements_enabled, + s_('Profiles|Display achievements on your profile') + .row.js-hide-when-nothing-matches-search + .col-lg-12 + %hr + = f.submit s_("Profiles|Update profile settings"), class: 'gl-mr-3 js-password-prompt-btn', pajamas_button: true + = render Pajamas::ButtonComponent.new(href: user_path(current_user)) do + = s_('TagsPage|Cancel') -.modal.modal-profile-crop{ data: { cropper_css_path: ActionController::Base.helpers.stylesheet_path('lazy_bundles/cropper.css') } } - .modal-dialog - .modal-content - .modal-header - %h4.modal-title - = s_("Profiles|Position and size your new avatar") - = render Pajamas::ButtonComponent.new(category: :tertiary, - icon: 'close', - button_options: { class: 'close', "data-dismiss": "modal", "aria-label" => _("Close") }) - .modal-body - .profile-crop-image-container - %img.modal-profile-crop-image{ alt: s_("Profiles|Avatar cropper") } - .gl-text-center.gl-mt-4 - .btn-group - = render Pajamas::ButtonComponent.new(icon: 'search-minus', - button_options: {data: { method: 'zoom', option: '-0.1' }}) - = render Pajamas::ButtonComponent.new(icon: 'search-plus', - button_options: {data: { method: 'zoom', option: '0.1' }}) - .modal-footer - = render Pajamas::ButtonComponent.new(variant: :confirm, - button_options: { class: 'js-upload-user-avatar'}) do - = s_("Profiles|Set new profile picture") + #password-prompt-modal + + .modal.modal-profile-crop{ data: { cropper_css_path: ActionController::Base.helpers.stylesheet_path('lazy_bundles/cropper.css') } } + .modal-dialog + .modal-content + .modal-header + %h4.modal-title + = s_("Profiles|Position and size your new avatar") + = render Pajamas::ButtonComponent.new(category: :tertiary, + icon: 'close', + button_options: { class: 'close', "data-dismiss": "modal", "aria-label" => _("Close") }) + .modal-body + .profile-crop-image-container + %img.modal-profile-crop-image{ alt: s_("Profiles|Avatar cropper") } + .gl-text-center.gl-mt-4 + .btn-group + = render Pajamas::ButtonComponent.new(icon: 'search-minus', + button_options: {data: { method: 'zoom', option: '-0.1' }}) + = render Pajamas::ButtonComponent.new(icon: 'search-plus', + button_options: {data: { method: 'zoom', option: '0.1' }}) + .modal-footer + = render Pajamas::ButtonComponent.new(variant: :confirm, + button_options: { class: 'js-upload-user-avatar'}) do + = s_("Profiles|Set new profile picture") diff --git a/config/feature_flags/development/edit_user_profile_vue.yml b/config/feature_flags/development/edit_user_profile_vue.yml new file mode 100644 index 00000000000..93a50457339 --- /dev/null +++ b/config/feature_flags/development/edit_user_profile_vue.yml @@ -0,0 +1,8 @@ +--- +name: edit_user_profile_vue +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/122402 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/414552 +milestone: '16.1' +type: development +group: group::tenant scale +default_enabled: false diff --git a/doc/ci/pipelines/merge_trains.md b/doc/ci/pipelines/merge_trains.md index ee1c08c4df8..ffddaaf88cb 100644 --- a/doc/ci/pipelines/merge_trains.md +++ b/doc/ci/pipelines/merge_trains.md @@ -209,7 +209,7 @@ the merge train drops your merge request automatically. For example, this could - Changing the merge request to a [draft](../../user/project/merge_requests/drafts.md). - A merge conflict. -- A new conversation thread that is unresolved, when [all threads must be resolved](../../user/discussions/index.md#prevent-merge-unless-all-threads-are-resolved) +- A new conversation thread that is unresolved, when [all threads must be resolved](../../user/project/merge_requests/index.md#prevent-merge-unless-all-threads-are-resolved) is enabled. You can find reason the merge request was dropped from the merge train in the system diff --git a/doc/user/discussions/index.md b/doc/user/discussions/index.md index 77b585c17db..c5fd38ba3e3 100644 --- a/doc/user/discussions/index.md +++ b/doc/user/discussions/index.md @@ -18,7 +18,7 @@ GitLab encourages communication through comments, threads, and Two types of comments are available: - A standard comment. -- A comment in a thread, which can be [resolved](#resolve-a-thread). +- A comment in a thread, which can be [resolved](../project/merge_requests/index.md#resolve-a-thread). In a comment, you can enter [Markdown](../markdown.md) and use [quick actions](../project/quick_actions.md). @@ -95,47 +95,6 @@ it's converted to a link in the context of the merge request. For example, `28719b171a056960dfdc0012b625d0b47b123196` becomes `28719b17` that links to `https://gitlab.example.com/example-group/example-project/-/merge_requests/12345/diffs?commit_id=28719b171a056960dfdc0012b625d0b47b123196`. -## Add a comment to a merge request file - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/121429) in GitLab 16.1 [with a flag](../../administration/feature_flags.md) named `comment_on_files`. Disabled by default. - -FLAG: -On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to [enable the feature flag](../../administration/feature_flags.md) named `comment_on_files`. -On GitLab.com, this feature is not available. - -You can add comments to a merge request diff file. These comments persist across -rebases and file changes. - -To add a comment a merge request file: - -1. On the top bar, select **Main menu > Projects** and find your project. -1. On the left sidebar, select **Settings > Merge requests** and find your merge request. -1. Select **Changes**. -1. In the header for the file you want to comment on, select **Comment** (**{comment}**). - -## Add a comment to a commit - -You can add comments and threads to a particular commit. - -1. On the top bar, select **Main menu > Projects** and find your project. -1. On the left sidebar, select **Repository > Commits**. -1. Below the commits, in the **Comment** field, enter a comment. -1. Select **Comment** or select the down arrow (**{chevron-down}**) to select **Start thread**. - -WARNING: -Threads created this way are lost if the commit ID changes after a -force push. - -## Add a comment to an image - -In merge requests and commit detail views, you can add a comment to an image. -This comment can also be a thread. - -1. Hover your mouse over the image. -1. Select the location where you want to comment. - -An icon is displayed on the image and a comment field is displayed. - ## Reply to a comment by sending email If you have ["reply by email"](../../administration/reply_by_email.md) configured, @@ -304,75 +263,3 @@ To create a thread: A threaded comment is created. ![Thread comment](img/discussion_comment.png) - -## Resolve a thread - -> Resolving comments individually was [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/28750) in GitLab 13.6. - -In a merge request, you can resolve a thread when you want to finish a conversation. - -Prerequisites: - -- You must have at least the Developer role - or be the author of the change being reviewed. -- Resolvable threads can be added only to merge requests. It doesn't work - for comments in issues, commits, or snippets. - -To resolve a thread: - -1. Go to the thread. -1. Do one of the following: - - In the upper-right corner of the original comment, select **Resolve thread** (**{check-circle}**). - - Below the last reply, in the **Reply** field, select **Resolve thread**. - - Below the last reply, in the **Reply** field, enter text, select the **Resolve thread** checkbox, and select **Add comment now**. - -At the top of the page, the number of unresolved threads is updated: - -![Count of unresolved threads](img/unresolved_threads_v15_4.png) - -### Move all unresolved threads in a merge request to an issue - -If you have multiple unresolved threads in a merge request, you can -create an issue to resolve them separately. In the merge request, at the top of the page, -select the ellipsis icon button (**{ellipsis_v}**) in the threads control and then select **Resolve all with new issue**: - -![Open new issue for all unresolved threads](img/create_new_issue_v15_4.png) - -All threads are marked as resolved, and a link is added from the merge request to -the newly created issue. - -### Move one unresolved thread in a merge request to an issue - -If you have one specific unresolved thread in a merge request, you can -create an issue to resolve it separately. In the merge request, under the last reply -to the thread, next to **Resolve thread**, select **Create issue to resolve thread** (**{issue-new}**): - -![Create issue for thread](img/new-issue-one-thread_v14_3.png) - -The thread is marked as resolved, and a link is added from the merge request to -the newly created issue. - -### Prevent merge unless all threads are resolved - -You can prevent merge requests from being merged until all threads are -resolved. When this setting is enabled, the **Unresolved threads** counter in a merge request -is shown in orange when at least one thread remains unresolved. - -1. On the top bar, select **Main menu > Projects** and find your project. -1. On the left sidebar, select **Settings > Merge requests**. -1. In the **Merge checks** section, select the **All threads must be resolved** checkbox. -1. Select **Save changes**. - -### Automatically resolve threads in a merge request when they become outdated - -You can set merge requests to automatically resolve threads when lines are modified -with a new push. - -1. On the top bar, select **Main menu > Projects** and find your project. -1. On the left sidebar, select **Settings > Merge requests**. -1. In the **Merge options** section, select - **Automatically resolve merge request diff threads when they become outdated**. -1. Select **Save changes**. - -Threads are now resolved if a push makes a diff section outdated. -Threads on lines that don't change and top-level resolvable threads are not resolved. diff --git a/doc/user/permissions.md b/doc/user/permissions.md index 0561dfbe3d0..9737a7855dd 100644 --- a/doc/user/permissions.md +++ b/doc/user/permissions.md @@ -129,7 +129,7 @@ The following table lists project permissions available for each role: | [Merge requests](project/merge_requests/index.md):
Add labels | | | ✓ | ✓ | ✓ | | [Merge requests](project/merge_requests/index.md):
Lock threads | | | ✓ | ✓ | ✓ | | [Merge requests](project/merge_requests/index.md):
Manage or accept | | | ✓ | ✓ | ✓ | -| [Merge requests](project/merge_requests/index.md):
[Resolve a thread](discussions/index.md#resolve-a-thread) | | | ✓ | ✓ | ✓ | +| [Merge requests](project/merge_requests/index.md):
[Resolve a thread](project/merge_requests/index.md#resolve-a-thread) | | | ✓ | ✓ | ✓ | | [Merge requests](project/merge_requests/index.md):
Manage [merge approval rules](project/merge_requests/approvals/settings.md) (project settings) | | | | ✓ | ✓ | | [Merge requests](project/merge_requests/index.md):
Delete | | | | | ✓ | | [Metrics dashboards](../operations/metrics/dashboards/index.md):
Manage user-starred metrics dashboards (6) | ✓ | ✓ | ✓ | ✓ | ✓ | diff --git a/doc/user/project/import/github.md b/doc/user/project/import/github.md index 6b88e87cf5a..509029a3099 100644 --- a/doc/user/project/import/github.md +++ b/doc/user/project/import/github.md @@ -284,7 +284,7 @@ When they are imported, supported GitHub branch protection rules are mapped to e | GitHub rule | GitLab rule | Introduced in | | :---------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------ | -| **Require conversation resolution before merging** for the project's default branch | **All threads must be resolved** [project setting](../../discussions/index.md#prevent-merge-unless-all-threads-are-resolved) | [GitLab 15.5](https://gitlab.com/gitlab-org/gitlab/-/issues/371110) | +| **Require conversation resolution before merging** for the project's default branch | **All threads must be resolved** [project setting](../merge_requests/index.md#prevent-merge-unless-all-threads-are-resolved) | [GitLab 15.5](https://gitlab.com/gitlab-org/gitlab/-/issues/371110) | | **Require a pull request before merging** | **No one** option in the **Allowed to push and merge** list of [branch protection settings](../protected_branches.md#add-protection-to-existing-branches) | [GitLab 15.5](https://gitlab.com/gitlab-org/gitlab/-/issues/370951) | | **Require signed commits** for the project's default branch | **Reject unsigned commits** GitLab [push rule](../repository/push_rules.md#prevent-unintended-consequences) **(PREMIUM)** | [GitLab 15.5](https://gitlab.com/gitlab-org/gitlab/-/issues/370949) | | **Allow force pushes - Everyone** | **Allowed to force push** [branch protection setting](../protected_branches.md#allow-force-push-on-a-protected-branch) | [GitLab 15.6](https://gitlab.com/gitlab-org/gitlab/-/issues/370943) | diff --git a/doc/user/project/merge_requests/approvals/index.md b/doc/user/project/merge_requests/approvals/index.md index 8c1f09387ce..68d5665139a 100644 --- a/doc/user/project/merge_requests/approvals/index.md +++ b/doc/user/project/merge_requests/approvals/index.md @@ -67,7 +67,7 @@ if a user approves a merge request and is shown in the reviewer list, a green ch After a merge request receives the [number and type of approvals](rules.md) you configure, it can merge unless it's blocked for another reason. Merge requests can be blocked by other problems, -such as merge conflicts, [unresolved threads](../../../discussions/index.md#prevent-merge-unless-all-threads-are-resolved), +such as merge conflicts, [unresolved threads](../index.md#prevent-merge-unless-all-threads-are-resolved), or a [failed CI/CD pipeline](../merge_when_pipeline_succeeds.md). To prevent merge request authors from approving their own merge requests, diff --git a/doc/user/project/merge_requests/changes.md b/doc/user/project/merge_requests/changes.md index 8f6b1a32424..e6e4a58d39f 100644 --- a/doc/user/project/merge_requests/changes.md +++ b/doc/user/project/merge_requests/changes.md @@ -149,3 +149,31 @@ When there are conflicts between the source and target branch, we show an alert per conflicted file on the merge request diff: ![Example of a conflict alert shown in a merge request diff](img/conflict_ui_v15_6.png) + +## Add a comment to a merge request file + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/121429) in GitLab 16.1 [with a flag](../../../administration/feature_flags.md) named `comment_on_files`. Disabled by default. + +FLAG: +On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to [enable the feature flag](../../../administration/feature_flags.md) named `comment_on_files`. +On GitLab.com, this feature is not available. + +You can add comments to a merge request diff file. These comments persist across +rebases and file changes. + +To add a comment a merge request file: + +1. On the top bar, select **Main menu > Projects** and find your project. +1. On the left sidebar, select **Settings > Merge requests** and find your merge request. +1. Select **Changes**. +1. In the header for the file you want to comment on, select **Comment** (**{comment}**). + +## Add a comment to an image + +In merge requests and commit detail views, you can add a comment to an image. +This comment can also be a thread. + +1. Hover your mouse over the image. +1. Select the location where you want to comment. + +An icon is displayed on the image and a comment field is displayed. diff --git a/doc/user/project/merge_requests/commits.md b/doc/user/project/merge_requests/commits.md index cc6ecd8398f..1c3c1215203 100644 --- a/doc/user/project/merge_requests/commits.md +++ b/doc/user/project/merge_requests/commits.md @@ -29,6 +29,19 @@ To navigate commits in a merge request: ![Merge requests commit navigation](img/commit_nav_v16_0.png) +## Add a comment to a commit + +You can add comments and threads to a particular commit. + +1. On the top bar, select **Main menu > Projects** and find your project. +1. On the left sidebar, select **Repository > Commits**. +1. Below the commits, in the **Comment** field, enter a comment. +1. Select **Comment** or select the down arrow (**{chevron-down}**) to select **Start thread**. + +WARNING: +Threads created this way are lost if the commit ID changes after a +force push. + ## View merge request commits in context > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/29274) in GitLab 13.12 [with a flag](../../../administration/feature_flags.md) named `context_commits`. Enabled by default. diff --git a/doc/user/discussions/img/create_new_issue_v15_4.png b/doc/user/project/merge_requests/img/create_new_issue_v15_4.png similarity index 100% rename from doc/user/discussions/img/create_new_issue_v15_4.png rename to doc/user/project/merge_requests/img/create_new_issue_v15_4.png diff --git a/doc/user/discussions/img/new-issue-one-thread_v14_3.png b/doc/user/project/merge_requests/img/new-issue-one-thread_v14_3.png similarity index 100% rename from doc/user/discussions/img/new-issue-one-thread_v14_3.png rename to doc/user/project/merge_requests/img/new-issue-one-thread_v14_3.png diff --git a/doc/user/discussions/img/unresolved_threads_v15_4.png b/doc/user/project/merge_requests/img/unresolved_threads_v15_4.png similarity index 100% rename from doc/user/discussions/img/unresolved_threads_v15_4.png rename to doc/user/project/merge_requests/img/unresolved_threads_v15_4.png diff --git a/doc/user/project/merge_requests/index.md b/doc/user/project/merge_requests/index.md index af2ebbb471f..abd54d1ebb8 100644 --- a/doc/user/project/merge_requests/index.md +++ b/doc/user/project/merge_requests/index.md @@ -352,6 +352,78 @@ only the items that are relevant to you. Your selection persists across all merge requests. You can also change the sort order by clicking the sort button on the right. +## Resolve a thread + +> Resolving comments individually was [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/28750) in GitLab 13.6. + +In a merge request, you can resolve a thread when you want to finish a conversation. + +Prerequisites: + +- You must have at least the Developer role + or be the author of the change being reviewed. +- Resolvable threads can be added only to merge requests. It doesn't work + for comments in issues, commits, or snippets. + +To resolve a thread: + +1. Go to the thread. +1. Do one of the following: + - In the upper-right corner of the original comment, select **Resolve thread** (**{check-circle}**). + - Below the last reply, in the **Reply** field, select **Resolve thread**. + - Below the last reply, in the **Reply** field, enter text, select the **Resolve thread** checkbox, and select **Add comment now**. + +At the top of the page, the number of unresolved threads is updated: + +![Count of unresolved threads](img/unresolved_threads_v15_4.png) + +### Move all unresolved threads in a merge request to an issue + +If you have multiple unresolved threads in a merge request, you can +create an issue to resolve them separately. In the merge request, at the top of the page, +select the ellipsis icon button (**{ellipsis_v}**) in the threads control and then select **Resolve all with new issue**: + +![Open new issue for all unresolved threads](img/create_new_issue_v15_4.png) + +All threads are marked as resolved, and a link is added from the merge request to +the newly created issue. + +### Move one unresolved thread in a merge request to an issue + +If you have one specific unresolved thread in a merge request, you can +create an issue to resolve it separately. In the merge request, under the last reply +to the thread, next to **Resolve thread**, select **Create issue to resolve thread** (**{issue-new}**): + +![Create issue for thread](img/new-issue-one-thread_v14_3.png) + +The thread is marked as resolved, and a link is added from the merge request to +the newly created issue. + +### Prevent merge unless all threads are resolved + +You can prevent merge requests from being merged until all threads are +resolved. When this setting is enabled, the **Unresolved threads** counter in a merge request +is shown in orange when at least one thread remains unresolved. + +1. On the top bar, select **Main menu > Projects** and find your project. +1. On the left sidebar, select **Settings > Merge requests**. +1. In the **Merge checks** section, select the **All threads must be resolved** checkbox. +1. Select **Save changes**. + +### Automatically resolve threads in a merge request when they become outdated + +You can set merge requests to automatically resolve threads when lines are modified +with a new push. + +1. On the top bar, select **Main menu > Projects** and find your project. +1. On the left sidebar, select **Settings > Merge requests**. +1. In the **Merge options** section, select + **Automatically resolve merge request diff threads when they become outdated**. +1. Select **Save changes**. + +Threads are now resolved if a push makes a diff section outdated. +Threads on lines that don't change and top-level resolvable threads are not resolved. + ## Related topics - [Create a merge request](creating_merge_requests.md) diff --git a/doc/user/project/merge_requests/merge_when_pipeline_succeeds.md b/doc/user/project/merge_requests/merge_when_pipeline_succeeds.md index 19416972ae6..f614a412937 100644 --- a/doc/user/project/merge_requests/merge_when_pipeline_succeeds.md +++ b/doc/user/project/merge_requests/merge_when_pipeline_succeeds.md @@ -31,7 +31,7 @@ Prerequisites: - You must have at least the Developer role in the project. - If the project is configured to require it, all threads in the - merge request [must be resolved](../../discussions/index.md#resolve-a-thread). + merge request [must be resolved](index.md#resolve-a-thread). - The merge request must have received all required approvals. To do this when pushing from the command line, use the `merge_request.merge_when_pipeline_succeeds` diff --git a/doc/user/project/merge_requests/reviews/index.md b/doc/user/project/merge_requests/reviews/index.md index 0f5982f47dc..65042da48e4 100644 --- a/doc/user/project/merge_requests/reviews/index.md +++ b/doc/user/project/merge_requests/reviews/index.md @@ -147,7 +147,7 @@ When you submit your review, GitLab: ### Resolve or unresolve thread with a comment -Review comments can also resolve or unresolve [resolvable threads](../../../discussions/index.md#resolve-a-thread). +Review comments can also resolve or unresolve [resolvable threads](../index.md#resolve-a-thread). To resolve or unresolve a thread when replying to a comment: 1. In the comment text area, write your comment. diff --git a/doc/user/project/settings/index.md b/doc/user/project/settings/index.md index 47500673b99..0a4be5d7053 100644 --- a/doc/user/project/settings/index.md +++ b/doc/user/project/settings/index.md @@ -159,7 +159,7 @@ Configure your project's merge request settings: - Enable [merge request approvals](../merge_requests/approvals/index.md). - Enable [status checks](../merge_requests/status_checks.md). - Enable [merge only if pipeline succeeds](../merge_requests/merge_when_pipeline_succeeds.md). -- Enable [merge only when all threads are resolved](../../discussions/index.md#prevent-merge-unless-all-threads-are-resolved). +- Enable [merge only when all threads are resolved](../merge_requests/index.md#prevent-merge-unless-all-threads-are-resolved). - Enable [require an associated issue from Jira](../../../integration/jira/issues.md#require-associated-jira-issue-for-merge-requests-to-be-merged). - Enable [**Delete source branch when merge request is accepted** option by default](#delete-the-source-branch-on-merge-by-default). - Configure [suggested changes commit messages](../merge_requests/reviews/suggestions.md#configure-the-commit-message-for-applied-suggestions). diff --git a/locale/gitlab.pot b/locale/gitlab.pot index ed511e9f43d..60676c13616 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -30091,9 +30091,6 @@ msgstr "" msgid "New Group" msgstr "" -msgid "New Group Name" -msgstr "" - msgid "New Identity" msgstr "" @@ -30180,6 +30177,9 @@ msgstr "" msgid "New group" msgstr "" +msgid "New group name" +msgstr "" + msgid "New health check access token has been generated!" msgstr "" diff --git a/package.json b/package.json index f02d0a1f864..0449b071c9a 100644 --- a/package.json +++ b/package.json @@ -281,7 +281,7 @@ "vue-loader-vue3": "npm:vue-loader@17", "vue-test-utils-compat": "0.0.13", "vuex-mock-store": "^0.1.0", - "webpack-dev-server": "4.15.0", + "webpack-dev-server": "4.15.1", "xhr-mock": "^2.5.1", "yarn-check-webpack-plugin": "^1.2.0", "yarn-deduplicate": "^6.0.2" diff --git a/spec/features/admin/admin_appearance_spec.rb b/spec/features/admin/admin_appearance_spec.rb index db0ae79c9c4..71c904b3a19 100644 --- a/spec/features/admin/admin_appearance_spec.rb +++ b/spec/features/admin/admin_appearance_spec.rb @@ -6,6 +6,10 @@ RSpec.describe 'Admin Appearance', feature_category: :shared do let!(:appearance) { create(:appearance) } let(:admin) { create(:admin) } + before do + stub_feature_flags(edit_user_profile_vue: false) + end + flag_values = [true, false] flag_values.each do |val| context "with #{val}" do diff --git a/spec/features/file_uploads/user_avatar_spec.rb b/spec/features/file_uploads/user_avatar_spec.rb index 062c47d5310..3f7d69afa0b 100644 --- a/spec/features/file_uploads/user_avatar_spec.rb +++ b/spec/features/file_uploads/user_avatar_spec.rb @@ -8,6 +8,7 @@ RSpec.describe 'Upload a user avatar', :js, feature_category: :user_profile do let(:file) { fixture_file_upload('spec/fixtures/banana_sample.gif') } before do + stub_feature_flags(edit_user_profile_vue: false) sign_in(user) visit(profile_path) attach_file('user_avatar-trigger', file.path, make_visible: true) diff --git a/spec/features/profiles/user_edit_profile_spec.rb b/spec/features/profiles/user_edit_profile_spec.rb index 3ce1c3a33a0..de8719630ee 100644 --- a/spec/features/profiles/user_edit_profile_spec.rb +++ b/spec/features/profiles/user_edit_profile_spec.rb @@ -8,6 +8,7 @@ RSpec.describe 'User edit profile', feature_category: :user_profile do let_it_be(:user) { create(:user) } before do + stub_feature_flags(edit_user_profile_vue: false) sign_in(user) visit(profile_path) end diff --git a/spec/features/profiles/user_search_settings_spec.rb b/spec/features/profiles/user_search_settings_spec.rb index 932ea11075a..96fe01cd0c2 100644 --- a/spec/features/profiles/user_search_settings_spec.rb +++ b/spec/features/profiles/user_search_settings_spec.rb @@ -7,6 +7,7 @@ RSpec.describe 'User searches their settings', :js, feature_category: :user_prof before do sign_in(user) + stub_feature_flags(edit_user_profile_vue: false) end context 'in profile page' do diff --git a/spec/features/profiles/user_visits_profile_spec.rb b/spec/features/profiles/user_visits_profile_spec.rb index ad265fbae9e..578025e1494 100644 --- a/spec/features/profiles/user_visits_profile_spec.rb +++ b/spec/features/profiles/user_visits_profile_spec.rb @@ -7,6 +7,7 @@ RSpec.describe 'User visits their profile', feature_category: :user_profile do before do stub_feature_flags(profile_tabs_vue: false) + stub_feature_flags(edit_user_profile_vue: false) sign_in(user) end diff --git a/spec/features/uploads/user_uploads_avatar_to_profile_spec.rb b/spec/features/uploads/user_uploads_avatar_to_profile_spec.rb index f1023f17d3e..03b072ea417 100644 --- a/spec/features/uploads/user_uploads_avatar_to_profile_spec.rb +++ b/spec/features/uploads/user_uploads_avatar_to_profile_spec.rb @@ -7,6 +7,7 @@ RSpec.describe 'User uploads avatar to profile', feature_category: :user_profile let(:avatar_file_path) { Rails.root.join('spec', 'fixtures', 'dk.png') } before do + stub_feature_flags(edit_user_profile_vue: false) sign_in user visit profile_path end diff --git a/spec/frontend/environments/kubernetes_overview_spec.js b/spec/frontend/environments/kubernetes_overview_spec.js index b9eff2f79c5..1c7ace00f48 100644 --- a/spec/frontend/environments/kubernetes_overview_spec.js +++ b/spec/frontend/environments/kubernetes_overview_spec.js @@ -22,6 +22,7 @@ const configuration = { basePath: provide.kasTunnelUrl.replace(/\/$/, ''), baseOptions: { headers: { 'GitLab-Agent-Id': '1' }, + withCredentials: true, }, }; diff --git a/spec/frontend/invite_members/components/members_token_select_spec.js b/spec/frontend/invite_members/components/members_token_select_spec.js index c7e9905dee3..ff0313cc49e 100644 --- a/spec/frontend/invite_members/components/members_token_select_spec.js +++ b/spec/frontend/invite_members/components/members_token_select_spec.js @@ -130,6 +130,18 @@ describe('MembersTokenSelect', () => { expect(tokenSelector.props('hideDropdownWithNoItems')).toBe(false); }); + it('calls the API with search parameter with whitespaces and is trimmed', async () => { + tokenSelector.vm.$emit('text-input', ' foo@bar.com '); + + await waitForPromises(); + + expect(UserApi.getUsers).toHaveBeenCalledWith('foo@bar.com', { + active: true, + without_project_bots: true, + }); + expect(tokenSelector.props('hideDropdownWithNoItems')).toBe(false); + }); + describe('when input text is an email', () => { it('allows user defined tokens', async () => { tokenSelector.vm.$emit('text-input', 'foo@bar.com'); diff --git a/spec/views/profiles/show.html.haml_spec.rb b/spec/views/profiles/show.html.haml_spec.rb index d5cb5694031..ea0a9ebb02c 100644 --- a/spec/views/profiles/show.html.haml_spec.rb +++ b/spec/views/profiles/show.html.haml_spec.rb @@ -10,6 +10,7 @@ RSpec.describe 'profiles/show' do assign(:user, user) allow(controller).to receive(:current_user).and_return(user) allow(view).to receive(:experiment_enabled?) + stub_feature_flags(edit_user_profile_vue: false) end context 'when the profile page is opened' do diff --git a/yarn.lock b/yarn.lock index cb4fe862d0f..41e1cd13621 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2468,10 +2468,10 @@ dependencies: "@types/node" "*" -"@types/ws@^8.0.0", "@types/ws@^8.5.1": - version "8.5.3" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" - integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== +"@types/ws@^8.0.0", "@types/ws@^8.5.5": + version "8.5.5" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.5.tgz#af587964aa06682702ee6dcbc7be41a80e4b28eb" + integrity sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg== dependencies: "@types/node" "*" @@ -12990,10 +12990,10 @@ webpack-dev-middleware@^5.3.1: range-parser "^1.2.1" schema-utils "^4.0.0" -webpack-dev-server@4.15.0: - version "4.15.0" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.15.0.tgz#87ba9006eca53c551607ea0d663f4ae88be7af21" - integrity sha512-HmNB5QeSl1KpulTBQ8UT4FPrByYyaLxpJoQ0+s7EvUrMc16m0ZS1sgb1XGqzmgCPk0c9y+aaXxn11tbLzuM7NQ== +webpack-dev-server@4.15.1: + version "4.15.1" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz#8944b29c12760b3a45bdaa70799b17cb91b03df7" + integrity sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA== dependencies: "@types/bonjour" "^3.5.9" "@types/connect-history-api-fallback" "^1.3.5" @@ -13001,7 +13001,7 @@ webpack-dev-server@4.15.0: "@types/serve-index" "^1.9.1" "@types/serve-static" "^1.13.10" "@types/sockjs" "^0.3.33" - "@types/ws" "^8.5.1" + "@types/ws" "^8.5.5" ansi-html-community "^0.0.8" bonjour-service "^1.0.11" chokidar "^3.5.3"