debian-mirror-gitlab/app/assets/javascripts/boards/stores/actions.js

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

929 lines
26 KiB
JavaScript
Raw Normal View History

2021-04-29 21:17:54 +05:30
import * as Sentry from '@sentry/browser';
2021-10-27 15:23:28 +05:30
import { sortBy } from 'lodash';
2021-04-17 20:07:23 +05:30
import {
BoardType,
ListType,
inactiveId,
flashAnimationDuration,
ISSUABLE,
2021-04-29 21:17:54 +05:30
titleQueries,
subscriptionQueries,
2021-06-08 01:23:25 +05:30
deleteListQueries,
listsQuery,
updateListQueries,
issuableTypes,
2021-09-04 01:27:46 +05:30
FilterFields,
ListTypeTitles,
2021-10-27 15:23:28 +05:30
DraggableItemTypes,
2022-10-11 01:57:18 +05:30
DEFAULT_BOARD_LIST_ITEMS_SIZE,
2021-06-08 01:23:25 +05:30
} from 'ee_else_ce/boards/constants';
2021-01-03 14:25:43 +05:30
import {
2022-01-26 12:08:38 +05:30
formatIssueInput,
2021-01-03 14:25:43 +05:30
formatBoardLists,
formatListIssues,
formatListsPageInfo,
2021-01-29 00:20:46 +05:30
formatIssue,
2021-03-08 18:12:59 +05:30
updateListPosition,
2021-04-29 21:17:54 +05:30
moveItemListHelper,
getMoveData,
2021-09-04 01:27:46 +05:30
FiltersInfo,
filterVariables,
2022-01-26 12:08:38 +05:30
} from 'ee_else_ce/boards/boards_util';
import createBoardListMutation from 'ee_else_ce/boards/graphql/board_list_create.mutation.graphql';
import issueMoveListMutation from 'ee_else_ce/boards/graphql/issue_move_list.mutation.graphql';
import totalCountAndWeightQuery from 'ee_else_ce/boards/graphql/board_lists_deferred.query.graphql';
2022-07-23 23:45:48 +05:30
import { fetchPolicies } from '~/lib/graphql';
2022-01-26 12:08:38 +05:30
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { queryToObject } from '~/lib/utils/url_utility';
import { s__ } from '~/locale';
2022-07-23 23:45:48 +05:30
import eventHub from '../eventhub';
2021-11-18 22:05:49 +05:30
import { gqlClient } from '../graphql';
2022-05-07 20:08:51 +05:30
import projectBoardQuery from '../graphql/project_board.query.graphql';
import groupBoardQuery from '../graphql/group_board.query.graphql';
2021-02-22 17:27:13 +05:30
import boardLabelsQuery from '../graphql/board_labels.query.graphql';
2021-10-27 15:23:28 +05:30
import groupBoardMilestonesQuery from '../graphql/group_board_milestones.query.graphql';
2021-03-11 19:13:27 +05:30
import groupProjectsQuery from '../graphql/group_projects.query.graphql';
2021-02-22 17:27:13 +05:30
import issueCreateMutation from '../graphql/issue_create.mutation.graphql';
2021-03-11 19:13:27 +05:30
import listsIssuesQuery from '../graphql/lists_issues.query.graphql';
2021-10-27 15:23:28 +05:30
import projectBoardMilestonesQuery from '../graphql/project_board_milestones.query.graphql';
2021-03-11 19:13:27 +05:30
import * as types from './mutation_types';
2020-06-23 00:09:42 +05:30
2019-09-04 21:01:54 +05:30
export default {
2022-05-07 20:08:51 +05:30
fetchBoard: ({ commit, dispatch }, { fullPath, fullBoardId, boardType }) => {
2022-07-23 23:45:48 +05:30
commit(types.REQUEST_CURRENT_BOARD);
2022-05-07 20:08:51 +05:30
const variables = {
fullPath,
boardId: fullBoardId,
};
return gqlClient
.query({
query: boardType === BoardType.group ? groupBoardQuery : projectBoardQuery,
variables,
})
.then(({ data }) => {
2022-07-23 23:45:48 +05:30
if (data.workspace?.errors) {
commit(types.RECEIVE_BOARD_FAILURE);
} else {
const board = data.workspace?.board;
dispatch('setBoard', board);
}
2022-05-07 20:08:51 +05:30
})
.catch(() => commit(types.RECEIVE_BOARD_FAILURE));
},
2020-10-24 23:57:45 +05:30
setInitialBoardData: ({ commit }, data) => {
commit(types.SET_INITIAL_BOARD_DATA, data);
},
2022-05-07 20:08:51 +05:30
setBoardConfig: ({ commit }, board) => {
const config = {
milestoneId: board.milestone?.id || null,
milestoneTitle: board.milestone?.title || null,
iterationId: board.iteration?.id || null,
iterationTitle: board.iteration?.title || null,
2022-07-16 23:28:13 +05:30
iterationCadenceId: board.iterationCadence?.id || null,
2022-05-07 20:08:51 +05:30
assigneeId: board.assignee?.id || null,
assigneeUsername: board.assignee?.username || null,
labels: board.labels?.nodes || [],
labelIds: board.labels?.nodes?.map((label) => label.id) || [],
weight: board.weight,
};
commit(types.SET_BOARD_CONFIG, config);
},
2022-07-23 23:45:48 +05:30
setBoard: async ({ commit, dispatch }, board) => {
commit(types.RECEIVE_BOARD_SUCCESS, board);
await dispatch('setBoardConfig', board);
dispatch('performSearch', { resetLists: true });
eventHub.$emit('updateTokens');
},
2020-11-24 15:15:51 +05:30
setActiveId({ commit }, { id, sidebarType }) {
commit(types.SET_ACTIVE_ID, { id, sidebarType });
2019-09-04 21:01:54 +05:30
},
2020-11-24 15:15:51 +05:30
unsetActiveId({ dispatch }) {
dispatch('setActiveId', { id: inactiveId, sidebarType: '' });
2019-09-04 21:01:54 +05:30
},
2021-09-04 01:27:46 +05:30
setFilters: ({ commit, state: { issuableType } }, filters) => {
commit(
types.SET_FILTERS,
filterVariables({
filters,
issuableType,
filterInfo: FiltersInfo,
filterFields: FilterFields,
}),
);
2020-11-24 15:15:51 +05:30
},
2022-07-23 23:45:48 +05:30
performSearch({ dispatch }, { resetLists = false } = {}) {
2021-02-22 17:27:13 +05:30
dispatch(
'setFilters',
2021-10-27 15:23:28 +05:30
convertObjectPropsToCamelCase(queryToObject(window.location.search, { gatherArrays: true })),
2021-02-22 17:27:13 +05:30
);
2022-07-23 23:45:48 +05:30
dispatch('fetchLists', { resetLists });
2021-11-11 11:23:49 +05:30
dispatch('resetIssues');
2021-02-22 17:27:13 +05:30
},
2022-07-23 23:45:48 +05:30
fetchLists: ({ commit, state, dispatch }, { resetLists = false } = {}) => {
2021-06-08 01:23:25 +05:30
const { boardType, filterParams, fullPath, fullBoardId, issuableType } = state;
2020-11-24 15:15:51 +05:30
const variables = {
fullPath,
2021-06-08 01:23:25 +05:30
boardId: fullBoardId,
2021-01-03 14:25:43 +05:30
filters: filterParams,
2021-06-08 01:23:25 +05:30
...(issuableType === issuableTypes.issue && {
isGroup: boardType === BoardType.group,
isProject: boardType === BoardType.project,
}),
2020-11-24 15:15:51 +05:30
};
return gqlClient
.query({
2021-06-08 01:23:25 +05:30
query: listsQuery[issuableType].query,
2020-11-24 15:15:51 +05:30
variables,
2022-07-23 23:45:48 +05:30
...(resetLists ? { fetchPolicy: fetchPolicies.NO_CACHE } : {}),
2020-11-24 15:15:51 +05:30
})
.then(({ data }) => {
2022-07-16 23:28:13 +05:30
const { lists, hideBacklogList } = data[boardType].board;
2021-01-03 14:25:43 +05:30
commit(types.RECEIVE_BOARD_LISTS_SUCCESS, formatBoardLists(lists));
// Backlog list needs to be created if it doesn't exist and it's not hidden
2021-03-08 18:12:59 +05:30
if (!lists.nodes.find((l) => l.listType === ListType.backlog) && !hideBacklogList) {
2020-11-24 15:15:51 +05:30
dispatch('createList', { backlog: true });
}
})
2021-01-03 14:25:43 +05:30
.catch(() => commit(types.RECEIVE_BOARD_LISTS_FAILURE));
2020-11-24 15:15:51 +05:30
},
2021-03-11 19:13:27 +05:30
highlightList: ({ commit, state }, listId) => {
if ([ListType.backlog, ListType.closed].includes(state.boardLists[listId].listType)) {
return;
}
commit(types.ADD_LIST_TO_HIGHLIGHTED_LISTS, listId);
setTimeout(() => {
commit(types.REMOVE_LIST_FROM_HIGHLIGHTED_LISTS, listId);
}, flashAnimationDuration);
},
2021-04-17 20:07:23 +05:30
createList: ({ dispatch }, { backlog, labelId, milestoneId, assigneeId }) => {
dispatch('createIssueList', { backlog, labelId, milestoneId, assigneeId });
},
createIssueList: (
2021-03-11 19:13:27 +05:30
{ state, commit, dispatch, getters },
2021-04-17 20:07:23 +05:30
{ backlog, labelId, milestoneId, assigneeId, iterationId },
2021-03-11 19:13:27 +05:30
) => {
2021-06-08 01:23:25 +05:30
const { fullBoardId } = state;
2021-01-03 14:25:43 +05:30
2021-03-11 19:13:27 +05:30
const existingList = getters.getListByLabelId(labelId);
if (existingList) {
dispatch('highlightList', existingList.id);
return;
}
2020-11-24 15:15:51 +05:30
gqlClient
.mutate({
mutation: createBoardListMutation,
variables: {
2021-06-08 01:23:25 +05:30
boardId: fullBoardId,
2020-11-24 15:15:51 +05:30
backlog,
2021-01-03 14:25:43 +05:30
labelId,
milestoneId,
assigneeId,
2021-04-17 20:07:23 +05:30
iterationId,
2020-11-24 15:15:51 +05:30
},
})
.then(({ data }) => {
2021-04-17 20:07:23 +05:30
if (data.boardListCreate?.errors.length) {
commit(types.CREATE_LIST_FAILURE, data.boardListCreate.errors[0]);
2020-11-24 15:15:51 +05:30
} else {
const list = data.boardListCreate?.list;
dispatch('addList', list);
2021-03-11 19:13:27 +05:30
dispatch('highlightList', list.id);
2020-11-24 15:15:51 +05:30
}
})
2021-04-17 20:07:23 +05:30
.catch((e) => {
commit(types.CREATE_LIST_FAILURE);
throw e;
});
2020-11-24 15:15:51 +05:30
},
2021-09-04 01:27:46 +05:30
addList: ({ commit, dispatch, getters }, list) => {
2021-03-08 18:12:59 +05:30
commit(types.RECEIVE_ADD_LIST_SUCCESS, updateListPosition(list));
2021-09-30 23:02:18 +05:30
2021-09-04 01:27:46 +05:30
dispatch('fetchItemsForList', {
2021-09-30 23:02:18 +05:30
listId: getters.getListByTitle(ListTypeTitles.backlog)?.id,
2021-09-04 01:27:46 +05:30
});
2020-11-24 15:15:51 +05:30
},
2021-11-11 11:23:49 +05:30
fetchLabels: ({ state, commit }, searchTerm) => {
2021-03-08 18:12:59 +05:30
const { fullPath, boardType } = state;
2021-01-29 00:20:46 +05:30
const variables = {
fullPath,
searchTerm,
isGroup: boardType === BoardType.group,
isProject: boardType === BoardType.project,
};
2021-04-17 20:07:23 +05:30
commit(types.RECEIVE_LABELS_REQUEST);
2021-01-29 00:20:46 +05:30
return gqlClient
.query({
query: boardLabelsQuery,
variables,
})
.then(({ data }) => {
2021-11-11 11:23:49 +05:30
const labels = data[boardType]?.labels.nodes;
2021-04-17 20:07:23 +05:30
2021-03-11 19:13:27 +05:30
commit(types.RECEIVE_LABELS_SUCCESS, labels);
return labels;
2021-04-17 20:07:23 +05:30
})
.catch((e) => {
commit(types.RECEIVE_LABELS_FAILURE);
throw e;
2021-03-11 19:13:27 +05:30
});
2021-01-29 00:20:46 +05:30
},
2021-10-27 15:23:28 +05:30
fetchMilestones({ state, commit }, searchTerm) {
commit(types.RECEIVE_MILESTONES_REQUEST);
const { fullPath, boardType } = state;
const variables = {
fullPath,
searchTerm,
};
let query;
if (boardType === BoardType.project) {
query = projectBoardMilestonesQuery;
}
if (boardType === BoardType.group) {
query = groupBoardMilestonesQuery;
}
if (!query) {
// eslint-disable-next-line @gitlab/require-i18n-strings
throw new Error('Unknown board type');
}
return gqlClient
.query({
query,
variables,
})
.then(({ data }) => {
const errors = data[boardType]?.errors;
const milestones = data[boardType]?.milestones.nodes;
if (errors?.[0]) {
throw new Error(errors[0]);
}
commit(types.RECEIVE_MILESTONES_SUCCESS, milestones);
return milestones;
})
.catch((e) => {
commit(types.RECEIVE_MILESTONES_FAILURE);
throw e;
});
},
2021-01-03 14:25:43 +05:30
moveList: (
2021-10-27 15:23:28 +05:30
{ state: { boardLists }, commit, dispatch },
{
item: {
dataset: { listId: movedListId, draggableItemType },
},
newIndex,
to: { children },
},
2021-01-03 14:25:43 +05:30
) => {
2021-10-27 15:23:28 +05:30
if (draggableItemType !== DraggableItemTypes.list) {
2021-02-22 17:27:13 +05:30
return;
}
2021-10-27 15:23:28 +05:30
const displacedListId = children[newIndex].dataset.listId;
if (movedListId === displacedListId) {
return;
}
2020-11-24 15:15:51 +05:30
2021-10-27 15:23:28 +05:30
const listIds = sortBy(
Object.keys(boardLists).filter(
(listId) =>
listId !== movedListId &&
boardLists[listId].listType !== ListType.backlog &&
boardLists[listId].listType !== ListType.closed,
),
(i) => boardLists[i].position,
);
2020-11-24 15:15:51 +05:30
2021-10-27 15:23:28 +05:30
const targetPosition = boardLists[displacedListId].position;
// When the dragged list moves left, displaced list should shift right.
const shiftOffset = Number(boardLists[movedListId].position < targetPosition);
const displacedListIndex = listIds.findIndex((listId) => listId === displacedListId);
2020-11-24 15:15:51 +05:30
2021-10-27 15:23:28 +05:30
commit(
types.MOVE_LISTS,
listIds
.slice(0, displacedListIndex + shiftOffset)
.concat([movedListId], listIds.slice(displacedListIndex + shiftOffset))
.map((listId, index) => ({ listId, position: index })),
);
dispatch('updateList', { listId: movedListId, position: targetPosition });
2019-09-04 21:01:54 +05:30
},
2021-06-08 01:23:25 +05:30
updateList: (
2021-10-27 15:23:28 +05:30
{ state: { issuableType, boardItemsByListId = {} }, dispatch },
{ listId, position, collapsed },
2021-06-08 01:23:25 +05:30
) => {
2020-11-24 15:15:51 +05:30
gqlClient
.mutate({
2021-06-08 01:23:25 +05:30
mutation: updateListQueries[issuableType].mutation,
2020-11-24 15:15:51 +05:30
variables: {
listId,
position,
collapsed,
},
})
.then(({ data }) => {
if (data?.updateBoardList?.errors.length) {
2021-10-27 15:23:28 +05:30
throw new Error();
2021-09-30 23:02:18 +05:30
}
// Only fetch when board items havent been fetched on a collapsed list
if (!boardItemsByListId[listId]) {
dispatch('fetchItemsForList', { listId });
2020-11-24 15:15:51 +05:30
}
})
.catch(() => {
2021-10-27 15:23:28 +05:30
dispatch('handleUpdateListFailure');
2020-11-24 15:15:51 +05:30
});
2019-09-04 21:01:54 +05:30
},
2021-10-27 15:23:28 +05:30
handleUpdateListFailure: ({ dispatch, commit }) => {
dispatch('fetchLists');
commit(
types.SET_ERROR,
s__('Boards|An error occurred while updating the board list. Please try again.'),
);
},
2021-04-17 20:07:23 +05:30
toggleListCollapsed: ({ commit }, { listId, collapsed }) => {
commit(types.TOGGLE_LIST_COLLAPSED, { listId, collapsed });
},
2021-09-04 01:27:46 +05:30
removeList: ({ state: { issuableType, boardLists }, commit, dispatch, getters }, listId) => {
2021-06-08 01:23:25 +05:30
const listsBackup = { ...boardLists };
2021-01-29 00:20:46 +05:30
commit(types.REMOVE_LIST, listId);
return gqlClient
.mutate({
2021-06-08 01:23:25 +05:30
mutation: deleteListQueries[issuableType].mutation,
2021-01-29 00:20:46 +05:30
variables: {
listId,
},
})
2021-03-08 18:12:59 +05:30
.then(
({
data: {
destroyBoardList: { errors },
},
}) => {
if (errors.length > 0) {
commit(types.REMOVE_LIST_FAILURE, listsBackup);
2021-09-04 01:27:46 +05:30
} else {
dispatch('fetchItemsForList', {
2021-09-30 23:02:18 +05:30
listId: getters.getListByTitle(ListTypeTitles.backlog)?.id,
2021-09-04 01:27:46 +05:30
});
2021-03-08 18:12:59 +05:30
}
},
)
2021-01-29 00:20:46 +05:30
.catch(() => {
commit(types.REMOVE_LIST_FAILURE, listsBackup);
});
2019-09-04 21:01:54 +05:30
},
2021-04-17 20:07:23 +05:30
fetchItemsForList: ({ state, commit }, { listId, fetchNext = false }) => {
2021-09-30 23:02:18 +05:30
if (!listId) return null;
2021-04-17 20:07:23 +05:30
commit(types.REQUEST_ITEMS_FOR_LIST, { listId, fetchNext });
2021-01-03 14:25:43 +05:30
2021-06-08 01:23:25 +05:30
const { fullPath, fullBoardId, boardType, filterParams } = state;
2020-11-24 15:15:51 +05:30
const variables = {
fullPath,
2021-06-08 01:23:25 +05:30
boardId: fullBoardId,
2020-11-24 15:15:51 +05:30
id: listId,
filters: filterParams,
isGroup: boardType === BoardType.group,
isProject: boardType === BoardType.project,
2022-10-11 01:57:18 +05:30
first: DEFAULT_BOARD_LIST_ITEMS_SIZE,
2021-01-03 14:25:43 +05:30
after: fetchNext ? state.pageInfoByListId[listId].endCursor : undefined,
2020-11-24 15:15:51 +05:30
};
return gqlClient
.query({
query: listsIssuesQuery,
context: {
isSingleRequest: true,
},
variables,
2022-07-23 23:45:48 +05:30
...(!fetchNext ? { fetchPolicy: fetchPolicies.NO_CACHE } : {}),
2020-11-24 15:15:51 +05:30
})
.then(({ data }) => {
2022-07-16 23:28:13 +05:30
const { lists } = data[boardType].board;
2021-04-17 20:07:23 +05:30
const listItems = formatListIssues(lists);
2021-01-03 14:25:43 +05:30
const listPageInfo = formatListsPageInfo(lists);
2021-04-17 20:07:23 +05:30
commit(types.RECEIVE_ITEMS_FOR_LIST_SUCCESS, { listItems, listPageInfo, listId });
2020-11-24 15:15:51 +05:30
})
2021-04-17 20:07:23 +05:30
.catch(() => commit(types.RECEIVE_ITEMS_FOR_LIST_FAILURE, listId));
2019-09-04 21:01:54 +05:30
},
2021-01-03 14:25:43 +05:30
resetIssues: ({ commit }) => {
commit(types.RESET_ISSUES);
2020-10-24 23:57:45 +05:30
},
2021-04-29 21:17:54 +05:30
moveItem: ({ dispatch }, payload) => {
dispatch('moveIssue', payload);
2021-04-17 20:07:23 +05:30
},
2021-04-29 21:17:54 +05:30
moveIssue: ({ dispatch, state }, params) => {
const moveData = getMoveData(state, params);
dispatch('moveIssueCard', moveData);
dispatch('updateMovedIssue', moveData);
dispatch('updateIssueOrder', { moveData });
},
moveIssueCard: ({ commit }, moveData) => {
const {
reordering,
shouldClone,
itemNotInToList,
originalIndex,
itemId,
fromListId,
toListId,
moveBeforeId,
moveAfterId,
2022-10-11 01:57:18 +05:30
positionInList,
allItemsLoadedInList,
2021-04-29 21:17:54 +05:30
} = moveData;
commit(types.REMOVE_BOARD_ITEM_FROM_LIST, { itemId, listId: fromListId });
2022-10-11 01:57:18 +05:30
if (reordering && !allItemsLoadedInList && positionInList === -1) {
return;
}
2021-04-29 21:17:54 +05:30
if (reordering) {
commit(types.ADD_BOARD_ITEM_TO_LIST, {
itemId,
listId: toListId,
moveBeforeId,
moveAfterId,
2022-10-11 01:57:18 +05:30
positionInList,
atIndex: originalIndex,
allItemsLoadedInList,
2021-04-29 21:17:54 +05:30
});
return;
}
if (itemNotInToList) {
commit(types.ADD_BOARD_ITEM_TO_LIST, {
itemId,
listId: toListId,
moveBeforeId,
moveAfterId,
2022-10-11 01:57:18 +05:30
positionInList,
2021-04-29 21:17:54 +05:30
});
}
if (shouldClone) {
commit(types.ADD_BOARD_ITEM_TO_LIST, { itemId, listId: fromListId, atIndex: originalIndex });
}
},
updateMovedIssue: (
{ commit, state: { boardItems, boardLists } },
{ itemId, fromListId, toListId },
2020-11-24 15:15:51 +05:30
) => {
2021-04-29 21:17:54 +05:30
const updatedIssue = moveItemListHelper(
boardItems[itemId],
boardLists[fromListId],
boardLists[toListId],
);
2020-11-24 15:15:51 +05:30
2021-04-29 21:17:54 +05:30
commit(types.UPDATE_BOARD_ITEM, updatedIssue);
},
2020-11-24 15:15:51 +05:30
2021-04-29 21:17:54 +05:30
undoMoveIssueCard: ({ commit }, moveData) => {
const {
reordering,
shouldClone,
itemNotInToList,
itemId,
fromListId,
toListId,
originalIssue,
originalIndex,
} = moveData;
commit(types.UPDATE_BOARD_ITEM, originalIssue);
if (reordering) {
commit(types.REMOVE_BOARD_ITEM_FROM_LIST, { itemId, listId: fromListId });
commit(types.ADD_BOARD_ITEM_TO_LIST, { itemId, listId: fromListId, atIndex: originalIndex });
return;
}
if (shouldClone) {
commit(types.REMOVE_BOARD_ITEM_FROM_LIST, { itemId, listId: fromListId });
}
if (itemNotInToList) {
commit(types.REMOVE_BOARD_ITEM_FROM_LIST, { itemId, listId: toListId });
}
commit(types.ADD_BOARD_ITEM_TO_LIST, { itemId, listId: fromListId, atIndex: originalIndex });
},
updateIssueOrder: async ({ commit, dispatch, state }, { moveData, mutationVariables = {} }) => {
try {
2022-10-11 01:57:18 +05:30
const {
itemId,
fromListId,
toListId,
moveBeforeId,
moveAfterId,
itemNotInToList,
positionInList,
} = moveData;
2021-04-29 21:17:54 +05:30
const {
2021-06-08 01:23:25 +05:30
fullBoardId,
2022-01-26 12:08:38 +05:30
filterParams,
2021-04-29 21:17:54 +05:30
boardItems: {
[itemId]: { iid, referencePath },
},
} = state;
2022-10-11 01:57:18 +05:30
commit(types.MUTATE_ISSUE_IN_PROGRESS, true);
2021-04-29 21:17:54 +05:30
const { data } = await gqlClient.mutate({
2020-11-24 15:15:51 +05:30
mutation: issueMoveListMutation,
variables: {
2021-04-29 21:17:54 +05:30
iid,
projectPath: referencePath.split(/[#]/)[0],
2021-06-08 01:23:25 +05:30
boardId: fullBoardId,
2020-11-24 15:15:51 +05:30
fromListId: getIdFromGraphQLId(fromListId),
toListId: getIdFromGraphQLId(toListId),
2021-11-11 11:23:49 +05:30
moveBeforeId: moveBeforeId ? getIdFromGraphQLId(moveBeforeId) : undefined,
moveAfterId: moveAfterId ? getIdFromGraphQLId(moveAfterId) : undefined,
2022-10-11 01:57:18 +05:30
positionInList,
2021-04-29 21:17:54 +05:30
// 'mutationVariables' allows EE code to pass in extra parameters.
...mutationVariables,
2020-11-24 15:15:51 +05:30
},
2022-01-26 12:08:38 +05:30
update(
cache,
{
data: {
issueMoveList: {
issue: { weight },
},
},
},
) {
if (fromListId === toListId) return;
const updateFromList = () => {
const fromList = cache.readQuery({
query: totalCountAndWeightQuery,
variables: { id: fromListId, filters: filterParams },
});
const updatedFromList = {
boardList: {
__typename: 'BoardList',
id: fromList.boardList.id,
issuesCount: fromList.boardList.issuesCount - 1,
totalWeight: fromList.boardList.totalWeight - Number(weight),
},
};
cache.writeQuery({
query: totalCountAndWeightQuery,
variables: { id: fromListId, filters: filterParams },
data: updatedFromList,
});
};
const updateToList = () => {
if (!itemNotInToList) return;
const toList = cache.readQuery({
query: totalCountAndWeightQuery,
variables: { id: toListId, filters: filterParams },
});
const updatedToList = {
boardList: {
__typename: 'BoardList',
id: toList.boardList.id,
issuesCount: toList.boardList.issuesCount + 1,
totalWeight: toList.boardList.totalWeight + Number(weight),
},
};
cache.writeQuery({
query: totalCountAndWeightQuery,
variables: { id: toListId, filters: filterParams },
data: updatedToList,
});
};
updateFromList();
updateToList();
},
2021-04-29 21:17:54 +05:30
});
if (data?.issueMoveList?.errors.length || !data.issueMoveList) {
throw new Error('issueMoveList empty');
}
commit(types.MUTATE_ISSUE_SUCCESS, { issue: data.issueMoveList.issue });
2022-10-11 01:57:18 +05:30
commit(types.MUTATE_ISSUE_IN_PROGRESS, false);
2021-04-29 21:17:54 +05:30
} catch {
2022-10-11 01:57:18 +05:30
commit(types.MUTATE_ISSUE_IN_PROGRESS, false);
2021-04-29 21:17:54 +05:30
commit(
types.SET_ERROR,
s__('Boards|An error occurred while moving the issue. Please try again.'),
2020-11-24 15:15:51 +05:30
);
2021-04-29 21:17:54 +05:30
dispatch('undoMoveIssueCard', moveData);
}
2019-09-04 21:01:54 +05:30
},
2021-09-30 23:02:18 +05:30
setAssignees: ({ commit }, { id, assignees }) => {
2021-04-29 21:17:54 +05:30
commit('UPDATE_BOARD_ITEM_BY_ID', {
2021-09-30 23:02:18 +05:30
itemId: id,
2021-03-11 19:13:27 +05:30
prop: 'assignees',
2021-09-30 23:02:18 +05:30
value: assignees,
2021-03-11 19:13:27 +05:30
});
2021-01-29 00:20:46 +05:30
},
2021-11-18 22:05:49 +05:30
addListItem: ({ commit, dispatch }, { list, item, position, inProgress = false }) => {
2021-09-04 01:27:46 +05:30
commit(types.ADD_BOARD_ITEM_TO_LIST, {
listId: list.id,
itemId: item.id,
atIndex: position,
inProgress,
2021-02-22 17:27:13 +05:30
});
2021-04-29 21:17:54 +05:30
commit(types.UPDATE_BOARD_ITEM, item);
2021-11-18 22:05:49 +05:30
if (!inProgress) {
dispatch('setActiveId', { id: item.id, sidebarType: ISSUABLE });
}
2021-04-29 21:17:54 +05:30
},
removeListItem: ({ commit }, { listId, itemId }) => {
commit(types.REMOVE_BOARD_ITEM_FROM_LIST, { listId, itemId });
commit(types.REMOVE_BOARD_ITEM, itemId);
},
2021-03-08 18:12:59 +05:30
2021-04-29 21:17:54 +05:30
addListNewIssue: (
2022-01-26 12:08:38 +05:30
{ state: { boardConfig, boardType, fullPath, filterParams }, dispatch, commit },
2021-04-29 21:17:54 +05:30
{ issueInput, list, placeholderId = `tmp-${new Date().getTime()}` },
) => {
2021-03-08 18:12:59 +05:30
const input = formatIssueInput(issueInput, boardConfig);
2021-01-29 00:20:46 +05:30
if (boardType === BoardType.project) {
2021-03-08 18:12:59 +05:30
input.projectPath = fullPath;
2021-01-29 00:20:46 +05:30
}
2021-09-04 01:27:46 +05:30
const placeholderIssue = formatIssue({ ...issueInput, id: placeholderId, isLoading: true });
dispatch('addListItem', { list, item: placeholderIssue, position: 0, inProgress: true });
2021-04-29 21:17:54 +05:30
gqlClient
2021-01-29 00:20:46 +05:30
.mutate({
mutation: issueCreateMutation,
variables: { input },
2022-01-26 12:08:38 +05:30
update(cache) {
const fromList = cache.readQuery({
query: totalCountAndWeightQuery,
variables: { id: list.id, filters: filterParams },
});
const updatedList = {
boardList: {
__typename: 'BoardList',
id: fromList.boardList.id,
issuesCount: fromList.boardList.issuesCount + 1,
totalWeight: fromList.boardList.totalWeight,
},
};
cache.writeQuery({
query: totalCountAndWeightQuery,
variables: { id: list.id, filters: filterParams },
data: updatedList,
});
},
2021-01-29 00:20:46 +05:30
})
.then(({ data }) => {
if (data.createIssue.errors.length) {
2021-04-29 21:17:54 +05:30
throw new Error();
2021-01-29 00:20:46 +05:30
}
2019-09-04 21:01:54 +05:30
2021-04-29 21:17:54 +05:30
const rawIssue = data.createIssue?.issue;
2021-11-11 11:23:49 +05:30
const formattedIssue = formatIssue(rawIssue);
2021-04-29 21:17:54 +05:30
dispatch('removeListItem', { listId: list.id, itemId: placeholderId });
dispatch('addListItem', { list, item: formattedIssue, position: 0 });
})
.catch(() => {
dispatch('removeListItem', { listId: list.id, itemId: placeholderId });
commit(
types.SET_ERROR,
s__('Boards|An error occurred while creating the issue. Please try again.'),
);
});
2020-11-24 15:15:51 +05:30
},
2021-04-29 21:17:54 +05:30
setActiveBoardItemLabels: ({ dispatch }, params) => {
dispatch('setActiveIssueLabels', params);
2020-11-24 15:15:51 +05:30
},
2021-01-03 14:25:43 +05:30
setActiveIssueLabels: async ({ commit, getters }, input) => {
2021-04-29 21:17:54 +05:30
const { activeBoardItem } = getters;
2021-12-11 22:18:48 +05:30
let labels = input?.labels || [];
if (input.removeLabelIds) {
labels = activeBoardItem.labels.filter(
(label) => input.removeLabelIds[0] !== getIdFromGraphQLId(label.id),
);
}
2021-04-29 21:17:54 +05:30
commit(types.UPDATE_BOARD_ITEM_BY_ID, {
2021-12-11 22:18:48 +05:30
itemId: input.id || activeBoardItem.id,
2021-01-03 14:25:43 +05:30
prop: 'labels',
2021-12-11 22:18:48 +05:30
value: labels,
2021-01-03 14:25:43 +05:30
});
},
2021-04-29 21:17:54 +05:30
setActiveItemSubscribed: async ({ commit, getters, state }, input) => {
const { activeBoardItem, isEpicBoard } = getters;
const { fullPath, issuableType } = state;
const workspacePath = isEpicBoard
? { groupPath: fullPath }
: { projectPath: input.projectPath };
2021-01-29 00:20:46 +05:30
const { data } = await gqlClient.mutate({
2021-04-29 21:17:54 +05:30
mutation: subscriptionQueries[issuableType].mutation,
2021-01-29 00:20:46 +05:30
variables: {
input: {
2021-04-29 21:17:54 +05:30
...workspacePath,
iid: String(activeBoardItem.iid),
2021-01-29 00:20:46 +05:30
subscribedState: input.subscribed,
},
},
});
2021-04-29 21:17:54 +05:30
if (data.updateIssuableSubscription?.errors?.length > 0) {
throw new Error(data.updateIssuableSubscription[issuableType].errors);
2021-01-29 00:20:46 +05:30
}
2021-04-29 21:17:54 +05:30
commit(types.UPDATE_BOARD_ITEM_BY_ID, {
itemId: activeBoardItem.id,
2021-01-29 00:20:46 +05:30
prop: 'subscribed',
2021-04-29 21:17:54 +05:30
value: data.updateIssuableSubscription[issuableType].subscribed,
2021-01-29 00:20:46 +05:30
});
},
2021-04-29 21:17:54 +05:30
setActiveItemTitle: async ({ commit, getters, state }, input) => {
const { activeBoardItem, isEpicBoard } = getters;
const { fullPath, issuableType } = state;
const workspacePath = isEpicBoard
? { groupPath: fullPath }
: { projectPath: input.projectPath };
2021-03-08 18:12:59 +05:30
const { data } = await gqlClient.mutate({
2021-04-29 21:17:54 +05:30
mutation: titleQueries[issuableType].mutation,
2021-03-08 18:12:59 +05:30
variables: {
input: {
2021-04-29 21:17:54 +05:30
...workspacePath,
iid: String(activeBoardItem.iid),
2021-03-08 18:12:59 +05:30
title: input.title,
},
},
});
2021-04-29 21:17:54 +05:30
if (data.updateIssuableTitle?.errors?.length > 0) {
throw new Error(data.updateIssuableTitle.errors);
2021-03-08 18:12:59 +05:30
}
2021-04-29 21:17:54 +05:30
commit(types.UPDATE_BOARD_ITEM_BY_ID, {
itemId: activeBoardItem.id,
2021-03-08 18:12:59 +05:30
prop: 'title',
2021-04-29 21:17:54 +05:30
value: data.updateIssuableTitle[issuableType].title,
2021-03-08 18:12:59 +05:30
});
},
2021-06-08 01:23:25 +05:30
setActiveItemConfidential: ({ commit, getters }, confidential) => {
const { activeBoardItem } = getters;
commit(types.UPDATE_BOARD_ITEM_BY_ID, {
itemId: activeBoardItem.id,
prop: 'confidential',
value: confidential,
});
},
2021-03-08 18:12:59 +05:30
fetchGroupProjects: ({ commit, state }, { search = '', fetchNext = false }) => {
commit(types.REQUEST_GROUP_PROJECTS, fetchNext);
const { fullPath } = state;
const variables = {
fullPath,
search: search !== '' ? search : undefined,
after: fetchNext ? state.groupProjectsFlags.pageInfo.endCursor : undefined,
};
return gqlClient
.query({
query: groupProjectsQuery,
variables,
})
.then(({ data }) => {
const { projects } = data.group;
commit(types.RECEIVE_GROUP_PROJECTS_SUCCESS, {
projects: projects.nodes,
pageInfo: projects.pageInfo,
fetchNext,
});
})
.catch(() => commit(types.RECEIVE_GROUP_PROJECTS_FAILURE));
},
setSelectedProject: ({ commit }, project) => {
commit(types.SET_SELECTED_PROJECT, project);
},
2021-04-17 20:07:23 +05:30
toggleBoardItemMultiSelection: ({ commit, state, dispatch, getters }, boardItem) => {
2021-03-11 19:13:27 +05:30
const { selectedBoardItems } = state;
const index = selectedBoardItems.indexOf(boardItem);
2021-04-29 21:17:54 +05:30
// If user already selected an item (activeBoardItem) without using mult-select,
2021-04-17 20:07:23 +05:30
// include that item in the selection and unset state.ActiveId to hide the sidebar.
2021-04-29 21:17:54 +05:30
if (getters.activeBoardItem) {
commit(types.ADD_BOARD_ITEM_TO_SELECTION, getters.activeBoardItem);
2021-04-17 20:07:23 +05:30
dispatch('unsetActiveId');
}
2021-03-11 19:13:27 +05:30
if (index === -1) {
commit(types.ADD_BOARD_ITEM_TO_SELECTION, boardItem);
} else {
commit(types.REMOVE_BOARD_ITEM_FROM_SELECTION, boardItem);
}
},
setAddColumnFormVisibility: ({ commit }, visible) => {
commit(types.SET_ADD_COLUMN_FORM_VISIBLE, visible);
},
2021-04-17 20:07:23 +05:30
resetBoardItemMultiSelection: ({ commit }) => {
commit(types.RESET_BOARD_ITEM_SELECTION);
},
toggleBoardItem: ({ state, dispatch }, { boardItem, sidebarType = ISSUABLE }) => {
dispatch('resetBoardItemMultiSelection');
if (boardItem.id === state.activeId) {
dispatch('unsetActiveId');
} else {
dispatch('setActiveId', { id: boardItem.id, sidebarType });
}
},
2021-09-04 01:27:46 +05:30
setError: ({ commit }, { message, error, captureError = true }) => {
2021-04-29 21:17:54 +05:30
commit(types.SET_ERROR, message);
if (captureError) {
Sentry.captureException(error);
}
},
unsetError: ({ commit }) => {
commit(types.SET_ERROR, undefined);
},
2021-09-30 23:02:18 +05:30
// EE action needs CE empty equivalent
setActiveItemWeight: () => {},
2019-09-04 21:01:54 +05:30
};