summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/boards/stores/actions.js
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/boards/stores/actions.js')
-rw-r--r--app/assets/javascripts/boards/stores/actions.js306
1 files changed, 215 insertions, 91 deletions
diff --git a/app/assets/javascripts/boards/stores/actions.js b/app/assets/javascripts/boards/stores/actions.js
index 19b31ee7291..8005414962c 100644
--- a/app/assets/javascripts/boards/stores/actions.js
+++ b/app/assets/javascripts/boards/stores/actions.js
@@ -1,16 +1,21 @@
+import * as Sentry from '@sentry/browser';
import { pick } from 'lodash';
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 issueMoveListMutation from 'ee_else_ce/boards/graphql/issue_move_list.mutation.graphql';
import {
BoardType,
ListType,
inactiveId,
flashAnimationDuration,
ISSUABLE,
+ titleQueries,
+ subscriptionQueries,
} from '~/boards/constants';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import createGqClient, { fetchPolicies } from '~/lib/graphql';
import { convertObjectPropsToCamelCase, urlParamsToObject } from '~/lib/utils/common_utils';
+import { s__ } from '~/locale';
import {
formatBoardLists,
formatListIssues,
@@ -20,18 +25,17 @@ import {
formatIssueInput,
updateListPosition,
transformNotFilters,
+ moveItemListHelper,
+ getMoveData,
} from '../boards_util';
import boardLabelsQuery from '../graphql/board_labels.query.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 issueCreateMutation from '../graphql/issue_create.mutation.graphql';
-import issueMoveListMutation from '../graphql/issue_move_list.mutation.graphql';
import issueSetDueDateMutation from '../graphql/issue_set_due_date.mutation.graphql';
import issueSetLabelsMutation from '../graphql/issue_set_labels.mutation.graphql';
import issueSetMilestoneMutation from '../graphql/issue_set_milestone.mutation.graphql';
-import issueSetSubscriptionMutation from '../graphql/issue_set_subscription.mutation.graphql';
-import issueSetTitleMutation from '../graphql/issue_set_title.mutation.graphql';
import listsIssuesQuery from '../graphql/lists_issues.query.graphql';
import * as types from './mutation_types';
@@ -68,6 +72,7 @@ export default {
'milestoneTitle',
'releaseTag',
'search',
+ 'myReactionEmoji',
]);
filterParams.not = transformNotFilters(filters);
commit(types.SET_FILTERS, filterParams);
@@ -326,63 +331,155 @@ export default {
commit(types.RESET_ISSUES);
},
- moveItem: ({ dispatch }) => {
- dispatch('moveIssue');
+ moveItem: ({ dispatch }, payload) => {
+ dispatch('moveIssue', payload);
},
- moveIssue: (
- { state, commit },
- { itemId, itemIid, itemPath, fromListId, toListId, moveBeforeId, moveAfterId },
+ 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,
+ } = moveData;
+
+ commit(types.REMOVE_BOARD_ITEM_FROM_LIST, { itemId, listId: fromListId });
+
+ if (reordering) {
+ commit(types.ADD_BOARD_ITEM_TO_LIST, {
+ itemId,
+ listId: toListId,
+ moveBeforeId,
+ moveAfterId,
+ });
+
+ return;
+ }
+
+ if (itemNotInToList) {
+ commit(types.ADD_BOARD_ITEM_TO_LIST, {
+ itemId,
+ listId: toListId,
+ moveBeforeId,
+ moveAfterId,
+ });
+ }
+
+ if (shouldClone) {
+ commit(types.ADD_BOARD_ITEM_TO_LIST, { itemId, listId: fromListId, atIndex: originalIndex });
+ }
+ },
+
+ updateMovedIssue: (
+ { commit, state: { boardItems, boardLists } },
+ { itemId, fromListId, toListId },
) => {
- const originalIssue = state.boardItems[itemId];
- const fromList = state.boardItemsByListId[fromListId];
- const originalIndex = fromList.indexOf(Number(itemId));
- commit(types.MOVE_ISSUE, { originalIssue, fromListId, toListId, moveBeforeId, moveAfterId });
+ const updatedIssue = moveItemListHelper(
+ boardItems[itemId],
+ boardLists[fromListId],
+ boardLists[toListId],
+ );
- const { boardId } = state;
- const [fullProjectPath] = itemPath.split(/[#]/);
+ commit(types.UPDATE_BOARD_ITEM, updatedIssue);
+ },
- gqlClient
- .mutate({
+ 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 {
+ const { itemId, fromListId, toListId, moveBeforeId, moveAfterId } = moveData;
+ const {
+ boardId,
+ boardItems: {
+ [itemId]: { iid, referencePath },
+ },
+ } = state;
+
+ const { data } = await gqlClient.mutate({
mutation: issueMoveListMutation,
variables: {
- projectPath: fullProjectPath,
+ iid,
+ projectPath: referencePath.split(/[#]/)[0],
boardId: fullBoardId(boardId),
- iid: itemIid,
fromListId: getIdFromGraphQLId(fromListId),
toListId: getIdFromGraphQLId(toListId),
moveBeforeId,
moveAfterId,
+ // 'mutationVariables' allows EE code to pass in extra parameters.
+ ...mutationVariables,
},
- })
- .then(({ data }) => {
- if (data?.issueMoveList?.errors.length) {
- throw new Error();
- } else {
- const issue = data.issueMoveList?.issue;
- commit(types.MOVE_ISSUE_SUCCESS, { issue });
- }
- })
- .catch(() =>
- commit(types.MOVE_ISSUE_FAILURE, { originalIssue, fromListId, toListId, originalIndex }),
+ });
+
+ if (data?.issueMoveList?.errors.length || !data.issueMoveList) {
+ throw new Error('issueMoveList empty');
+ }
+
+ commit(types.MUTATE_ISSUE_SUCCESS, { issue: data.issueMoveList.issue });
+ } catch {
+ commit(
+ types.SET_ERROR,
+ s__('Boards|An error occurred while moving the issue. Please try again.'),
);
+ dispatch('undoMoveIssueCard', moveData);
+ }
},
setAssignees: ({ commit, getters }, assigneeUsernames) => {
- commit('UPDATE_ISSUE_BY_ID', {
- issueId: getters.activeIssue.id,
+ commit('UPDATE_BOARD_ITEM_BY_ID', {
+ itemId: getters.activeBoardItem.id,
prop: 'assignees',
value: assigneeUsernames,
});
},
setActiveIssueMilestone: async ({ commit, getters }, input) => {
- const { activeIssue } = getters;
+ const { activeBoardItem } = getters;
const { data } = await gqlClient.mutate({
mutation: issueSetMilestoneMutation,
variables: {
input: {
- iid: String(activeIssue.iid),
+ iid: String(activeBoardItem.iid),
milestoneId: getIdFromGraphQLId(input.milestoneId),
projectPath: input.projectPath,
},
@@ -393,65 +490,71 @@ export default {
throw new Error(data.updateIssue.errors);
}
- commit(types.UPDATE_ISSUE_BY_ID, {
- issueId: activeIssue.id,
+ commit(types.UPDATE_BOARD_ITEM_BY_ID, {
+ itemId: activeBoardItem.id,
prop: 'milestone',
value: data.updateIssue.issue.milestone,
});
},
- createNewIssue: ({ commit, state }, issueInput) => {
- const { boardConfig } = state;
+ addListItem: ({ commit }, { list, item, position }) => {
+ commit(types.ADD_BOARD_ITEM_TO_LIST, { listId: list.id, itemId: item.id, atIndex: position });
+ commit(types.UPDATE_BOARD_ITEM, item);
+ },
+
+ removeListItem: ({ commit }, { listId, itemId }) => {
+ commit(types.REMOVE_BOARD_ITEM_FROM_LIST, { listId, itemId });
+ commit(types.REMOVE_BOARD_ITEM, itemId);
+ },
+ addListNewIssue: (
+ { state: { boardConfig, boardType, fullPath }, dispatch, commit },
+ { issueInput, list, placeholderId = `tmp-${new Date().getTime()}` },
+ ) => {
const input = formatIssueInput(issueInput, boardConfig);
- const { boardType, fullPath } = state;
if (boardType === BoardType.project) {
input.projectPath = fullPath;
}
- return gqlClient
+ const placeholderIssue = formatIssue({ ...issueInput, id: placeholderId });
+ dispatch('addListItem', { list, item: placeholderIssue, position: 0 });
+
+ gqlClient
.mutate({
mutation: issueCreateMutation,
variables: { input },
})
.then(({ data }) => {
if (data.createIssue.errors.length) {
- commit(types.CREATE_ISSUE_FAILURE);
- } else {
- return data.createIssue?.issue;
+ throw new Error();
}
- return null;
- })
- .catch(() => commit(types.CREATE_ISSUE_FAILURE));
- },
- addListIssue: ({ commit }, { list, issue, position }) => {
- commit(types.ADD_ISSUE_TO_LIST, { list, issue, position });
+ const rawIssue = data.createIssue?.issue;
+ const formattedIssue = formatIssue({ ...rawIssue, id: getIdFromGraphQLId(rawIssue.id) });
+ 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.'),
+ );
+ });
},
- addListNewIssue: ({ commit, dispatch }, { issueInput, list }) => {
- const issue = formatIssue({ ...issueInput, id: 'tmp' });
- commit(types.ADD_ISSUE_TO_LIST, { list, issue, position: 0 });
-
- dispatch('createNewIssue', issueInput)
- .then((res) => {
- commit(types.ADD_ISSUE_TO_LIST, {
- list,
- issue: formatIssue({ ...res, id: getIdFromGraphQLId(res.id) }),
- });
- commit(types.REMOVE_ISSUE_FROM_LIST, { list, issue });
- })
- .catch(() => commit(types.ADD_ISSUE_TO_LIST_FAILURE, { list, issueId: issueInput.id }));
+ setActiveBoardItemLabels: ({ dispatch }, params) => {
+ dispatch('setActiveIssueLabels', params);
},
setActiveIssueLabels: async ({ commit, getters }, input) => {
- const { activeIssue } = getters;
+ const { activeBoardItem } = getters;
const { data } = await gqlClient.mutate({
mutation: issueSetLabelsMutation,
variables: {
input: {
- iid: String(activeIssue.iid),
+ iid: String(activeBoardItem.iid),
addLabelIds: input.addLabelIds ?? [],
removeLabelIds: input.removeLabelIds ?? [],
projectPath: input.projectPath,
@@ -463,20 +566,20 @@ export default {
throw new Error(data.updateIssue.errors);
}
- commit(types.UPDATE_ISSUE_BY_ID, {
- issueId: activeIssue.id,
+ commit(types.UPDATE_BOARD_ITEM_BY_ID, {
+ itemId: activeBoardItem.id,
prop: 'labels',
value: data.updateIssue.issue.labels.nodes,
});
},
setActiveIssueDueDate: async ({ commit, getters }, input) => {
- const { activeIssue } = getters;
+ const { activeBoardItem } = getters;
const { data } = await gqlClient.mutate({
mutation: issueSetDueDateMutation,
variables: {
input: {
- iid: String(activeIssue.iid),
+ iid: String(activeBoardItem.iid),
projectPath: input.projectPath,
dueDate: input.dueDate,
},
@@ -487,57 +590,66 @@ export default {
throw new Error(data.updateIssue.errors);
}
- commit(types.UPDATE_ISSUE_BY_ID, {
- issueId: activeIssue.id,
+ commit(types.UPDATE_BOARD_ITEM_BY_ID, {
+ itemId: activeBoardItem.id,
prop: 'dueDate',
value: data.updateIssue.issue.dueDate,
});
},
- setActiveIssueSubscribed: async ({ commit, getters }, input) => {
+ setActiveItemSubscribed: async ({ commit, getters, state }, input) => {
+ const { activeBoardItem, isEpicBoard } = getters;
+ const { fullPath, issuableType } = state;
+ const workspacePath = isEpicBoard
+ ? { groupPath: fullPath }
+ : { projectPath: input.projectPath };
const { data } = await gqlClient.mutate({
- mutation: issueSetSubscriptionMutation,
+ mutation: subscriptionQueries[issuableType].mutation,
variables: {
input: {
- iid: String(getters.activeIssue.iid),
- projectPath: input.projectPath,
+ ...workspacePath,
+ iid: String(activeBoardItem.iid),
subscribedState: input.subscribed,
},
},
});
- if (data.issueSetSubscription?.errors?.length > 0) {
- throw new Error(data.issueSetSubscription.errors);
+ if (data.updateIssuableSubscription?.errors?.length > 0) {
+ throw new Error(data.updateIssuableSubscription[issuableType].errors);
}
- commit(types.UPDATE_ISSUE_BY_ID, {
- issueId: getters.activeIssue.id,
+ commit(types.UPDATE_BOARD_ITEM_BY_ID, {
+ itemId: activeBoardItem.id,
prop: 'subscribed',
- value: data.issueSetSubscription.issue.subscribed,
+ value: data.updateIssuableSubscription[issuableType].subscribed,
});
},
- setActiveIssueTitle: async ({ commit, getters }, input) => {
- const { activeIssue } = getters;
+ setActiveItemTitle: async ({ commit, getters, state }, input) => {
+ const { activeBoardItem, isEpicBoard } = getters;
+ const { fullPath, issuableType } = state;
+ const workspacePath = isEpicBoard
+ ? { groupPath: fullPath }
+ : { projectPath: input.projectPath };
const { data } = await gqlClient.mutate({
- mutation: issueSetTitleMutation,
+ mutation: titleQueries[issuableType].mutation,
variables: {
input: {
- iid: String(activeIssue.iid),
- projectPath: input.projectPath,
+ ...workspacePath,
+ iid: String(activeBoardItem.iid),
title: input.title,
},
},
});
- if (data.updateIssue?.errors?.length > 0) {
- throw new Error(data.updateIssue.errors);
+ if (data.updateIssuableTitle?.errors?.length > 0) {
+ throw new Error(data.updateIssuableTitle.errors);
}
- commit(types.UPDATE_ISSUE_BY_ID, {
- issueId: activeIssue.id,
+ commit(types.UPDATE_BOARD_ITEM_BY_ID, {
+ itemId: activeBoardItem.id,
prop: 'title',
- value: data.updateIssue.issue.title,
+ value: data.updateIssuableTitle[issuableType].title,
});
},
@@ -576,10 +688,10 @@ export default {
const { selectedBoardItems } = state;
const index = selectedBoardItems.indexOf(boardItem);
- // If user already selected an item (activeIssue) without using mult-select,
+ // If user already selected an item (activeBoardItem) without using mult-select,
// include that item in the selection and unset state.ActiveId to hide the sidebar.
- if (getters.activeIssue) {
- commit(types.ADD_BOARD_ITEM_TO_SELECTION, getters.activeIssue);
+ if (getters.activeBoardItem) {
+ commit(types.ADD_BOARD_ITEM_TO_SELECTION, getters.activeBoardItem);
dispatch('unsetActiveId');
}
@@ -608,6 +720,18 @@ export default {
}
},
+ setError: ({ commit }, { message, error, captureError = false }) => {
+ commit(types.SET_ERROR, message);
+
+ if (captureError) {
+ Sentry.captureException(error);
+ }
+ },
+
+ unsetError: ({ commit }) => {
+ commit(types.SET_ERROR, undefined);
+ },
+
fetchBacklog: () => {
notImplemented();
},