diff options
Diffstat (limited to 'app')
23 files changed, 115 insertions, 57 deletions
diff --git a/app/assets/javascripts/notes/components/noteable_discussion.vue b/app/assets/javascripts/notes/components/noteable_discussion.vue index de9c695de2e..8e32c3b3073 100644 --- a/app/assets/javascripts/notes/components/noteable_discussion.vue +++ b/app/assets/javascripts/notes/components/noteable_discussion.vue @@ -223,17 +223,20 @@ export default { }) .catch((err) => { this.removePlaceholderNotes(); - const msg = __( - 'Your comment could not be submitted! Please check your network connection and try again.', - ); - createFlash({ - message: msg, - parent: this.$el, - }); + this.handleSaveError(err); // The 'err' parameter is being used in JH, don't remove it this.$refs.noteForm.note = noteText; callback(err); }); }, + handleSaveError() { + const msg = __( + 'Your comment could not be submitted! Please check your network connection and try again.', + ); + createFlash({ + message: msg, + parent: this.$el, + }); + }, deleteNoteHandler(note) { this.$emit('noteDeleted', this.discussion, note); }, diff --git a/app/assets/javascripts/notes/components/noteable_note.vue b/app/assets/javascripts/notes/components/noteable_note.vue index e74d4deeaec..3250a4818c7 100644 --- a/app/assets/javascripts/notes/components/noteable_note.vue +++ b/app/assets/javascripts/notes/components/noteable_note.vue @@ -331,17 +331,20 @@ export default { this.isEditing = true; this.setSelectedCommentPositionHover(); this.$nextTick(() => { - const msg = __('Something went wrong while editing your comment. Please try again.'); - createFlash({ - message: msg, - parent: this.$el, - }); + this.handleUpdateError(response); // The 'response' parameter is being used in JH, don't remove it this.recoverNoteContent(noteText); callback(); }); } }); }, + handleUpdateError() { + const msg = __('Something went wrong while editing your comment. Please try again.'); + createFlash({ + message: msg, + parent: this.$el, + }); + }, formCancelHandler({ shouldConfirm, isDirty }) { if (shouldConfirm && isDirty) { // eslint-disable-next-line no-alert diff --git a/app/assets/javascripts/repository/components/last_commit.vue b/app/assets/javascripts/repository/components/last_commit.vue index 62066973ee6..43e114a91d3 100644 --- a/app/assets/javascripts/repository/components/last_commit.vue +++ b/app/assets/javascripts/repository/components/last_commit.vue @@ -111,7 +111,7 @@ export default { </script> <template> - <div class="info-well d-none d-sm-flex project-last-commit commit p-3"> + <div class="well-segment commit gl-p-5 gl-w-full"> <gl-loading-icon v-if="isLoading" size="md" color="dark" class="m-auto" /> <template v-else-if="commit"> <user-avatar-link diff --git a/app/assets/javascripts/repository/index.js b/app/assets/javascripts/repository/index.js index 45e026ad695..197b19387cf 100644 --- a/app/assets/javascripts/repository/index.js +++ b/app/assets/javascripts/repository/index.js @@ -188,5 +188,5 @@ export default function setupVueRepositoryList() { }, }); - return { router, data: dataset }; + return { router, data: dataset, apolloProvider, projectPath }; } diff --git a/app/assets/javascripts/user_lists/components/add_user_modal.vue b/app/assets/javascripts/user_lists/components/add_user_modal.vue index a8dde1f681e..e982d10f63b 100644 --- a/app/assets/javascripts/user_lists/components/add_user_modal.vue +++ b/app/assets/javascripts/user_lists/components/add_user_modal.vue @@ -19,7 +19,7 @@ export default { modalOptions: { actionPrimary: { text: s__('UserLists|Add'), - attributes: [{ 'data-testid': 'confirm-add-user-ids' }], + attributes: [{ 'data-testid': 'confirm-add-user-ids', variant: 'confirm' }], }, actionCancel: { text: s__('UserLists|Cancel'), diff --git a/app/controllers/projects/forks_controller.rb b/app/controllers/projects/forks_controller.rb index 5154f145b46..ba83f8dad35 100644 --- a/app/controllers/projects/forks_controller.rb +++ b/app/controllers/projects/forks_controller.rb @@ -22,6 +22,8 @@ class Projects::ForksController < Projects::ApplicationController end def index + @sort = params[:sort] + @total_forks_count = project.forks.size @public_forks_count = project.forks.public_only.size @private_forks_count = @total_forks_count - project.forks.public_and_internal_only.size diff --git a/app/controllers/projects/google_cloud/service_accounts_controller.rb b/app/controllers/projects/google_cloud/service_accounts_controller.rb index d5db4fabf88..a69a744154c 100644 --- a/app/controllers/projects/google_cloud/service_accounts_controller.rb +++ b/app/controllers/projects/google_cloud/service_accounts_controller.rb @@ -54,7 +54,7 @@ class Projects::GoogleCloud::ServiceAccountsController < Projects::GoogleCloud:: return if is_token_valid - return_url = project_google_cloud_service_accounts_path(project) + return_url = project_google_cloud_index_path(project) state = generate_session_key_redirect(request.url, return_url) @authorize_url = GoogleApi::CloudPlatform::Client.new(nil, callback_google_api_auth_url, diff --git a/app/graphql/types/repository/blob_type.rb b/app/graphql/types/repository/blob_type.rb index cd4993ea86d..3265c14bdca 100644 --- a/app/graphql/types/repository/blob_type.rb +++ b/app/graphql/types/repository/blob_type.rb @@ -71,6 +71,10 @@ module Types field :pipeline_editor_path, GraphQL::Types::String, null: true, description: 'Web path to edit .gitlab-ci.yml file.' + field :code_owners, [Types::UserType], null: true, + description: 'List of code owners for the blob.', + calls_gitaly: true + field :file_type, GraphQL::Types::String, null: true, description: 'Expected format of the blob based on the extension.' @@ -104,3 +108,5 @@ module Types end end end + +Types::Repository::BlobType.prepend_mod_with('Types::Repository::BlobType') diff --git a/app/helpers/sorting_helper.rb b/app/helpers/sorting_helper.rb index b28e5ff39b2..fb30e8ca059 100644 --- a/app/helpers/sorting_helper.rb +++ b/app/helpers/sorting_helper.rb @@ -70,6 +70,15 @@ module SortingHelper options end + def forks_sort_options_hash + { + sort_value_recently_created => sort_title_created_date, + sort_value_oldest_created => sort_title_created_date, + sort_value_latest_activity => sort_title_latest_activity, + sort_value_oldest_activity => sort_title_latest_activity + } + end + def projects_sort_option_titles # Only used for the project filter search bar projects_sort_options_hash.merge({ @@ -93,6 +102,15 @@ module SortingHelper } end + def forks_reverse_sort_options_hash + { + sort_value_recently_created => sort_value_oldest_created, + sort_value_oldest_created => sort_value_recently_created, + sort_value_latest_activity => sort_value_oldest_activity, + sort_value_oldest_activity => sort_value_latest_activity + } + end + def groups_sort_options_hash { sort_value_name => sort_title_name, @@ -303,6 +321,13 @@ module SortingHelper sort_direction_button(url, reverse_sort, sort_value) end + + def forks_sort_direction_button(sort_value, without = [:state, :scope, :label_name, :milestone_id, :assignee_id, :author_id]) + reverse_sort = forks_reverse_sort_options_hash[sort_value] + url = page_filter_path(sort: reverse_sort, without: without) + + sort_direction_button(url, reverse_sort, sort_value) + end end SortingHelper.prepend_mod_with('SortingHelper') diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index e0126373864..7a2224c0dcf 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -190,8 +190,6 @@ module Ci scope :without_coverage, -> { where(coverage: nil) } scope :with_coverage_regex, -> { where.not(coverage_regex: nil) } - scope :for_project, -> (project_id) { where(project_id: project_id) } - acts_as_taggable add_authentication_token_field :token, encrypted: :required @@ -288,6 +286,7 @@ module Ci build.run_after_commit do BuildQueueWorker.perform_async(id) + BuildHooksWorker.perform_async(id) end end diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 6a924c1b576..edf1191e2ab 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -648,7 +648,7 @@ module Ci def coverage coverage_array = latest_statuses.map(&:coverage).compact if coverage_array.size >= 1 - '%.2f' % (coverage_array.reduce(:+) / coverage_array.size) + coverage_array.reduce(:+) / coverage_array.size end end diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb index d80b2fe37dc..9054a25fdb5 100644 --- a/app/models/commit_status.rb +++ b/app/models/commit_status.rb @@ -53,6 +53,7 @@ class CommitStatus < Ci::ApplicationRecord scope :before_stage, -> (index) { where('stage_idx < ?', index) } scope :for_stage, -> (index) { where(stage_idx: index) } scope :after_stage, -> (index) { where('stage_idx > ?', index) } + scope :for_project, -> (project_id) { where(project_id: project_id) } scope :for_ref, -> (ref) { where(ref: ref) } scope :by_name, -> (name) { where(name: name) } scope :in_pipelines, ->(pipelines) { where(pipeline: pipelines) } @@ -68,7 +69,8 @@ class CommitStatus < Ci::ApplicationRecord # Pluck is used to split this query. Splitting the query is required for database decomposition for `ci_*` tables. # https://docs.gitlab.com/ee/development/database/transaction_guidelines.html#database-decomposition-and-sharding project_ids = Project.where_full_path_in(Array(paths)).pluck(:id) - where(project: project_ids) + + for_project(project_ids) end scope :with_preloads, -> do diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 8bc4a9db20a..3e94043234e 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -1802,7 +1802,7 @@ class MergeRequest < ApplicationRecord def pipeline_coverage_delta if base_pipeline&.coverage && head_pipeline&.coverage - '%.2f' % (head_pipeline.coverage.to_f - base_pipeline.coverage.to_f) + head_pipeline.coverage - base_pipeline.coverage end end diff --git a/app/presenters/blob_presenter.rb b/app/presenters/blob_presenter.rb index 3555c6c3d0c..b310f8fff15 100644 --- a/app/presenters/blob_presenter.rb +++ b/app/presenters/blob_presenter.rb @@ -66,6 +66,11 @@ class BlobPresenter < Gitlab::View::Presenter::Delegated project_ci_pipeline_editor_path(project, branch_name: blob.commit_id) if can_collaborate_with_project?(project) && blob.path == project.ci_config_path_or_default end + # Will be overridden in EE + def code_owners + [] + end + def fork_and_edit_path fork_path_for_current_user(project, edit_blob_path) end @@ -147,3 +152,5 @@ class BlobPresenter < Gitlab::View::Presenter::Delegated blob.data end end + +BlobPresenter.prepend_mod_with('BlobPresenter') diff --git a/app/presenters/ci/pipeline_presenter.rb b/app/presenters/ci/pipeline_presenter.rb index e0cb899c9d3..00820e00863 100644 --- a/app/presenters/ci/pipeline_presenter.rb +++ b/app/presenters/ci/pipeline_presenter.rb @@ -62,6 +62,13 @@ module Ci localized_names.fetch(pipeline.merge_request_event_type, s_('Pipeline|Pipeline')) end + delegator_override :coverage + def coverage + return unless pipeline.coverage.present? + + '%.2f' % pipeline.coverage + end + def ref_text if pipeline.detached_merge_request_pipeline? _("for %{link_to_merge_request} with %{link_to_merge_request_source_branch}") diff --git a/app/presenters/merge_request_presenter.rb b/app/presenters/merge_request_presenter.rb index 380ed5d7bed..eeb94a8e657 100644 --- a/app/presenters/merge_request_presenter.rb +++ b/app/presenters/merge_request_presenter.rb @@ -254,6 +254,13 @@ class MergeRequestPresenter < Gitlab::View::Presenter::Delegated end end + delegator_override :pipeline_coverage_delta + def pipeline_coverage_delta + return unless merge_request.pipeline_coverage_delta.present? + + '%.2f' % merge_request.pipeline_coverage_delta + end + private def cached_can_be_reverted? diff --git a/app/serializers/ci/pipeline_entity.rb b/app/serializers/ci/pipeline_entity.rb index a5af543f49f..d97c92ce993 100644 --- a/app/serializers/ci/pipeline_entity.rb +++ b/app/serializers/ci/pipeline_entity.rb @@ -4,7 +4,7 @@ class Ci::PipelineEntity < Grape::Entity include RequestAwareEntity include Gitlab::Utils::StrongMemoize - delegate :name, :failure_reason, to: :presented_pipeline + delegate :name, :failure_reason, :coverage, to: :presented_pipeline expose :id expose :iid diff --git a/app/serializers/merge_requests/pipeline_entity.rb b/app/serializers/merge_requests/pipeline_entity.rb index bdf5cb160b2..f4fb01604d0 100644 --- a/app/serializers/merge_requests/pipeline_entity.rb +++ b/app/serializers/merge_requests/pipeline_entity.rb @@ -43,7 +43,9 @@ class MergeRequests::PipelineEntity < Grape::Entity # Coverage isn't always necessary (e.g. when displaying project pipelines in # the UI). Instead of creating an entirely different entity we just allow the # disabling of this specific field whenever necessary. - expose :coverage, unless: proc { options[:disable_coverage] } + expose :coverage, unless: proc { options[:disable_coverage] } do |pipeline| + pipeline.present.coverage + end expose :ref do expose :branch?, as: :branch diff --git a/app/services/projects/destroy_service.rb b/app/services/projects/destroy_service.rb index b7ed9202b01..3a9418f1dfa 100644 --- a/app/services/projects/destroy_service.rb +++ b/app/services/projects/destroy_service.rb @@ -150,7 +150,7 @@ module Projects ::Ci::DestroyPipelineService.new(project, current_user).execute(pipeline) end - deleted_count = project.commit_statuses.delete_all + deleted_count = ::CommitStatus.for_project(project).delete_all Gitlab::AppLogger.info( class: 'Projects::DestroyService', diff --git a/app/views/projects/_files.html.haml b/app/views/projects/_files.html.haml index cdcc98552f9..2f4a61865f8 100644 --- a/app/views/projects/_files.html.haml +++ b/app/views/projects/_files.html.haml @@ -10,10 +10,11 @@ .nav-block.gl-display-flex.gl-xs-flex-direction-column.gl-align-items-stretch = render 'projects/tree/tree_header', tree: @tree - #js-last-commit - .info-well.gl-display-none.gl-sm-display-flex.project-last-commit + .info-well.gl-display-none.gl-sm-display-flex.project-last-commit.gl-flex-direction-column + #js-last-commit.gl-m-auto .gl-spinner-container.m-auto = loading_icon(size: 'md', color: 'dark', css_class: 'align-text-bottom') + #js-code-owners - if is_project_overview .project-buttons.gl-mb-3.js-show-on-project-root diff --git a/app/views/projects/forks/index.html.haml b/app/views/projects/forks/index.html.haml index ba4e40a8675..d6f421e8ad6 100644 --- a/app/views/projects/forks/index.html.haml +++ b/app/views/projects/forks/index.html.haml @@ -1,40 +1,36 @@ +- sort_value = @sort || sort_value_recently_created +- sort_title = forks_sort_options_hash[sort_value] + .top-area .nav-text - full_count_title = "#{@public_forks_count} public, #{@internal_forks_count} internal, and #{@private_forks_count} private" #{pluralize(@total_forks_count, 'fork')}: #{full_count_title} - .nav-controls - = form_tag request.original_url, method: :get, class: 'project-filter-form', id: 'project-filter-form' do |f| - = search_field_tag :filter_projects, nil, placeholder: _('Search forks'), class: 'projects-list-filter project-filter-form-field form-control input-short', + .gl-display-flex.gl-sm-flex-direction-column.gl-md-align-items-center + = form_tag request.original_url, method: :get, class: 'project-filter-form gl-display-flex gl-mt-3 gl-md-mt-0', id: 'project-filter-form' do |f| + = search_field_tag :filter_projects, nil, placeholder: _('Search forks'), class: 'projects-list-filter project-filter-form-field form-control input-short gl-flex-grow-1', spellcheck: false, data: { 'filter-selector' => 'span.namespace-name' } - .dropdown - %button.dropdown-menu-toggle{ type: 'button', 'data-toggle' => 'dropdown' } - %span.light= _("sort:") - - if @sort.present? - = sort_options_hash[@sort] - - else - = sort_title_recently_created - = sprite_icon('chevron-down', css_class: 'dropdown-menu-toggle-icon gl-top-3') - %ul.dropdown-menu.dropdown-menu-right - %li - - excluded_filters = [:state, :scope, :label_name, :milestone_id, :assignee_id, :author_id] - = link_to page_filter_path(sort: sort_value_recently_created, without: excluded_filters) do - = sort_title_recently_created - = link_to page_filter_path(sort: sort_value_oldest_created, without: excluded_filters) do - = sort_title_oldest_created - = link_to page_filter_path(sort: sort_value_recently_updated, without: excluded_filters) do - = sort_title_recently_updated - = link_to page_filter_path(sort: sort_value_oldest_updated, without: excluded_filters) do - = sort_title_oldest_updated + .dropdown.gl-display-inline.gl-md-ml-3.issue-sort-dropdown.gl-mt-3.gl-md-mt-0 + .btn-group{ role: 'group' } + .btn-group{ role: 'group' } + %button.dropdown-menu-toggle{ type: 'button', data: { toggle: 'dropdown', display: 'static' }, class: 'gl-button btn btn-default' } + = sort_title + = sprite_icon('chevron-down', css_class: "dropdown-menu-toggle-icon gl-top-3") + %ul.dropdown-menu.dropdown-menu-right.dropdown-menu-selectable.dropdown-menu-sort + %li + - excluded_filters = [:state, :scope, :label_name, :milestone_id, :assignee_id, :author_id] + = sortable_item(sort_title_created_date, page_filter_path(sort: sort_value_recently_created, without: excluded_filters), sort_title) + = sortable_item(sort_title_latest_activity, page_filter_path(sort: sort_value_latest_activity, without: excluded_filters), sort_title) + = forks_sort_direction_button(sort_value) - if current_user && can?(current_user, :fork_project, @project) - if current_user.already_forked?(@project) && current_user.manageable_namespaces.size < 2 - = link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: _('Go to your fork'), class: 'btn gl-button btn-confirm' do + = link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: _('Go to your fork'), class: 'btn gl-button btn-confirm gl-md-ml-3' do = sprite_icon('fork', size: 12) %span= _('Fork') - else - = link_to new_project_fork_path(@project), title: _("Fork project"), class: 'btn gl-button btn-confirm' do + = link_to new_project_fork_path(@project), title: _("Fork project"), class: 'btn gl-button btn-confirm gl-md-ml-3 gl-mt-3 gl-md-mt-0' do = sprite_icon('fork', size: 12) %span= _('Fork') diff --git a/app/views/shared/_milestone_expired.html.haml b/app/views/shared/_milestone_expired.html.haml index 925344ab2f7..8c84f96932c 100644 --- a/app/views/shared/_milestone_expired.html.haml +++ b/app/views/shared/_milestone_expired.html.haml @@ -1,6 +1,6 @@ - if milestone.expired? && !milestone.closed? - .gl-badge.badge-warning.badge-pill.gl-mb-2= _('Expired') + = gl_badge_tag _('Expired'), { variant: :warning }, { class: "gl-mb-2" } - if milestone.upcoming? - .gl-badge.badge-primary.badge-pill.gl-mb-2= _('Upcoming') + = gl_badge_tag _('Upcoming'), { variant: :info }, { class: "gl-mb-2" } - if milestone.closed? - .gl-badge.badge-danger.badge-pill.gl-mb-2= _('Closed') + = gl_badge_tag _('Closed'), { variant: :danger }, { class: "gl-mb-2" } diff --git a/app/views/shared/milestones/_milestone.html.haml b/app/views/shared/milestones/_milestone.html.haml index 44934a12559..4e06b7902bd 100644 --- a/app/views/shared/milestones/_milestone.html.haml +++ b/app/views/shared/milestones/_milestone.html.haml @@ -33,11 +33,9 @@ %div = render('shared/milestone_expired', milestone: milestone) - if milestone.group_milestone? - .gl-badge.badge-info.badge-pill - = milestone.group.full_name + = gl_badge_tag milestone.group.full_name, variant: :info - if milestone.project_milestone? - .gl-badge.badge-muted.badge-pill - = milestone.project.full_name + = gl_badge_tag milestone.project.full_name, variant: :muted .col-sm-4.milestone-progress = milestone_progress_bar(milestone) |