diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-10-07 03:09:20 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-10-07 03:09:20 +0300 |
commit | fa5ca3519ed27787cb302f0c62f791def0834038 (patch) | |
tree | d35965a17156eab4f62e53f8e9ca37e878e72e08 /app | |
parent | 87598f1576cc7b3e1071a83d70778a51009b853b (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r-- | app/graphql/mutations/customer_relations/contacts/create.rb | 69 | ||||
-rw-r--r-- | app/graphql/types/mutation_type.rb | 1 | ||||
-rw-r--r-- | app/models/project_setting.rb | 4 | ||||
-rw-r--r-- | app/policies/group_policy.rb | 3 | ||||
-rw-r--r-- | app/serializers/merge_request_metrics_helper.rb | 28 | ||||
-rw-r--r-- | app/serializers/merge_request_poll_cached_widget_entity.rb | 25 | ||||
-rw-r--r-- | app/services/customer_relations/contacts/base_service.rb | 17 | ||||
-rw-r--r-- | app/services/customer_relations/contacts/create_service.rb | 41 | ||||
-rw-r--r-- | app/services/customer_relations/organizations/base_service.rb | 2 | ||||
-rw-r--r-- | app/services/customer_relations/organizations/create_service.rb | 4 | ||||
-rw-r--r-- | app/views/shared/builds/_tabs.html.haml | 41 |
11 files changed, 180 insertions, 55 deletions
diff --git a/app/graphql/mutations/customer_relations/contacts/create.rb b/app/graphql/mutations/customer_relations/contacts/create.rb new file mode 100644 index 00000000000..43f44637042 --- /dev/null +++ b/app/graphql/mutations/customer_relations/contacts/create.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +module Mutations + module CustomerRelations + module Contacts + class Create < BaseMutation + include ResolvesIds + include Gitlab::Graphql::Authorize::AuthorizeResource + + graphql_name 'CustomerRelationsContactCreate' + + field :contact, + Types::CustomerRelations::ContactType, + null: true, + description: 'Contact after the mutation.' + + argument :group_id, ::Types::GlobalIDType[::Group], + required: true, + description: 'Group for the contact.' + + argument :organization_id, ::Types::GlobalIDType[::CustomerRelations::Organization], + required: false, + description: 'Organization for the contact.' + + argument :first_name, GraphQL::Types::String, + required: true, + description: 'First name of the contact.' + + argument :last_name, GraphQL::Types::String, + required: true, + description: 'Last name of the contact.' + + argument :phone, GraphQL::Types::String, + required: false, + description: 'Phone number of the contact.' + + argument :email, GraphQL::Types::String, + required: false, + description: 'Email address of the contact.' + + argument :description, GraphQL::Types::String, + required: false, + description: 'Description or notes for the contact.' + + authorize :admin_contact + + def resolve(args) + group = authorized_find!(id: args[:group_id]) + + raise Gitlab::Graphql::Errors::ResourceNotAvailable, 'Feature disabled' unless Feature.enabled?(:customer_relations, group, default_enabled: :yaml) + + set_organization!(args) + result = ::CustomerRelations::Contacts::CreateService.new(group: group, current_user: current_user, params: args).execute + { contact: result.payload, errors: result.errors } + end + + def find_object(id:) + GitlabSchema.object_from_id(id, expected_type: ::Group) + end + + def set_organization!(args) + return unless args[:organization_id] + + args[:organization_id] = resolve_ids(args[:organization_id], ::Types::GlobalIDType[::CustomerRelations::Organization])[0] + end + end + end + end +end diff --git a/app/graphql/types/mutation_type.rb b/app/graphql/types/mutation_type.rb index a3be4fcba92..9d4078f873a 100644 --- a/app/graphql/types/mutation_type.rb +++ b/app/graphql/types/mutation_type.rb @@ -38,6 +38,7 @@ module Types mount_mutation Mutations::Commits::Create, calls_gitaly: true mount_mutation Mutations::CustomEmoji::Create, feature_flag: :custom_emoji mount_mutation Mutations::CustomEmoji::Destroy, feature_flag: :custom_emoji + mount_mutation Mutations::CustomerRelations::Contacts::Create mount_mutation Mutations::CustomerRelations::Organizations::Create mount_mutation Mutations::CustomerRelations::Organizations::Update mount_mutation Mutations::Discussions::ToggleResolve diff --git a/app/models/project_setting.rb b/app/models/project_setting.rb index b2559636f32..24d892290a6 100644 --- a/app/models/project_setting.rb +++ b/app/models/project_setting.rb @@ -1,10 +1,6 @@ # frozen_string_literal: true class ProjectSetting < ApplicationRecord - include IgnorableColumns - - ignore_column :allow_editing_commit_messages, remove_with: '14.4', remove_after: '2021-09-10' - belongs_to :project, inverse_of: :project_setting enum squash_option: { diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb index 7abffd2c352..ac8165dfd27 100644 --- a/app/policies/group_policy.rb +++ b/app/policies/group_policy.rb @@ -134,6 +134,8 @@ class GroupPolicy < BasePolicy enable :create_package enable :create_package_settings enable :developer_access + enable :admin_organization + enable :admin_contact end rule { reporter }.policy do @@ -147,7 +149,6 @@ class GroupPolicy < BasePolicy enable :read_prometheus enable :read_package enable :read_package_settings - enable :admin_organization end rule { maintainer }.policy do diff --git a/app/serializers/merge_request_metrics_helper.rb b/app/serializers/merge_request_metrics_helper.rb new file mode 100644 index 00000000000..fb1769d0aa6 --- /dev/null +++ b/app/serializers/merge_request_metrics_helper.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module MergeRequestMetricsHelper + # There are cases where where metrics object doesn't exist and it needs to be rebuilt. + # TODO: Once https://gitlab.com/gitlab-org/gitlab/-/issues/342508 has been resolved and + # all merge requests have metrics we can remove this helper method. + def build_metrics(merge_request) + # There's no need to query and serialize metrics data for merge requests that are not + # merged or closed. + return unless merge_request.merged? || merge_request.closed? + return merge_request.metrics if merge_request.merged? && merge_request.metrics&.merged_by_id + return merge_request.metrics if merge_request.closed? && merge_request.metrics&.latest_closed_by_id + + build_metrics_from_events(merge_request) + end + + private + + def build_metrics_from_events(merge_request) + closed_event = merge_request.closed_event + merge_event = merge_request.merge_event + + MergeRequest::Metrics.new(latest_closed_at: closed_event&.updated_at, + latest_closed_by: closed_event&.author, + merged_at: merge_event&.updated_at, + merged_by: merge_event&.author) + end +end diff --git a/app/serializers/merge_request_poll_cached_widget_entity.rb b/app/serializers/merge_request_poll_cached_widget_entity.rb index 7fba52cbe17..8b0f3c8eb74 100644 --- a/app/serializers/merge_request_poll_cached_widget_entity.rb +++ b/app/serializers/merge_request_poll_cached_widget_entity.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true class MergeRequestPollCachedWidgetEntity < IssuableEntity + include MergeRequestMetricsHelper + expose :auto_merge_enabled expose :state expose :merged_commit_sha @@ -158,29 +160,6 @@ class MergeRequestPollCachedWidgetEntity < IssuableEntity @presenters ||= {} @presenters[merge_request] ||= MergeRequestPresenter.new(merge_request, current_user: current_user) # rubocop: disable CodeReuse/Presenter end - - # Once SchedulePopulateMergeRequestMetricsWithEventsData fully runs, - # we can remove this method and just serialize MergeRequest#metrics - # instead. See https://gitlab.com/gitlab-org/gitlab-foss/issues/41587 - def build_metrics(merge_request) - # There's no need to query and serialize metrics data for merge requests that are not - # merged or closed. - return unless merge_request.merged? || merge_request.closed? - return merge_request.metrics if merge_request.merged? && merge_request.metrics&.merged_by_id - return merge_request.metrics if merge_request.closed? && merge_request.metrics&.latest_closed_by_id - - build_metrics_from_events(merge_request) - end - - def build_metrics_from_events(merge_request) - closed_event = merge_request.closed_event - merge_event = merge_request.merge_event - - MergeRequest::Metrics.new(latest_closed_at: closed_event&.updated_at, - latest_closed_by: closed_event&.author, - merged_at: merge_event&.updated_at, - merged_by: merge_event&.author) - end end MergeRequestPollCachedWidgetEntity.prepend_mod_with('MergeRequestPollCachedWidgetEntity') diff --git a/app/services/customer_relations/contacts/base_service.rb b/app/services/customer_relations/contacts/base_service.rb new file mode 100644 index 00000000000..89f6f2c3f1f --- /dev/null +++ b/app/services/customer_relations/contacts/base_service.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module CustomerRelations + module Contacts + class BaseService < ::BaseGroupService + private + + def allowed? + current_user&.can?(:admin_contact, group) + end + + def error(message) + ServiceResponse.error(message: Array(message)) + end + end + end +end diff --git a/app/services/customer_relations/contacts/create_service.rb b/app/services/customer_relations/contacts/create_service.rb new file mode 100644 index 00000000000..7ff8b731e0d --- /dev/null +++ b/app/services/customer_relations/contacts/create_service.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +module CustomerRelations + module Contacts + class CreateService < BaseService + def execute + return error_no_permissions unless allowed? + return error_organization_invalid unless organization_valid? + + contact = Contact.create(params.merge(group_id: group.id)) + + return error_creating(contact) unless contact.persisted? + + ServiceResponse.success(payload: contact) + end + + private + + def organization_valid? + return true unless params[:organization_id] + + organization = Organization.find(params[:organization_id]) + organization.group_id == group.id + rescue ActiveRecord::RecordNotFound + false + end + + def error_organization_invalid + error('The specified organization was not found or does not belong to this group') + end + + def error_no_permissions + error('You have insufficient permissions to create a contact for this group') + end + + def error_creating(contact) + error(contact&.errors&.full_messages || 'Failed to create contact') + end + end + end +end diff --git a/app/services/customer_relations/organizations/base_service.rb b/app/services/customer_relations/organizations/base_service.rb index 63261534b37..8f8480d697c 100644 --- a/app/services/customer_relations/organizations/base_service.rb +++ b/app/services/customer_relations/organizations/base_service.rb @@ -10,7 +10,7 @@ module CustomerRelations end def error(message) - ServiceResponse.error(message: message) + ServiceResponse.error(message: Array(message)) end end end diff --git a/app/services/customer_relations/organizations/create_service.rb b/app/services/customer_relations/organizations/create_service.rb index 9c223796eaf..aad1b7e2ca4 100644 --- a/app/services/customer_relations/organizations/create_service.rb +++ b/app/services/customer_relations/organizations/create_service.rb @@ -7,9 +7,7 @@ module CustomerRelations def execute return error_no_permissions unless allowed? - params[:group_id] = group.id - - organization = Organization.create(params) + organization = Organization.create(params.merge(group_id: group.id)) return error_creating(organization) unless organization.persisted? diff --git a/app/views/shared/builds/_tabs.html.haml b/app/views/shared/builds/_tabs.html.haml index 4973309edf5..498e9cc33ce 100644 --- a/app/views/shared/builds/_tabs.html.haml +++ b/app/views/shared/builds/_tabs.html.haml @@ -1,24 +1,19 @@ -%ul.nav-links.mobile-separator.nav.nav-tabs - %li{ class: active_when(scope.nil?) }> - = link_to build_path_proc.call(nil) do - All - %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm.js-totalbuilds-count - = limited_counter_with_delimiter(all_builds) +- count_badge_classes = 'badge badge-muted badge-pill gl-badge gl-tab-counter-badge sm gl-display-none gl-sm-display-inline-flex' - %li{ class: active_when(scope == 'pending') }> - = link_to build_path_proc.call('pending') do - Pending - %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm - = limited_counter_with_delimiter(all_builds.pending) - - %li{ class: active_when(scope == 'running') }> - = link_to build_path_proc.call('running') do - Running - %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm - = limited_counter_with_delimiter(all_builds.running) - - %li{ class: active_when(scope == 'finished') }> - = link_to build_path_proc.call('finished') do - Finished - %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm - = limited_counter_with_delimiter(all_builds.finished) += gl_tabs_nav( {class: 'gl-border-b-0 gl-flex-grow-1', data: { testid: 'jobs-tabs' } } ) do + = gl_tab_link_to build_path_proc.call(nil), { item_active: scope.nil? } do + = _('All') + %span{ class: count_badge_classes } + = limited_counter_with_delimiter(all_builds) + = gl_tab_link_to build_path_proc.call('pending'), { item_active: scope == 'pending' } do + = _('Pending') + %span{ class: count_badge_classes } + = limited_counter_with_delimiter(all_builds.pending) + = gl_tab_link_to build_path_proc.call('running'), { item_active: scope == 'running' } do + = _('Running') + %span{ class: count_badge_classes } + = limited_counter_with_delimiter(all_builds.running) + = gl_tab_link_to build_path_proc.call('finished'), { item_active: scope == 'finished' } do + = _('Finished') + %span{ class: count_badge_classes } + = limited_counter_with_delimiter(all_builds.finished) |