Commit eadc6f28 authored by Paul Slaughter's avatar Paul Slaughter

Merge branch '229507-graphql-mutation-to-remove-issue-from-board' into 'master'

Remove Remove from board button from board sidebar [RUN ALL RSPEC] [RUN AS-IF-FOSS]

See merge request gitlab-org/gitlab!53946
parents e9ccfaff 05a8a521
......@@ -20,7 +20,6 @@ import Subscriptions from '~/sidebar/components/subscriptions/subscriptions.vue'
import TimeTracker from '~/sidebar/components/time_tracking/time_tracker.vue';
import eventHub from '~/sidebar/event_hub';
import boardsStore from '../stores/boards_store';
import RemoveBtn from './sidebar/remove_issue.vue';
export default Vue.extend({
components: {
......@@ -29,7 +28,6 @@ export default Vue.extend({
GlLabel,
SidebarEpicsSelect: () =>
import('ee_component/sidebar/components/sidebar_item_epics_select.vue'),
RemoveBtn,
Subscriptions,
TimeTracker,
SidebarAssigneesWidget,
......
<script>
import { GlButton } from '@gitlab/ui';
import axios from '~/lib/utils/axios_utils';
import { deprecatedCreateFlash as Flash } from '../../../flash';
import { __ } from '../../../locale';
import boardsStore from '../../stores/boards_store';
export default {
components: {
GlButton,
},
props: {
issue: {
type: Object,
required: true,
},
list: {
type: Object,
required: true,
},
},
computed: {
updateUrl() {
return this.issue.path;
},
},
methods: {
removeIssue() {
const { issue } = this;
const lists = issue.getLists();
const req = this.buildPatchRequest(issue, lists);
const data = {
issue: this.seedPatchRequest(issue, req),
};
if (data.issue.label_ids.length === 0) {
data.issue.label_ids = [''];
}
// Post the remove data
axios.patch(this.updateUrl, data).catch(() => {
Flash(__('Failed to remove issue from board, please try again.'));
lists.forEach((list) => {
list.addIssue(issue);
});
});
// Remove from the frontend store
lists.forEach((list) => {
list.removeIssue(issue);
});
boardsStore.clearDetailIssue();
},
/**
* Build the default patch request.
*/
buildPatchRequest(issue, lists) {
const listLabelIds = lists.map((list) => list.label.id);
const labelIds = issue.labels
.map((label) => label.id)
.filter((id) => !listLabelIds.includes(id));
return {
label_ids: labelIds,
};
},
/**
* Seed the given patch request.
*
* (This is overridden in EE)
*/
seedPatchRequest(issue, req) {
return req;
},
},
};
</script>
<template>
<div class="block list">
<gl-button variant="default" category="secondary" block="block" @click="removeIssue">
{{ __('Remove from board') }}
</gl-button>
</div>
</template>
......@@ -25,7 +25,3 @@
= render "shared/boards/components/sidebar/labels"
= render_if_exists "shared/boards/components/sidebar/weight"
= render "shared/boards/components/sidebar/notifications"
%remove-btn{ ":issue" => "issue",
":issue-update" => "issue.sidebarInfoEndpoint",
":list" => "list",
"v-if" => "canRemove" }
---
title: Remove Remove from board button from board sidebar
merge_request: 53946
author:
type: removed
......@@ -87,9 +87,9 @@ To delete the currently active issue board:
You can tailor GitLab issue boards to your own preferred workflow.
Here are some common use cases for issue boards.
For examples of using issue boards along with [epics](../group/epics/index.md) **(PREMIUM)**,
[issue health status](issues/index.md#health-status) **(ULTIMATE)**, and
[scoped labels](labels.md#scoped-labels) **(PREMIUM)** for various Agile frameworks, check:
For examples of using issue boards along with [epics](../group/epics/index.md),
[issue health status](issues/index.md#health-status), and
[scoped labels](labels.md#scoped-labels) for various Agile frameworks, check:
- The [How to use GitLab for Agile portfolio planning and project management](https://about.gitlab.com/blog/2020/11/11/gitlab-for-agile-portfolio-planning-project-management/) blog post (November 2020)
- <i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
......@@ -485,11 +485,14 @@ the list by filtering by the following:
### Remove an issue from a list
Removing an issue from a list can be done by clicking the issue card and then
clicking the **Remove from board** button in the sidebar. The
respective label is removed.
> The **Remove from board** button was [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/229507) in GitLab 13.10.
![Remove issue from list](img/issue_boards_remove_issue_v13_6.png)
When an issue should no longer belong to a list, you can remove it.
The steps depend on the scope of the list:
1. To open the right sidebar, select the issue card.
1. Remove what's keeping the issue in the list.
If it's a label list, remove the label. If it's an [assignee list](#assignee-lists), unassign the user.
### Filter issues
......
import Weight from 'ee/sidebar/components/weight/weight.vue';
import BoardSidebar from '~/boards/components/board_sidebar';
import RemoveBtn from './sidebar/remove_issue';
export default BoardSidebar.extend({
components: {
RemoveBtn,
Weight,
},
});
import base from '~/boards/components/sidebar/remove_issue.vue';
import boardsStore from '~/boards/stores/boards_store';
export default {
extends: base,
methods: {
seedPatchRequest(issue, req) {
/* eslint-disable no-param-reassign */
const board = boardsStore.state.currentBoard;
const boardLabelIds = board.labels.map((label) => label.id);
req.label_ids = req.label_ids.filter((id) => !boardLabelIds.includes(id));
if (board.milestone_id) {
req.milestone_id = -1;
}
if (board.weight) {
req.weight = null;
}
const boardAssignee = board.assignee ? board.assignee.id : null;
const assigneeIds = issue.assignees
.map((assignee) => assignee.id)
.filter((id) => id !== boardAssignee);
return {
...req,
assignee_ids: assigneeIds.length ? assigneeIds : ['0'],
};
},
},
};
......@@ -422,25 +422,6 @@ RSpec.describe 'Scoped issue boards', :js do
end
end
end
context 'remove issue' do
let!(:issue) { create(:labeled_issue, project: project, labels: [project_label], milestone: milestone, assignees: [user]) }
let!(:list) { create(:list, board: board, label: project_label, position: 0) }
it 'removes issues milestone when removing from the board' do
board.update!(milestone: milestone, assignee: user)
visit project_boards_path(project)
wait_for_requests
find(".board-card[data-issue-id='#{issue.id}']").click
click_button 'Remove from board'
wait_for_requests
expect(issue.reload.milestone).to be_nil
expect(issue.reload.assignees).to be_empty
end
end
end
context 'user without edit permissions' do
......
......@@ -12608,9 +12608,6 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
msgid "Failed to remove issue from board, please try again."
msgstr ""
msgid "Failed to remove mirror."
msgstr ""
......@@ -25038,9 +25035,6 @@ msgstr ""
msgid "Remove from batch"
msgstr ""
msgid "Remove from board"
msgstr ""
msgid "Remove from epic"
msgstr ""
......
......@@ -72,36 +72,6 @@ RSpec.describe 'Issue Boards', :js do
end
end
it 'removes card from board when clicking' do
click_card(card)
page.within('.issue-boards-sidebar') do
click_button 'Remove from board'
end
wait_for_requests
page.within(find('.board:nth-child(2)')) do
expect(page).to have_selector('.board-card', count: 1)
end
end
it 'does not show remove button for backlog or closed issues' do
create(:issue, project: project)
create(:issue, :closed, project: project)
visit project_board_path(project, board)
wait_for_requests
click_card(find('.board:nth-child(1)').first('.board-card'))
expect(find('.issue-boards-sidebar')).not_to have_button 'Remove from board'
click_card(find('.board:nth-child(3)').first('.board-card'))
expect(find('.issue-boards-sidebar')).not_to have_button 'Remove from board'
end
context 'assignee' do
it 'updates the issues assignee' do
click_card(card)
......
import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import RemoveIssue from '~/boards/components/sidebar/remove_issue.vue';
describe('boards sidebar remove issue', () => {
let wrapper;
const findButton = () => wrapper.find(GlButton);
const createComponent = (propsData) => {
wrapper = shallowMount(RemoveIssue, {
propsData: {
issue: {},
list: {},
...propsData,
},
});
};
beforeEach(() => {
createComponent();
});
it('renders remove button', () => {
expect(findButton().exists()).toBe(true);
});
});
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