diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-06-12 18:10:26 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-06-12 18:10:26 +0300 |
commit | c0b17cee8be646588b14db49ad6d91b8cc818f97 (patch) | |
tree | 97287971303bccd649da1718c1a3a1ba8f345df6 /app | |
parent | 8ef107c43390ea9c9932afb55d1318e4716fbf3b (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
14 files changed, 136 insertions, 74 deletions
diff --git a/app/assets/javascripts/vue_merge_request_widget/mixins/approvals.js b/app/assets/javascripts/vue_merge_request_widget/mixins/approvals.js index 3228c09c9b6..564e9321d54 100644 --- a/app/assets/javascripts/vue_merge_request_widget/mixins/approvals.js +++ b/app/assets/javascripts/vue_merge_request_widget/mixins/approvals.js @@ -39,7 +39,7 @@ export default { }; }, skip() { - return !this.mr?.id || !this.isRealtimeEnabled; + return !this.mr?.id; }, updateQuery( _, @@ -63,14 +63,6 @@ export default { disableCommittersApproval: false, }; }, - computed: { - isRealtimeEnabled() { - // This mixin needs glFeatureFlagsMixin, but fatals if it's included here. - // Parents that include this mixin (approvals) should also include the - // glFeatureFlagsMixin mixin, or this will always be false. - return Boolean(this.glFeatures?.realtimeApprovals); - }, - }, methods: { clearError() { this.$emit('clearError'); diff --git a/app/assets/stylesheets/components/content_editor.scss b/app/assets/stylesheets/components/content_editor.scss index 680b24be442..2ed955a56b6 100644 --- a/app/assets/stylesheets/components/content_editor.scss +++ b/app/assets/stylesheets/components/content_editor.scss @@ -56,17 +56,15 @@ list-style: none; padding: 0; - li { - margin: 0 !important; - } - } - - [data-type='taskList'] { + ul, p { margin-bottom: 0; } - li { + > li { + display: flex; + margin: 0; + > label, > div { display: inline-block; diff --git a/app/assets/stylesheets/framework/files.scss b/app/assets/stylesheets/framework/files.scss index 0b5d20c7398..287a20a56c5 100644 --- a/app/assets/stylesheets/framework/files.scss +++ b/app/assets/stylesheets/framework/files.scss @@ -3,6 +3,7 @@ * */ .file-holder { + background: $white; border: 1px solid $border-color; border-radius: $border-radius-default; @@ -99,8 +100,6 @@ } .file-content { - background: $white; - &.image_file, &.audio, &.video { diff --git a/app/assets/stylesheets/page_bundles/login.scss b/app/assets/stylesheets/page_bundles/login.scss index c25e15c1af9..1752d6e90a9 100644 --- a/app/assets/stylesheets/page_bundles/login.scss +++ b/app/assets/stylesheets/page_bundles/login.scss @@ -55,12 +55,12 @@ .omniauth-container { box-shadow: none; } + } - .g-recaptcha { - > div { - margin-left: auto; - margin-right: auto; - } + .g-recaptcha { + > div { + margin-left: auto; + margin-right: auto; } } diff --git a/app/assets/stylesheets/startup/startup-signin.scss b/app/assets/stylesheets/startup/startup-signin.scss index dc26eb98564..7c37bcd085b 100644 --- a/app/assets/stylesheets/startup/startup-signin.scss +++ b/app/assets/stylesheets/startup/startup-signin.scss @@ -79,16 +79,11 @@ input { button { text-transform: none; } -[role="button"] { - cursor: pointer; -} button:not(:disabled), -[type="button"]:not(:disabled), [type="submit"]:not(:disabled) { cursor: pointer; } button::-moz-focus-inner, -[type="button"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner { padding: 0; border-style: none; @@ -216,6 +211,10 @@ hr { .form-group { margin-bottom: 1rem; } +.form-text { + display: block; + margin-top: 0.25rem; +} .btn { display: inline-block; font-weight: 400; @@ -248,8 +247,7 @@ fieldset:disabled a.btn { .btn-block + .btn-block { margin-top: 0.5rem; } -input.btn-block[type="submit"], -input.btn-block[type="button"] { +input.btn-block[type="submit"] { width: 100%; } .custom-control { @@ -584,9 +582,7 @@ body { font-size: 0.875rem; } button, -html [type="button"], -[type="submit"], -[role="button"] { +[type="submit"] { cursor: pointer; } h1, @@ -727,9 +723,6 @@ label { label.custom-control-label { font-weight: 400; } -label.label-bold { - font-weight: 600; -} .form-control { border-radius: 4px; padding: 6px 10px; @@ -780,18 +773,12 @@ svg { .gl-display-flex { display: flex; } -.gl-display-inline-block { - display: inline-block; -} .gl-align-items-center { align-items: center; } .gl-justify-content-space-between { justify-content: space-between; } -.gl-float-right { - float: right; -} .gl-w-10 { width: 3.5rem; } @@ -806,16 +793,13 @@ svg { width: 100%; } } +.gl-p-5 { + padding: 1rem; +} .gl-px-5 { padding-left: 1rem; padding-right: 1rem; } -.gl-pt-5 { - padding-top: 1rem; -} -.gl-pb-5 { - padding-bottom: 1rem; -} .gl-py-5 { padding-top: 1rem; padding-bottom: 1rem; @@ -829,9 +813,6 @@ svg { .gl-mr-auto { margin-right: auto; } -.gl-mb-1 { - margin-bottom: 0.125rem; -} .gl-mb-2 { margin-bottom: 0.25rem; } @@ -849,6 +830,9 @@ svg { .gl-text-center { text-align: center; } +.gl-text-right { + text-align: right; +} .gl-font-size-h2 { font-size: 1.1875rem; } diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 2b450239914..123a8c70444 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -46,7 +46,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo push_frontend_feature_flag(:moved_mr_sidebar, project) push_frontend_feature_flag(:mr_experience_survey, project) push_frontend_feature_flag(:realtime_mr_status_change, project) - push_frontend_feature_flag(:realtime_approvals, project) push_frontend_feature_flag(:saved_replies, current_user) push_frontend_feature_flag(:code_quality_inline_drawer, project) push_frontend_feature_flag(:auto_merge_labels_mr_widget, project) diff --git a/app/models/issue_link.rb b/app/models/issue_link.rb index 1bd34aa0083..af55a5dec91 100644 --- a/app/models/issue_link.rb +++ b/app/models/issue_link.rb @@ -9,6 +9,9 @@ class IssueLink < ApplicationRecord scope :for_source_issue, ->(issue) { where(source_id: issue.id) } scope :for_target_issue, ->(issue) { where(target_id: issue.id) } + scope :for_issues, ->(source, target) do + where(source: source, target: target).or(where(source: target, target: source)) + end class << self def issuable_type diff --git a/app/presenters/packages/nuget/packages_metadata_presenter.rb b/app/presenters/packages/nuget/packages_metadata_presenter.rb index 10a19060f8a..f87f447fb23 100644 --- a/app/presenters/packages/nuget/packages_metadata_presenter.rb +++ b/app/presenters/packages/nuget/packages_metadata_presenter.rb @@ -59,8 +59,8 @@ module Packages end def sorted_versions - versions = @packages.map(&:version).compact - VersionSorter.sort(versions) + versions = @packages.filter_map(&:version) + sort_versions(versions) end strong_memoize_attr :sorted_versions end diff --git a/app/presenters/packages/nuget/presenter_helpers.rb b/app/presenters/packages/nuget/presenter_helpers.rb index ea8558c54f4..16c32a9d0d0 100644 --- a/app/presenters/packages/nuget/presenter_helpers.rb +++ b/app/presenters/packages/nuget/presenter_helpers.rb @@ -4,6 +4,7 @@ module Packages module Nuget module PresenterHelpers include ::API::Helpers::RelatedResourcesHelpers + include Packages::Nuget::VersionHelpers PACKAGE_DEPENDENCY_GROUP = 'PackageDependencyGroup' PACKAGE_DEPENDENCY = 'PackageDependency' diff --git a/app/presenters/packages/nuget/search_results_presenter.rb b/app/presenters/packages/nuget/search_results_presenter.rb index 45c2c5170ae..020e8656a36 100644 --- a/app/presenters/packages/nuget/search_results_presenter.rb +++ b/app/presenters/packages/nuget/search_results_presenter.rb @@ -45,8 +45,8 @@ module Packages end def latest_version(packages) - versions = packages.map(&:version).compact - VersionSorter.sort(versions).last + versions = packages.filter_map(&:version) + sort_versions(versions).last end end end diff --git a/app/presenters/packages/nuget/version_helpers.rb b/app/presenters/packages/nuget/version_helpers.rb new file mode 100644 index 00000000000..8c9c82791b3 --- /dev/null +++ b/app/presenters/packages/nuget/version_helpers.rb @@ -0,0 +1,88 @@ +# frozen_string_literal: true + +module Packages + module Nuget + module VersionHelpers + private + + def sort_versions(versions) + versions.sort { |a, b| compare_versions(a, b) } + end + + # NuGet version sorting algorithm as per https://semver.org/spec/v2.0.0.html#spec-item-11 + def compare_versions(version_a, version_b) + return 0 if version_a == version_b + return 1 if version_b.nil? + return -1 if version_a.nil? + + a_without_build_meta, a_build_meta = version_a.split('+', 2) + b_without_build_meta, b_build_meta = version_b.split('+', 2) + + a_core, a_pre = a_without_build_meta.split(/-/, 2) + b_core, b_pre = b_without_build_meta.split(/-/, 2) + + a_core_parts = a_core.split('.') + b_core_parts = b_core.split('.') + + compare_core_parts(a_core_parts, b_core_parts) || + compare_pre_release_parts(a_pre, b_pre) || + pick_non_nil(a_pre, b_pre) || + compare_build_meta_parts(a_build_meta, b_build_meta) + end + + def compare_core_parts(a_core_parts, b_core_parts) + while a_core_parts.any? || b_core_parts.any? + a_part = a_core_parts.shift&.to_i || 0 + b_part = b_core_parts.shift&.to_i || 0 + return a_part <=> b_part if a_part != b_part + end + end + + def compare_pre_release_parts(a_pre, b_pre) + return unless a_pre && b_pre + + a_pre_parts = a_pre.split('.').map(&:downcase) + b_pre_parts = b_pre.split('.').map(&:downcase) + + while a_pre_parts.any? || b_pre_parts.any? + a_pre_part = a_pre_parts.shift + b_pre_part = b_pre_parts.shift + + # Empty parts are considered lower + return -1 if a_pre_part.nil? + return 1 if b_pre_part.nil? + + a_num = a_pre_part.to_i + b_num = b_pre_part.to_i + next if a_num == b_num && a_pre_part.to_s == b_pre_part.to_s # Both are same numeric/alphanumeric parts + + return select_numeric_before_alphanumeric(a_num, a_pre_part, b_num, b_pre_part) || + compare_numeric_parts(a_pre_part, a_num, b_pre_part, b_num) || + a_pre_part <=> b_pre_part + end + end + + def compare_build_meta_parts(a_build_meta, b_build_meta) + (a_build_meta || '').casecmp(b_build_meta || '') + end + + def select_numeric_before_alphanumeric(a_num, a_pre_part, b_num, b_pre_part) + return -1 if a_num != b_num && numeric?(a_pre_part) && !numeric?(b_pre_part) + return 1 if a_num != b_num && !numeric?(a_pre_part) && numeric?(b_pre_part) + end + + def numeric?(pre_part) + !!Integer(pre_part, exception: false) + end + + def compare_numeric_parts(a_pre_part, a_num, b_pre_part, b_num) + a_num <=> b_num if a_num != b_num && numeric?(a_pre_part) && numeric?(b_pre_part) + end + + def pick_non_nil(var_a, var_b) + return -1 if var_a && !var_b + return 1 if !var_a && var_b + end + end + end +end diff --git a/app/services/projects/lfs_pointers/lfs_import_service.rb b/app/services/projects/lfs_pointers/lfs_import_service.rb index c9791041088..95ddff45dff 100644 --- a/app/services/projects/lfs_pointers/lfs_import_service.rb +++ b/app/services/projects/lfs_pointers/lfs_import_service.rb @@ -14,7 +14,7 @@ module Projects end success - rescue StandardError => e + rescue StandardError, GRPC::Core::CallError => e error(e.message) end end diff --git a/app/views/devise/sessions/_new_base.html.haml b/app/views/devise/sessions/_new_base.html.haml index be93073f3d2..4825f192d4d 100644 --- a/app/views/devise/sessions/_new_base.html.haml +++ b/app/views/devise/sessions/_new_base.html.haml @@ -1,28 +1,27 @@ -= gitlab_ui_form_for(resource, as: resource_name, url: session_path(resource_name), html: { class: 'new_user gl-show-field-errors js-arkose-labs-form', aria: { live: 'assertive' }, data: { testid: 'sign-in-form' }}) do |f| - .form-group.gl-px-5.gl-pt-5 - = render_if_exists 'devise/sessions/new_base_user_login_label', form: f - = f.text_field :login, value: @invite_email, class: 'form-control gl-form-input top js-username-field', autofocus: 'autofocus', autocapitalize: 'off', autocorrect: 'off', required: true, title: _('This field is required.'), data: { qa_selector: 'login_field', testid: 'username-field' } - .form-group.gl-px-5 - = f.label :password, class: "label-bold #{'gl-mb-1' if Feature.enabled?(:restyle_login_page, @project)}" += gitlab_ui_form_for(resource, as: resource_name, url: session_path(resource_name), html: { class: 'gl-p-5 gl-show-field-errors js-arkose-labs-form', aria: { live: 'assertive' }, data: { testid: 'sign-in-form' }}) do |f| + .form-group + = f.label :login, _('Username or email') + = f.text_field :login, value: @invite_email, class: 'form-control gl-form-input js-username-field', autocomplete: 'username', autofocus: 'autofocus', autocapitalize: 'off', autocorrect: 'off', required: true, title: _('This field is required.'), data: { qa_selector: 'login_field', testid: 'username-field' } + .form-group + = f.label :password, _('Password') = f.password_field :password, class: 'form-control gl-form-input js-password', data: { id: "#{resource_name}_password", qa_selector: 'password_field', testid: 'password-field', name: "#{resource_name}[password]" } - .gl-px-5 - .gl-display-inline-block - - if remember_me_enabled? - = f.gitlab_ui_checkbox_component :remember_me, _('Remember me') - .gl-float-right + .form-text.gl-text-right - if unconfirmed_email? = link_to _('Resend confirmation email'), new_user_confirmation_path - else = link_to _('Forgot your password?'), new_password_path(:user) - %div + + .form-group - if Feature.enabled?(:arkose_labs_login_challenge) = render_if_exists 'devise/sessions/arkose_labs' - elsif captcha_enabled? || captcha_on_login_required? - .gl-px-5 - = recaptcha_tags nonce: content_security_policy_nonce + = recaptcha_tags nonce: content_security_policy_nonce + + - if remember_me_enabled? + = f.gitlab_ui_checkbox_component :remember_me, _('Remember me'), checkbox_options: { autocomplete: 'off' } - .submit-container.gl-px-5.gl-pb-5 - = f.button _('Sign in'), type: :submit, class: "gl-button btn btn-block btn-confirm js-sign-in-button#{' js-no-auto-disable' if Feature.enabled?(:arkose_labs_login_challenge)}", data: { qa_selector: 'sign_in_button', testid: 'sign-in-button' } + = render Pajamas::ButtonComponent.new(type: :submit, variant: :confirm, block: true, button_options: { class: "js-sign-in-button #{'js-no-auto-disable' if Feature.enabled?(:arkose_labs_login_challenge)}", data: { qa_selector: 'sign_in_button', testid: 'sign-in-button' } }) do + = _('Sign in') diff --git a/app/views/devise/sessions/_new_base_user_login_label.html.haml b/app/views/devise/sessions/_new_base_user_login_label.html.haml deleted file mode 100644 index 8a8b9f7a361..00000000000 --- a/app/views/devise/sessions/_new_base_user_login_label.html.haml +++ /dev/null @@ -1 +0,0 @@ -= local_assigns[:form].label _('Username or email'), for: 'user_login', class: "label-bold #{'gl-mb-1' if Feature.enabled?(:restyle_login_page, @project)}" |