diff options
Diffstat (limited to 'app/services/work_items')
10 files changed, 89 insertions, 40 deletions
diff --git a/app/services/work_items/create_and_link_service.rb b/app/services/work_items/create_and_link_service.rb index 6a773a84225..5cc358c4b4f 100644 --- a/app/services/work_items/create_and_link_service.rb +++ b/app/services/work_items/create_and_link_service.rb @@ -7,19 +7,20 @@ module WorkItems # new work items that were never associated with other work items as expected. class CreateAndLinkService def initialize(project:, current_user: nil, params: {}, spam_params:, link_params: {}) - @create_service = CreateService.new( - project: project, - current_user: current_user, - params: params, - spam_params: spam_params - ) @project = project @current_user = current_user + @params = params @link_params = link_params + @spam_params = spam_params end def execute - create_result = @create_service.execute + create_result = CreateService.new( + project: @project, + current_user: @current_user, + params: @params.merge(title: @params[:title].strip).reverse_merge(confidential: confidential_parent), + spam_params: @spam_params + ).execute return create_result if create_result.error? work_item = create_result[:work_item] @@ -40,6 +41,10 @@ module WorkItems private + def confidential_parent + !!@link_params[:parent_work_item]&.confidential + end + def payload(work_item) { work_item: work_item } end diff --git a/app/services/work_items/parent_links/create_service.rb b/app/services/work_items/parent_links/create_service.rb index 9940776e367..e7906f1fcdd 100644 --- a/app/services/work_items/parent_links/create_service.rb +++ b/app/services/work_items/parent_links/create_service.rb @@ -41,10 +41,8 @@ module WorkItems params[:issuable_references] end - # TODO: Create system notes when work item's parent or children are updated - # See https://gitlab.com/gitlab-org/gitlab/-/issues/362213 def create_notes(work_item) - # no-op + SystemNoteService.relate_work_item(issuable, work_item, current_user) end def target_issuable_type diff --git a/app/services/work_items/parent_links/destroy_service.rb b/app/services/work_items/parent_links/destroy_service.rb index 55870d44db9..19770b3e4b5 100644 --- a/app/services/work_items/parent_links/destroy_service.rb +++ b/app/services/work_items/parent_links/destroy_service.rb @@ -14,10 +14,8 @@ module WorkItems private - # TODO: Create system notes when work item's parent or children are removed - # See https://gitlab.com/gitlab-org/gitlab/-/issues/362213 def create_notes - # no-op + SystemNoteService.unrelate_work_item(parent, child, current_user) end def not_found_message diff --git a/app/services/work_items/update_service.rb b/app/services/work_items/update_service.rb index 98818fda263..2deb8c82741 100644 --- a/app/services/work_items/update_service.rb +++ b/app/services/work_items/update_service.rb @@ -26,8 +26,8 @@ module WorkItems private - def update(work_item) - execute_widgets(work_item: work_item, callback: :update, widget_params: @widget_params) + def before_update(work_item, skip_spam_check: false) + execute_widgets(work_item: work_item, callback: :before_update_callback, widget_params: @widget_params) super end diff --git a/app/services/work_items/widgets/assignees_service/update_service.rb b/app/services/work_items/widgets/assignees_service/update_service.rb new file mode 100644 index 00000000000..9176b71c85e --- /dev/null +++ b/app/services/work_items/widgets/assignees_service/update_service.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module WorkItems + module Widgets + module AssigneesService + class UpdateService < WorkItems::Widgets::BaseService + def before_update_in_transaction(params:) + return unless params.present? && params.has_key?(:assignee_ids) + return unless has_permission?(:set_work_item_metadata) + + assignee_ids = filter_assignees_count(params[:assignee_ids]) + assignee_ids = filter_assignee_permissions(assignee_ids) + + return if assignee_ids.sort == work_item.assignee_ids.sort + + work_item.assignee_ids = assignee_ids + work_item.touch + end + + private + + def filter_assignees_count(assignee_ids) + return assignee_ids if work_item.allows_multiple_assignees? + + assignee_ids.first(1) + end + + def filter_assignee_permissions(assignee_ids) + assignees = User.id_in(assignee_ids) + + assignees.select { |assignee| assignee.can?(:read_work_item, work_item) }.map(&:id) + end + end + end + end +end diff --git a/app/services/work_items/widgets/base_service.rb b/app/services/work_items/widgets/base_service.rb index 037733bbed5..37ed2bf4b05 100644 --- a/app/services/work_items/widgets/base_service.rb +++ b/app/services/work_items/widgets/base_service.rb @@ -5,12 +5,19 @@ module WorkItems class BaseService < ::BaseService WidgetError = Class.new(StandardError) - attr_reader :widget, :current_user + attr_reader :widget, :work_item, :current_user def initialize(widget:, current_user:) @widget = widget + @work_item = widget.work_item @current_user = current_user end + + private + + def has_permission?(permission) + can?(current_user, permission, widget.work_item) + end end end end diff --git a/app/services/work_items/widgets/description_service/update_service.rb b/app/services/work_items/widgets/description_service/update_service.rb index e63b6b2ee6c..fe591ba605e 100644 --- a/app/services/work_items/widgets/description_service/update_service.rb +++ b/app/services/work_items/widgets/description_service/update_service.rb @@ -4,10 +4,12 @@ module WorkItems module Widgets module DescriptionService class UpdateService < WorkItems::Widgets::BaseService - def update(params: {}) - return unless params.present? && params[:description] + def before_update_callback(params: {}) + return unless params.present? && params.key?(:description) + return unless has_permission?(:update_work_item) - widget.work_item.description = params[:description] + work_item.description = params[:description] + work_item.assign_attributes(last_edited_at: Time.current, last_edited_by: current_user) end end end diff --git a/app/services/work_items/widgets/hierarchy_service/base_service.rb b/app/services/work_items/widgets/hierarchy_service/base_service.rb index 085d6c6b0e7..bb681ef0083 100644 --- a/app/services/work_items/widgets/hierarchy_service/base_service.rb +++ b/app/services/work_items/widgets/hierarchy_service/base_service.rb @@ -15,7 +15,7 @@ module WorkItems elsif params.key?(:children) update_work_item_children(params.delete(:children)) else - invalid_args_error + invalid_args_error(params) end end @@ -29,13 +29,13 @@ module WorkItems def set_parent(parent) ::WorkItems::ParentLinks::CreateService - .new(parent, current_user, { target_issuable: widget.work_item }) + .new(parent, current_user, { target_issuable: work_item }) .execute end # rubocop: disable CodeReuse/ActiveRecord def remove_parent - link = ::WorkItems::ParentLink.find_by(work_item: widget.work_item) + link = ::WorkItems::ParentLink.find_by(work_item: work_item) return success unless link.present? ::WorkItems::ParentLinks::DestroyService.new(link, current_user).execute @@ -44,12 +44,12 @@ module WorkItems def update_work_item_children(children) ::WorkItems::ParentLinks::CreateService - .new(widget.work_item, current_user, { issuable_references: children }) + .new(work_item, current_user, { issuable_references: children }) .execute end def feature_flag_enabled? - Feature.enabled?(:work_items_hierarchy, widget.work_item&.project) + Feature.enabled?(:work_items_hierarchy, work_item&.project) end def incompatible_args?(params) @@ -64,11 +64,14 @@ module WorkItems error(_('A Work Item can be a parent or a child, but not both.')) end - def invalid_args_error + def invalid_args_error(params) error(_("One or more arguments are invalid: %{args}." % { args: params.keys.to_sentence } )) end def service_response!(result) + work_item.reload_work_item_parent + work_item.work_item_children.reset + return result unless result[:status] == :error raise WidgetError, result[:message] diff --git a/app/services/work_items/widgets/start_and_due_date_service/update_service.rb b/app/services/work_items/widgets/start_and_due_date_service/update_service.rb new file mode 100644 index 00000000000..6a5dc0d5ef3 --- /dev/null +++ b/app/services/work_items/widgets/start_and_due_date_service/update_service.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module WorkItems + module Widgets + module StartAndDueDateService + class UpdateService < WorkItems::Widgets::BaseService + def before_update_callback(params: {}) + return if params.blank? + + widget.work_item.assign_attributes(params.slice(:start_date, :due_date)) + end + end + end + end +end diff --git a/app/services/work_items/widgets/weight_service/update_service.rb b/app/services/work_items/widgets/weight_service/update_service.rb deleted file mode 100644 index cd62a25358f..00000000000 --- a/app/services/work_items/widgets/weight_service/update_service.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true - -module WorkItems - module Widgets - module WeightService - class UpdateService < WorkItems::Widgets::BaseService - def update(params: {}) - return unless params.present? && params[:weight] - - widget.work_item.weight = params[:weight] - end - end - end - end -end |