Commit 3f6610db authored by Heinrich Lee Yu's avatar Heinrich Lee Yu

Project reporters can drag cards in group board

This reverts the behavior to match what we had before GraphQL boards.

Changelog: fixed
parent 676c2ef8
......@@ -27,11 +27,6 @@ export default {
GlIntersectionObserver,
},
mixins: [Tracking.mixin()],
inject: {
canAdminList: {
default: false,
},
},
props: {
disabled: {
type: Boolean,
......@@ -89,8 +84,8 @@ export default {
return !this.isEpicBoard && this.list.listType !== 'closed' && this.showIssueForm;
},
listRef() {
// When list is draggable, the reference to the list needs to be accessed differently
return this.canAdminList ? this.$refs.list.$el : this.$refs.list;
// When list is draggable, the reference to the list needs to be accessed differently
return this.canMoveIssue ? this.$refs.list.$el : this.$refs.list;
},
showingAllItems() {
return this.boardItems.length === this.listItemsCount;
......@@ -100,8 +95,11 @@ export default {
? this.$options.i18n.showingAllEpics
: this.$options.i18n.showingAllIssues;
},
canMoveIssue() {
return !this.disabled;
},
treeRootWrapper() {
return this.canAdminList && !this.listsFlags[this.list.id]?.addItemToListInProgress
return this.canMoveIssue && !this.listsFlags[this.list.id]?.addItemToListInProgress
? Draggable
: 'ul';
},
......@@ -116,7 +114,7 @@ export default {
value: this.boardItems,
};
return this.canAdminList ? options : {};
return this.canMoveIssue ? options : {};
},
},
watch: {
......
......@@ -5,6 +5,7 @@ require 'spec_helper'
RSpec.describe 'Project issue boards', :js do
include DragTo
include MobileHelpers
include BoardHelpers
let_it_be(:group) { create(:group, :nested) }
let_it_be(:project) { create(:project, :public, namespace: group) }
......@@ -546,23 +547,6 @@ RSpec.describe 'Project issue boards', :js do
end
end
def drag(selector: '.board-list', list_from_index: 0, from_index: 0, to_index: 0, list_to_index: 0, perform_drop: true)
# ensure there is enough horizontal space for four boards
inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
resize_window(2000, 800)
drag_to(selector: selector,
scrollable: '#board-app',
list_from_index: list_from_index,
from_index: from_index,
to_index: to_index,
list_to_index: list_to_index,
perform_drop: perform_drop)
end
wait_for_requests
end
def wait_for_board_cards(board_number, expected_cards)
page.within(find(".board:nth-child(#{board_number})")) do
expect(page.find('.board-header')).to have_content(expected_cards.to_s)
......
......@@ -3,16 +3,21 @@
require 'spec_helper'
RSpec.describe 'Group Boards' do
let(:group) { create(:group) }
let!(:project) { create(:project_empty_repo, group: group) }
let(:user) { create(:group_member, :maintainer, user: create(:user), group: group ).user }
include DragTo
include MobileHelpers
include BoardHelpers
before do
sign_in(user)
end
let_it_be(:group) { create(:group) }
let_it_be(:user) { create(:user) }
context 'Creates an issue', :js do
let_it_be(:project) { create(:project_empty_repo, group: group) }
context 'Creates a an issue', :js do
before do
group.add_maintainer(user)
sign_in(user)
visit group_boards_path(group)
end
......@@ -39,4 +44,58 @@ RSpec.describe 'Group Boards' do
end
end
end
context "when user is a Reporter in one of the group's projects", :js do
let_it_be(:board) { create(:board, group: group) }
let_it_be(:backlog_list) { create(:backlog_list, board: board) }
let_it_be(:group_label1) { create(:group_label, title: "bug", group: group) }
let_it_be(:group_label2) { create(:group_label, title: "dev", group: group) }
let_it_be(:list1) { create(:list, board: board, label: group_label1, position: 0) }
let_it_be(:list2) { create(:list, board: board, label: group_label2, position: 1) }
let_it_be(:project1) { create(:project_empty_repo, :private, group: group) }
let_it_be(:project2) { create(:project_empty_repo, :private, group: group) }
let_it_be(:issue1) { create(:issue, title: 'issue1', project: project1, labels: [group_label2]) }
let_it_be(:issue2) { create(:issue, title: 'issue2', project: project2) }
before do
project1.add_guest(user)
project2.add_reporter(user)
sign_in(user)
inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
visit group_boards_path(group)
end
end
it 'allows user to move issue of project where they are a Reporter' do
expect(find('.board:nth-child(1)')).to have_content(issue2.title)
drag(list_from_index: 0, from_index: 0, list_to_index: 1)
expect(find('.board:nth-child(2)')).to have_content(issue2.title)
expect(issue2.reload.labels).to contain_exactly(group_label1)
end
it 'does not allow user to move issue of project where they are a Guest' do
expect(find('.board:nth-child(3)')).to have_content(issue1.title)
drag(list_from_index: 2, from_index: 0, list_to_index: 1)
expect(find('.board:nth-child(3)')).to have_content(issue1.title)
expect(issue1.reload.labels).to contain_exactly(group_label2)
expect(issue2.reload.labels).to eq([])
end
it 'does not allow user to re-position lists' do
drag(list_from_index: 1, list_to_index: 2, selector: '.board-header')
expect(find('.board:nth-child(2) [data-testid="board-list-header"]')).to have_content(group_label1.title)
expect(find('.board:nth-child(3) [data-testid="board-list-header"]')).to have_content(group_label2.title)
expect(list1.reload.position).to eq(0)
expect(list2.reload.position).to eq(1)
end
end
end
import Draggable from 'vuedraggable';
import { useFakeRequestAnimationFrame } from 'helpers/fake_request_animation_frame';
import createComponent from 'jest/boards/board_list_helper';
import BoardCard from '~/boards/components/board_card.vue';
......@@ -10,6 +11,7 @@ describe('Board list component', () => {
const findByTestId = (testId) => wrapper.find(`[data-testid="${testId}"]`);
const findIssueCountLoadingIcon = () => wrapper.find('[data-testid="count-loading-icon"]');
const findDraggable = () => wrapper.findComponent(Draggable);
useFakeRequestAnimationFrame();
......@@ -155,40 +157,64 @@ describe('Board list component', () => {
});
describe('drag & drop issue', () => {
beforeEach(() => {
wrapper = createComponent();
});
describe('when dragging is allowed', () => {
beforeEach(() => {
wrapper = createComponent({
componentProps: {
disabled: false,
},
});
});
describe('handleDragOnStart', () => {
it('adds a class `is-dragging` to document body', () => {
expect(document.body.classList.contains('is-dragging')).toBe(false);
it('Draggable is used', () => {
expect(findDraggable().exists()).toBe(true);
});
findByTestId('tree-root-wrapper').vm.$emit('start');
describe('handleDragOnStart', () => {
it('adds a class `is-dragging` to document body', () => {
expect(document.body.classList.contains('is-dragging')).toBe(false);
expect(document.body.classList.contains('is-dragging')).toBe(true);
});
});
findByTestId('tree-root-wrapper').vm.$emit('start');
describe('handleDragOnEnd', () => {
it('removes class `is-dragging` from document body', () => {
jest.spyOn(wrapper.vm, 'moveItem').mockImplementation(() => {});
document.body.classList.add('is-dragging');
expect(document.body.classList.contains('is-dragging')).toBe(true);
});
});
findByTestId('tree-root-wrapper').vm.$emit('end', {
oldIndex: 1,
newIndex: 0,
item: {
dataset: {
itemId: mockIssues[0].id,
itemIid: mockIssues[0].iid,
itemPath: mockIssues[0].referencePath,
describe('handleDragOnEnd', () => {
it('removes class `is-dragging` from document body', () => {
jest.spyOn(wrapper.vm, 'moveItem').mockImplementation(() => {});
document.body.classList.add('is-dragging');
findByTestId('tree-root-wrapper').vm.$emit('end', {
oldIndex: 1,
newIndex: 0,
item: {
dataset: {
itemId: mockIssues[0].id,
itemIid: mockIssues[0].iid,
itemPath: mockIssues[0].referencePath,
},
},
to: { children: [], dataset: { listId: 'gid://gitlab/List/1' } },
from: { dataset: { listId: 'gid://gitlab/List/2' } },
});
expect(document.body.classList.contains('is-dragging')).toBe(false);
});
});
});
describe('when dragging is not allowed', () => {
beforeEach(() => {
wrapper = createComponent({
componentProps: {
disabled: true,
},
to: { children: [], dataset: { listId: 'gid://gitlab/List/1' } },
from: { dataset: { listId: 'gid://gitlab/List/2' } },
});
});
expect(document.body.classList.contains('is-dragging')).toBe(false);
it('Draggable is not used', () => {
expect(findDraggable().exists()).toBe(false);
});
});
});
......
......@@ -23,4 +23,21 @@ module BoardHelpers
wait_for_requests
end
end
def drag(selector: '.board-list', list_from_index: 0, from_index: 0, to_index: 0, list_to_index: 0, perform_drop: true)
inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
# ensure there is enough horizontal space for four board lists
resize_window(2000, 800)
drag_to(selector: selector,
scrollable: '#board-app',
list_from_index: list_from_index,
from_index: from_index,
to_index: to_index,
list_to_index: list_to_index,
perform_drop: perform_drop)
end
wait_for_requests
end
end
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