Commit cc2d3c3e authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '323871-epic-boards-reorder-lists' into 'master'

Epic board list reorder [RUN AS-IF-FOSS]

See merge request gitlab-org/gitlab!60072
parents dd2427c3 a4e830c6
...@@ -4,7 +4,6 @@ import { sortBy } from 'lodash'; ...@@ -4,7 +4,6 @@ import { sortBy } from 'lodash';
import Draggable from 'vuedraggable'; import Draggable from 'vuedraggable';
import { mapState, mapGetters, mapActions } from 'vuex'; import { mapState, mapGetters, mapActions } from 'vuex';
import BoardAddNewColumn from 'ee_else_ce/boards/components/board_add_new_column.vue'; import BoardAddNewColumn from 'ee_else_ce/boards/components/board_add_new_column.vue';
import { sortableEnd, sortableStart } from '~/boards/mixins/sortable_default_options';
import defaultSortableConfig from '~/sortable/sortable_config'; import defaultSortableConfig from '~/sortable/sortable_config';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import BoardColumn from './board_column.vue'; import BoardColumn from './board_column.vue';
...@@ -48,7 +47,7 @@ export default { ...@@ -48,7 +47,7 @@ export default {
: this.lists; : this.lists;
}, },
canDragColumns() { canDragColumns() {
return !this.isEpicBoard && this.glFeatures.graphqlBoardLists && this.canAdminList; return (this.isEpicBoard || this.glFeatures.graphqlBoardLists) && this.canAdminList;
}, },
boardColumnWrapper() { boardColumnWrapper() {
return this.canDragColumns ? Draggable : 'div'; return this.canDragColumns ? Draggable : 'div';
...@@ -73,14 +72,7 @@ export default { ...@@ -73,14 +72,7 @@ export default {
const el = this.canDragColumns ? this.$refs.list.$el : this.$refs.list; const el = this.canDragColumns ? this.$refs.list.$el : this.$refs.list;
el.scrollTo({ left: el.scrollWidth, behavior: 'smooth' }); el.scrollTo({ left: el.scrollWidth, behavior: 'smooth' });
}, },
handleDragOnStart() {
sortableStart();
},
handleDragOnEnd(params) { handleDragOnEnd(params) {
sortableEnd();
if (this.isEpicBoard) return;
const { item, newIndex, oldIndex, to } = params; const { item, newIndex, oldIndex, to } = params;
const listId = item.dataset.id; const listId = item.dataset.id;
...@@ -108,7 +100,6 @@ export default { ...@@ -108,7 +100,6 @@ export default {
ref="list" ref="list"
v-bind="draggableOptions" v-bind="draggableOptions"
class="boards-list gl-w-full gl-py-5 gl-px-3 gl-white-space-nowrap" class="boards-list gl-w-full gl-py-5 gl-px-3 gl-white-space-nowrap"
@start="handleDragOnStart"
@end="handleDragOnEnd" @end="handleDragOnEnd"
> >
<board-column <board-column
......
...@@ -84,7 +84,7 @@ export default { ...@@ -84,7 +84,7 @@ export default {
return this.list?.label?.description || this.list?.assignee?.name || this.list.title || ''; return this.list?.label?.description || this.list?.assignee?.name || this.list.title || '';
}, },
showListHeaderButton() { showListHeaderButton() {
return !this.disabled && this.listType !== ListType.closed; return !this.disabled && this.listType !== ListType.closed && !this.isEpicBoard;
}, },
showMilestoneListDetails() { showMilestoneListDetails() {
return this.listType === ListType.milestone && this.list.milestone && this.showListDetails; return this.listType === ListType.milestone && this.list.milestone && this.showListDetails;
...@@ -161,7 +161,7 @@ export default { ...@@ -161,7 +161,7 @@ export default {
const collapsed = !this.list.collapsed; const collapsed = !this.list.collapsed;
this.toggleListCollapsed({ listId: this.list.id, collapsed }); this.toggleListCollapsed({ listId: this.list.id, collapsed });
if (!this.isLoggedIn || this.isEpicBoard) { if (!this.isLoggedIn) {
this.addToLocalStorage(); this.addToLocalStorage();
} else { } else {
this.updateListFunction(); this.updateListFunction();
......
...@@ -2,6 +2,7 @@ import { __ } from '~/locale'; ...@@ -2,6 +2,7 @@ import { __ } from '~/locale';
import updateEpicSubscriptionMutation from '~/sidebar/queries/update_epic_subscription.mutation.graphql'; import updateEpicSubscriptionMutation from '~/sidebar/queries/update_epic_subscription.mutation.graphql';
import updateEpicTitleMutation from '~/sidebar/queries/update_epic_title.mutation.graphql'; import updateEpicTitleMutation from '~/sidebar/queries/update_epic_title.mutation.graphql';
import boardBlockingIssuesQuery from './graphql/board_blocking_issues.query.graphql'; import boardBlockingIssuesQuery from './graphql/board_blocking_issues.query.graphql';
import updateBoardListMutation from './graphql/board_list_update.mutation.graphql';
import issueSetSubscriptionMutation from './graphql/issue_set_subscription.mutation.graphql'; import issueSetSubscriptionMutation from './graphql/issue_set_subscription.mutation.graphql';
import issueSetTitleMutation from './graphql/issue_set_title.mutation.graphql'; import issueSetTitleMutation from './graphql/issue_set_title.mutation.graphql';
...@@ -71,6 +72,12 @@ export const blockingIssuablesQueries = { ...@@ -71,6 +72,12 @@ export const blockingIssuablesQueries = {
}, },
}; };
export const updateListQueries = {
[issuableTypes.issue]: {
mutation: updateBoardListMutation,
},
};
export const titleQueries = { export const titleQueries = {
[issuableTypes.issue]: { [issuableTypes.issue]: {
mutation: issueSetTitleMutation, mutation: issueSetTitleMutation,
......
import * as Sentry from '@sentry/browser'; import * as Sentry from '@sentry/browser';
import { updateListQueries } from 'ee_else_ce/boards/constants';
import createBoardListMutation from 'ee_else_ce/boards/graphql/board_list_create.mutation.graphql'; import createBoardListMutation from 'ee_else_ce/boards/graphql/board_list_create.mutation.graphql';
import boardListsQuery from 'ee_else_ce/boards/graphql/board_lists.query.graphql'; import boardListsQuery from 'ee_else_ce/boards/graphql/board_lists.query.graphql';
import issueMoveListMutation from 'ee_else_ce/boards/graphql/issue_move_list.mutation.graphql'; import issueMoveListMutation from 'ee_else_ce/boards/graphql/issue_move_list.mutation.graphql';
...@@ -31,7 +32,6 @@ import { ...@@ -31,7 +32,6 @@ import {
} from '../boards_util'; } from '../boards_util';
import boardLabelsQuery from '../graphql/board_labels.query.graphql'; import boardLabelsQuery from '../graphql/board_labels.query.graphql';
import destroyBoardListMutation from '../graphql/board_list_destroy.mutation.graphql'; import destroyBoardListMutation from '../graphql/board_list_destroy.mutation.graphql';
import updateBoardListMutation from '../graphql/board_list_update.mutation.graphql';
import groupProjectsQuery from '../graphql/group_projects.query.graphql'; import groupProjectsQuery from '../graphql/group_projects.query.graphql';
import issueCreateMutation from '../graphql/issue_create.mutation.graphql'; import issueCreateMutation from '../graphql/issue_create.mutation.graphql';
import issueSetDueDateMutation from '../graphql/issue_set_due_date.mutation.graphql'; import issueSetDueDateMutation from '../graphql/issue_set_due_date.mutation.graphql';
...@@ -238,10 +238,13 @@ export default { ...@@ -238,10 +238,13 @@ export default {
dispatch('updateList', { listId, position: newPosition, backupList }); dispatch('updateList', { listId, position: newPosition, backupList });
}, },
updateList: ({ commit }, { listId, position, collapsed, backupList }) => { updateList: (
{ commit, state: { issuableType } },
{ listId, position, collapsed, backupList },
) => {
gqlClient gqlClient
.mutate({ .mutate({
mutation: updateBoardListMutation, mutation: updateListQueries[issuableType].mutation,
variables: { variables: {
listId, listId,
position, position,
......
...@@ -10,7 +10,7 @@ module BoardsHelper ...@@ -10,7 +10,7 @@ module BoardsHelper
boards_endpoint: @boards_endpoint, boards_endpoint: @boards_endpoint,
lists_endpoint: board_lists_path(board), lists_endpoint: board_lists_path(board),
board_id: board.id, board_id: board.id,
disabled: (!can?(current_user, :create_non_backlog_issues, board)).to_s, disabled: disabled?.to_s,
root_path: root_path, root_path: root_path,
full_path: full_path, full_path: full_path,
bulk_update_path: @bulk_issues_path, bulk_update_path: @bulk_issues_path,
...@@ -101,6 +101,10 @@ module BoardsHelper ...@@ -101,6 +101,10 @@ module BoardsHelper
can?(current_user, :admin_issue, current_board_parent) can?(current_user, :admin_issue, current_board_parent)
end end
def disabled?
!can?(current_user, :create_non_backlog_issues, board)
end
def board_list_data def board_list_data
include_descendant_groups = @group&.present? include_descendant_groups = @group&.present?
......
import { issuableTypes } from '~/boards/constants';
import updateBoardListMutation from '~/boards/graphql/board_list_update.mutation.graphql';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import updateEpicBoardListMutation from './graphql/epic_board_list_update.mutation.graphql';
export const DRAGGABLE_TAG = 'div'; export const DRAGGABLE_TAG = 'div';
export const EPIC_LANE_BASE_HEIGHT = 40; export const EPIC_LANE_BASE_HEIGHT = 40;
...@@ -54,6 +59,15 @@ export const ErrorMessages = { ...@@ -54,6 +59,15 @@ export const ErrorMessages = {
), ),
}; };
export const updateListQueries = {
[issuableTypes.issue]: {
mutation: updateBoardListMutation,
},
[issuableTypes.epic]: {
mutation: updateEpicBoardListMutation,
},
};
export default { export default {
DRAGGABLE_TAG, DRAGGABLE_TAG,
EpicFilterType, EpicFilterType,
......
#import "./epic_board_list.fragment.graphql"
mutation UpdateEpicBoardList($listId: BoardsEpicListID!, $position: Int, $collapsed: Boolean) {
updateBoardList: updateEpicBoardList(
input: { listId: $listId, position: $position, collapsed: $collapsed }
) {
list {
...EpicBoardListFragment
}
errors
}
}
...@@ -33,6 +33,7 @@ module EE ...@@ -33,6 +33,7 @@ module EE
scoped_labels: current_board_parent.feature_available?(:scoped_labels)&.to_s, scoped_labels: current_board_parent.feature_available?(:scoped_labels)&.to_s,
can_update: can_update?.to_s, can_update: can_update?.to_s,
can_admin_list: can_admin_list?.to_s, can_admin_list: can_admin_list?.to_s,
disabled: disabled?.to_s,
emails_disabled: current_board_parent.emails_disabled?.to_s emails_disabled: current_board_parent.emails_disabled?.to_s
} }
...@@ -60,6 +61,13 @@ module EE ...@@ -60,6 +61,13 @@ module EE
super super
end end
override :disabled?
def disabled?
return false if board.is_a?(::Boards::EpicBoard)
super
end
override :recent_boards_path override :recent_boards_path
def recent_boards_path def recent_boards_path
return recent_group_boards_path(@group) if current_board_parent.is_a?(Group) return recent_group_boards_path(@group) if current_board_parent.is_a?(Group)
......
...@@ -93,8 +93,41 @@ RSpec.describe 'epic boards', :js do ...@@ -93,8 +93,41 @@ RSpec.describe 'epic boards', :js do
drag(list_from_index: 0, list_to_index: 1) drag(list_from_index: 0, list_to_index: 1)
wait_for_all_requests wait_for_all_requests
expect(find('.board:nth-child(1)')).not_to have_content(epic3.title) expect(find_board_list(1)).not_to have_content(epic3.title)
expect(find('.board:nth-child(2)')).to have_content(epic3.title) expect(find_board_list(2)).to have_content(epic3.title)
end
context 'lists' do
let_it_be(:label_list2) { create(:epic_list, epic_board: epic_board, label: label2, position: 1) }
it 'changes position of list' do
expect(find_board_list(2)).to have_content(label.title)
expect(find_board_list(3)).to have_content(label2.title)
drag(list_from_index: 2, list_to_index: 1, selector: '.board-header')
wait_for_all_requests
expect(find_board_list(2)).to have_content(label2.title)
expect(find_board_list(3)).to have_content(label.title)
# Make sure list positions are preserved after a reload
visit_epic_boards_page
wait_for_all_requests
expect(find_board_list(2)).to have_content(label2.title)
expect(find_board_list(3)).to have_content(label.title)
end
it 'dragging does not duplicate list' do
selector = '.board:not(.is-ghost) .board-header'
expect(page).to have_selector(selector, text: label.title, count: 1)
drag(list_from_index: 2, list_to_index: 1, selector: '.board-header', perform_drop: false)
expect(page).to have_selector(selector, text: label.title, count: 1)
end
end end
end end
...@@ -289,4 +322,8 @@ RSpec.describe 'epic boards', :js do ...@@ -289,4 +322,8 @@ RSpec.describe 'epic boards', :js do
def click_on_board_modal def click_on_board_modal
find('.board-config-modal .modal-content').click find('.board-config-modal .modal-content').click
end end
def find_board_list(board_number)
find(".board:nth-child(#{board_number})")
end
end end
...@@ -459,6 +459,7 @@ describe('updateList', () => { ...@@ -459,6 +459,7 @@ describe('updateList', () => {
boardType: 'group', boardType: 'group',
disabled: false, disabled: false,
boardLists: [{ type: 'closed' }], boardLists: [{ type: 'closed' }],
issuableType: 'issue',
}; };
testAction( testAction(
......
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