diff --git a/app/assets/javascripts/boards/components/board_column.vue b/app/assets/javascripts/boards/components/board_column.vue
index dae24338e45..23e4edea40f 100644
--- a/app/assets/javascripts/boards/components/board_column.vue
+++ b/app/assets/javascripts/boards/components/board_column.vue
@@ -1,9 +1,11 @@
+
+
+
+
{{ title }}
+
{{ refPath }}
+
+
diff --git a/app/assets/javascripts/boards/filtered_search_boards.js b/app/assets/javascripts/boards/filtered_search_boards.js
index f421faeb52d..fff89832bf0 100644
--- a/app/assets/javascripts/boards/filtered_search_boards.js
+++ b/app/assets/javascripts/boards/filtered_search_boards.js
@@ -27,7 +27,7 @@ export default class FilteredSearchBoards extends FilteredSearchManager {
updateObject(path) {
this.store.path = path.substr(1);
- if (gon.features.boardsWithSwimlanes) {
+ if (gon.features.boardsWithSwimlanes || gon.features.graphqlBoardLists) {
boardsStore.updateFiltersUrl();
boardsStore.performSearch();
}
diff --git a/app/assets/javascripts/boards/queries/issue.fragment.graphql b/app/assets/javascripts/boards/queries/issue.fragment.graphql
index 21b52766190..4b429f875a6 100644
--- a/app/assets/javascripts/boards/queries/issue.fragment.graphql
+++ b/app/assets/javascripts/boards/queries/issue.fragment.graphql
@@ -7,15 +7,10 @@ fragment IssueNode on Issue {
referencePath: reference(full: true)
dueDate
timeEstimate
- weight
confidential
webUrl
subscribed
- blocked
relativePosition
- epic {
- id
- }
assignees {
nodes {
...User
diff --git a/app/assets/javascripts/boards/queries/lists_issues.query.graphql b/app/assets/javascripts/boards/queries/lists_issues.query.graphql
index a9fc99fd916..c66cdf68cf4 100644
--- a/app/assets/javascripts/boards/queries/lists_issues.query.graphql
+++ b/app/assets/javascripts/boards/queries/lists_issues.query.graphql
@@ -1,15 +1,16 @@
-#import "./issue.fragment.graphql"
+#import "ee_else_ce/boards/queries/issue.fragment.graphql"
query ListIssues(
$fullPath: ID!
$boardId: ID!
+ $id: ID
$filters: BoardIssueInput
$isGroup: Boolean = false
$isProject: Boolean = false
) {
group(fullPath: $fullPath) @include(if: $isGroup) {
board(id: $boardId) {
- lists {
+ lists(id: $id) {
nodes {
id
issues(filters: $filters) {
@@ -23,7 +24,7 @@ query ListIssues(
}
project(fullPath: $fullPath) @include(if: $isProject) {
board(id: $boardId) {
- lists {
+ lists(id: $id) {
nodes {
id
issues(filters: $filters) {
diff --git a/app/assets/javascripts/boards/stores/actions.js b/app/assets/javascripts/boards/stores/actions.js
index f8767211abd..248e06ba264 100644
--- a/app/assets/javascripts/boards/stores/actions.js
+++ b/app/assets/javascripts/boards/stores/actions.js
@@ -79,10 +79,10 @@ export default {
lists = lists.nodes.map(list =>
boardStore.updateListPosition({
...list,
- id: getIdFromGraphQLId(list.id),
+ doNotFetchIssues: true,
}),
);
- commit(types.RECEIVE_LISTS, sortBy(lists, 'position'));
+ commit(types.RECEIVE_BOARD_LISTS_SUCCESS, sortBy(lists, 'position'));
// Backlog list needs to be created if it doesn't exist
if (!lists.find(l => l.type === ListType.backlog)) {
dispatch('createList', { backlog: true });
@@ -113,7 +113,7 @@ export default {
commit(types.CREATE_LIST_FAILURE);
} else {
const list = data.boardListCreate?.list;
- dispatch('addList', { ...list, id: getIdFromGraphQLId(list.id) });
+ dispatch('addList', list);
}
})
.catch(() => {
@@ -124,8 +124,8 @@ export default {
addList: ({ state, commit }, list) => {
const lists = state.boardLists;
// Temporarily using positioning logic from boardStore
- lists.push(boardStore.updateListPosition(list));
- commit(types.RECEIVE_LISTS, sortBy(lists, 'position'));
+ lists.push(boardStore.updateListPosition({ ...list, doNotFetchIssues: true }));
+ commit(types.RECEIVE_BOARD_LISTS_SUCCESS, sortBy(lists, 'position'));
},
showWelcomeList: ({ state, dispatch }) => {
@@ -197,8 +197,33 @@ export default {
notImplemented();
},
- fetchIssuesForList: () => {
- notImplemented();
+ fetchIssuesForList: ({ state, commit }, listId) => {
+ const { endpoints, boardType, filterParams } = state;
+ const { fullPath, boardId } = endpoints;
+
+ const variables = {
+ fullPath,
+ boardId: fullBoardId(boardId),
+ id: listId,
+ filters: filterParams,
+ isGroup: boardType === BoardType.group,
+ isProject: boardType === BoardType.project,
+ };
+
+ return gqlClient
+ .query({
+ query: listsIssuesQuery,
+ context: {
+ isSingleRequest: true,
+ },
+ variables,
+ })
+ .then(({ data }) => {
+ const { lists } = data[boardType]?.board;
+ const listIssues = formatListIssues(lists);
+ commit(types.RECEIVE_ISSUES_FOR_LIST_SUCCESS, { listIssues, listId });
+ })
+ .catch(() => commit(types.RECEIVE_ISSUES_FOR_LIST_FAILURE, listId));
},
fetchIssuesForAllLists: ({ state, commit }) => {
diff --git a/app/assets/javascripts/boards/stores/boards_store.js b/app/assets/javascripts/boards/stores/boards_store.js
index 4fdbfbc36c5..faf4f9ebfd3 100644
--- a/app/assets/javascripts/boards/stores/boards_store.js
+++ b/app/assets/javascripts/boards/stores/boards_store.js
@@ -304,7 +304,11 @@ const boardsStore = {
onNewListIssueResponse(list, issue, data) {
issue.refreshData(data);
- if (!gon.features.boardsWithSwimlanes && list.issuesSize > 1) {
+ if (
+ !gon.features.boardsWithSwimlanes &&
+ !gon.features.graphqlBoardLists &&
+ list.issues.length > 1
+ ) {
const moveBeforeId = list.issues[1].id;
this.moveIssue(issue.id, null, null, null, moveBeforeId);
}
@@ -723,6 +727,10 @@ const boardsStore = {
newListIssue(list, issue) {
list.addIssue(issue, null, 0);
list.issuesSize += 1;
+ let listId = list.id;
+ if (typeof listId === 'string') {
+ listId = getIdFromGraphQLId(listId);
+ }
return this.newIssue(list.id, issue)
.then(res => res.data)
diff --git a/app/assets/javascripts/boards/stores/getters.js b/app/assets/javascripts/boards/stores/getters.js
index 80acf8e66cc..3688476dc5f 100644
--- a/app/assets/javascripts/boards/stores/getters.js
+++ b/app/assets/javascripts/boards/stores/getters.js
@@ -14,6 +14,11 @@ export default {
return state.issues[id] || {};
},
+ getIssues: (state, getters) => listId => {
+ const listIssueIds = state.issuesByListId[listId] || [];
+ return listIssueIds.map(id => getters.getIssueById(id));
+ },
+
getActiveIssue: state => {
return state.issues[state.activeId] || {};
},
diff --git a/app/assets/javascripts/boards/stores/mutation_types.js b/app/assets/javascripts/boards/stores/mutation_types.js
index 5a3d62dc703..f0a283f6161 100644
--- a/app/assets/javascripts/boards/stores/mutation_types.js
+++ b/app/assets/javascripts/boards/stores/mutation_types.js
@@ -2,7 +2,7 @@ export const SET_INITIAL_BOARD_DATA = 'SET_INITIAL_BOARD_DATA';
export const SET_FILTERS = 'SET_FILTERS';
export const CREATE_LIST_SUCCESS = 'CREATE_LIST_SUCCESS';
export const CREATE_LIST_FAILURE = 'CREATE_LIST_FAILURE';
-export const RECEIVE_LISTS = 'RECEIVE_LISTS';
+export const RECEIVE_BOARD_LISTS_SUCCESS = 'RECEIVE_BOARD_LISTS_SUCCESS';
export const SHOW_PROMOTION_LIST = 'SHOW_PROMOTION_LIST';
export const REQUEST_ADD_LIST = 'REQUEST_ADD_LIST';
export const RECEIVE_ADD_LIST_SUCCESS = 'RECEIVE_ADD_LIST_SUCCESS';
@@ -13,6 +13,8 @@ export const REQUEST_REMOVE_LIST = 'REQUEST_REMOVE_LIST';
export const RECEIVE_REMOVE_LIST_SUCCESS = 'RECEIVE_REMOVE_LIST_SUCCESS';
export const RECEIVE_REMOVE_LIST_ERROR = 'RECEIVE_REMOVE_LIST_ERROR';
export const REQUEST_ISSUES_FOR_ALL_LISTS = 'REQUEST_ISSUES_FOR_ALL_LISTS';
+export const RECEIVE_ISSUES_FOR_LIST_FAILURE = 'RECEIVE_ISSUES_FOR_LIST_FAILURE';
+export const RECEIVE_ISSUES_FOR_LIST_SUCCESS = 'RECEIVE_ISSUES_FOR_LIST_SUCCESS';
export const RECEIVE_ISSUES_FOR_ALL_LISTS_SUCCESS = 'RECEIVE_ISSUES_FOR_ALL_LISTS_SUCCESS';
export const RECEIVE_ISSUES_FOR_ALL_LISTS_FAILURE = 'RECEIVE_ISSUES_FOR_ALL_LISTS_FAILURE';
export const REQUEST_ADD_ISSUE = 'REQUEST_ADD_ISSUE';
diff --git a/app/assets/javascripts/boards/stores/mutations.js b/app/assets/javascripts/boards/stores/mutations.js
index a03c541ada5..faeb3e25a71 100644
--- a/app/assets/javascripts/boards/stores/mutations.js
+++ b/app/assets/javascripts/boards/stores/mutations.js
@@ -35,7 +35,7 @@ export default {
state.showPromotion = showPromotion;
},
- [mutationTypes.RECEIVE_LISTS]: (state, lists) => {
+ [mutationTypes.RECEIVE_BOARD_LISTS_SUCCESS]: (state, lists) => {
state.boardLists = lists;
},
@@ -89,6 +89,20 @@ export default {
notImplemented();
},
+ [mutationTypes.RECEIVE_ISSUES_FOR_LIST_SUCCESS]: (state, { listIssues, listId }) => {
+ const { listData, issues } = listIssues;
+ Vue.set(state, 'issues', { ...state.issues, ...issues });
+ Vue.set(state.issuesByListId, listId, listData[listId]);
+ const listIndex = state.boardLists.findIndex(l => l.id === listId);
+ Vue.set(state.boardLists[listIndex], 'loading', false);
+ },
+
+ [mutationTypes.RECEIVE_ISSUES_FOR_LIST_FAILURE]: (state, listId) => {
+ state.error = __('An error occurred while fetching the board issues. Please reload the page.');
+ const listIndex = state.boardLists.findIndex(l => l.id === listId);
+ Vue.set(state.boardLists[listIndex], 'loading', false);
+ },
+
[mutationTypes.REQUEST_ISSUES_FOR_ALL_LISTS]: state => {
state.isLoadingIssues = true;
},
diff --git a/app/assets/javascripts/diffs/components/diff_file.vue b/app/assets/javascripts/diffs/components/diff_file.vue
index c8b7168dce1..02396a4ba1b 100644
--- a/app/assets/javascripts/diffs/components/diff_file.vue
+++ b/app/assets/javascripts/diffs/components/diff_file.vue
@@ -1,32 +1,26 @@