diff options
Diffstat (limited to 'lib/gitlab/quick_actions/work_item_actions.rb')
-rw-r--r-- | lib/gitlab/quick_actions/work_item_actions.rb | 90 |
1 files changed, 71 insertions, 19 deletions
diff --git a/lib/gitlab/quick_actions/work_item_actions.rb b/lib/gitlab/quick_actions/work_item_actions.rb index fa43308c9e2..5664410f3ca 100644 --- a/lib/gitlab/quick_actions/work_item_actions.rb +++ b/lib/gitlab/quick_actions/work_item_actions.rb @@ -12,42 +12,94 @@ module Gitlab format(_("Converts work item to %{type}. Widgets not supported in new type are removed."), type: target_type) end types WorkItem - condition do - quick_action_target&.project&.work_items_mvc_2_feature_flag_enabled? - end params 'Task | Objective | Key Result | Issue' command :type do |type_name| - work_item_type = ::WorkItems::Type.find_by_name(type_name) - errors = validate_type(work_item_type) - - if errors.present? - @execution_message[:type] = errors - else - @updates[:issue_type] = work_item_type.base_type - @updates[:work_item_type] = work_item_type - @execution_message[:type] = _('Type changed successfully.') - end + @execution_message[:type] = update_type(type_name, :type) + end + + desc { _('Promote work item') } + explanation do |type_name| + format(_("Promotes work item to %{type}."), type: type_name) + end + types WorkItem + params 'issue | objective' + condition { supports_promotion? } + command :promote_to do |type_name| + @execution_message[:promote_to] = update_type(type_name, :promote_to) end end private + # rubocop:disable Gitlab/ModuleWithInstanceVariables + def update_type(type_name, command) + new_type = ::WorkItems::Type.find_by_name(type_name.titleize) + error_message = command == :type ? validate_type(new_type) : validate_promote_to(new_type) + return error_message if error_message.present? + + @updates[:issue_type] = new_type.base_type + @updates[:work_item_type] = new_type + + success_msg[command] + end + # rubocop:enable Gitlab/ModuleWithInstanceVariables + def validate_type(type) - return type_error(:not_found) unless type.present? - return type_error(:same_type) if quick_action_target.work_item_type == type - return type_error(:forbidden) unless current_user.can?(:"create_#{type.base_type}", quick_action_target) + return error_msg(:not_found) unless type.present? + return error_msg(:same_type) if quick_action_target.work_item_type == type + return error_msg(:forbidden) unless current_user.can?(:"create_#{type.base_type}", quick_action_target) nil end - def type_error(reason) + def validate_promote_to(type) + return error_msg(:not_found, action: 'promote') unless type && supports_promote_to?(type.name) + + unless current_user.can?(:"create_#{type.base_type}", quick_action_target) + return error_msg(:forbidden, action: 'promote') + end + + validate_hierarchy + end + + def validate_hierarchy + return unless current_type.task? && quick_action_target.parent_link + + error_msg(:hierarchy, action: 'promote') + end + + def current_type + quick_action_target.work_item_type + end + + def supports_promotion? + current_type.base_type.in?(promote_to_map.keys) + end + + def supports_promote_to?(type_name) + type_name == promote_to_map[current_type.base_type] + end + + def promote_to_map + { issue: 'Incident', task: 'Issue' }.with_indifferent_access + end + + def error_msg(reason, action: 'convert') message = { not_found: 'Provided type is not supported', same_type: 'Types are the same', - forbidden: 'You have insufficient permissions' + forbidden: 'You have insufficient permissions', + hierarchy: 'A task cannot be promoted when a parent issue is present' }.freeze - format(_("Failed to convert this work item: %{reason}."), { reason: message[reason] }) + format(_("Failed to %{action} this work item: %{reason}."), { action: action, reason: message[reason] }) + end + + def success_msg + { + type: _('Type changed successfully.'), + promote_to: _("Work Item promoted successfully.") + } end end end |