Commit 85a6cb60 authored by Douwe Maan's avatar Douwe Maan

Merge branch '10556-support-adding-an-epics-to-a-parent-using-quick-action' into 'master'

Quick actions for adding/removing epic parent relations

Closes #10556

See merge request gitlab-org/gitlab-ee!14451
parents d6da4a25 cbaf9438
---
title: Add Quick Actions for adding/removing epic parent relations
merge_request: 14451
author:
type: added
......@@ -42,6 +42,37 @@ module EE
end
end
desc _('Set parent epic to an epic')
explanation do |epic_param|
parent_epic = extract_epic(epic_param)
_("Sets %{epic_ref} as parent epic.") % { epic_ref: parent_epic.to_reference(quick_action_target) } if parent_epic
end
types Epic
condition { action_allowed? }
params '<&epic | group&epic | Epic URL>'
command :parent_epic do |epic_param|
parent_epic = extract_epic(epic_param)
if parent_epic && !parent_epic.child?(quick_action_target.id)
EpicLinks::CreateService.new(parent_epic, current_user, { target_issuable: quick_action_target }).execute
end
end
desc _('Remove parent epic from an epic')
explanation do
parent_epic = quick_action_target.parent
_('Removes parent epic %{epic_ref}.') % { epic_ref: parent_epic.to_reference(quick_action_target) }
end
types Epic
condition do
action_allowed? && quick_action_target.parent.present?
end
command :remove_parent_epic do
EpicLinks::DestroyService.new(quick_action_target, current_user).execute
end
private
def extract_epic(params)
......
......@@ -96,13 +96,18 @@ describe Groups::AutocompleteService do
describe '#commands' do
context 'when target is an epic' do
let(:parent_epic) { create(:epic, group: group, author: user) }
let(:epic) { create(:epic, group: group, author: user, parent: parent_epic) }
before do
stub_licensed_features(epics: true)
end
it 'returns available commands' do
available_commands = [:todo, :unsubscribe, :award, :shrug, :tableflip, :cc, :title, :close]
available_commands += [:child_epic, :remove_child_epic] if ::Epic.supports_nested_objects?
if ::Epic.supports_nested_objects?
available_commands += [:child_epic, :remove_child_epic, :parent_epic, :remove_parent_epic]
end
expect(subject.commands(epic).map { |c| c[:name] }).to match_array(available_commands)
end
......
......@@ -519,7 +519,7 @@ describe QuickActions::InterpretService do
end
end
context 'when child and paretn epics are in different groups' do
context 'when child and parent epics are in different groups' do
let(:child_epic) { create(:epic, group: group, parent: epic) }
context 'when child epic is in a parent group of the parent epic' do
before do
......@@ -591,7 +591,7 @@ describe QuickActions::InterpretService do
end
context 'when a user does not have permissions to label an epic' do
it 'does not populate any lables' do
it 'does not populate any labels' do
_, updates = service.execute(content, epic)
expect(updates).to be_empty
......@@ -600,7 +600,7 @@ describe QuickActions::InterpretService do
end
context 'when epics are disabled' do
it 'does not populate any lables' do
it 'does not populate any labels' do
group.add_developer(current_user)
_, updates = service.execute(content, epic)
......@@ -913,25 +913,27 @@ describe QuickActions::InterpretService do
context 'epic commands' do
let(:epic) { create(:epic, group: group) }
let(:child_epic) { create(:epic, group: group) }
let(:epic2) { create(:epic, group: group) }
before do
stub_licensed_features(epics: true)
group.add_developer(current_user)
end
context 'child_epic command', :nested_groups do
shared_examples 'adds epic relation' do |relation|
context 'when correct epic reference' do
let(:content) { "/child_epic #{child_epic&.to_reference(epic)}" }
let(:content) { "/#{relation}_epic #{epic2&.to_reference(epic)}" }
let(:action) { relation == :child ? 'Adds' : 'Sets'}
it 'returns message with epic reference' do
_, explanations = service.explain(content, epic)
expect(explanations).to eq(["Adds #{child_epic.group.name}&#{child_epic.iid} as child epic."])
expect(explanations)
.to eq(["#{action} #{epic2.group.name}&#{epic2.iid} as #{relation} epic."])
end
end
context 'when epic reference is wrong' do
let(:content) { "/child_epic qwe" }
context 'when epic reference is wrong' do |relation|
let(:content) { "/#{relation}_epic qwe" }
it 'returns empty explain message' do
_, explanations = service.explain(content, epic)
......@@ -940,13 +942,17 @@ describe QuickActions::InterpretService do
end
end
context 'remove_child_epic command', :nested_groups do
context 'child_epic command' do
it_behaves_like 'adds epic relation', :child
end
context 'remove_child_epic command' do
context 'when correct epic reference' do
let(:content) { "/remove_child_epic #{child_epic&.to_reference(epic)}" }
let(:content) { "/remove_child_epic #{epic2&.to_reference(epic)}" }
it 'returns message with epic reference' do
_, explanations = service.explain(content, epic)
expect(explanations).to eq(["Removes #{child_epic.group.name}&#{child_epic.iid} from child epics."])
expect(explanations).to eq(["Removes #{epic2.group.name}&#{epic2.iid} from child epics."])
end
end
......@@ -959,6 +965,34 @@ describe QuickActions::InterpretService do
end
end
end
context 'parent_epic command' do
it_behaves_like 'adds epic relation', :parent
end
context 'remove_parent_epic command' do
context 'when parent is present' do
before do
epic.parent = epic2
end
it 'returns message with epic reference' do
_, explanations = service.explain("/remove_parent_epic", epic)
expect(explanations).to eq(["Removes parent epic #{epic2.group.name}&#{epic2.iid}."])
end
end
context 'when parent is not present' do
before do
epic.parent = nil
end
it 'returns empty explain message' do
_, explanations = service.explain("/remove_parent_epic", epic)
expect(explanations).to eq([])
end
end
end
end
end
end
......@@ -11377,6 +11377,9 @@ msgstr ""
msgid "Remove milestone"
msgstr ""
msgid "Remove parent epic from an epic"
msgstr ""
msgid "Remove priority"
msgstr ""
......@@ -11410,6 +11413,9 @@ msgstr ""
msgid "Removes all labels."
msgstr ""
msgid "Removes parent epic %{epic_ref}."
msgstr ""
msgid "Removes spent time."
msgstr ""
......@@ -12337,6 +12343,9 @@ msgstr ""
msgid "Set notification email for abuse reports."
msgstr ""
msgid "Set parent epic to an epic"
msgstr ""
msgid "Set requirements for a user to sign-in. Enable mandatory two-factor authentication."
msgstr ""
......@@ -12406,6 +12415,9 @@ msgstr ""
msgid "SetStatusModal|What's your status?"
msgstr ""
msgid "Sets %{epic_ref} as parent epic."
msgstr ""
msgid "Sets the due date to %{due_date}."
msgstr ""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment