239 lines
7.6 KiB
JavaScript
239 lines
7.6 KiB
JavaScript
import createFlash from '~/flash';
|
|
import { __ } from '~/locale';
|
|
import { leftSidebarViews, PERMISSION_READ_MR, MAX_MR_FILES_AUTO_OPEN } from '../../constants';
|
|
import service from '../../services';
|
|
import * as types from '../mutation_types';
|
|
|
|
export const getMergeRequestsForBranch = (
|
|
{ commit, state, getters },
|
|
{ projectId, branchId } = {},
|
|
) => {
|
|
if (!getters.findProjectPermissions(projectId)[PERMISSION_READ_MR]) {
|
|
return Promise.resolve();
|
|
}
|
|
|
|
return service
|
|
.getProjectMergeRequests(`${projectId}`, {
|
|
source_branch: branchId,
|
|
source_project_id: state.projects[projectId].id,
|
|
state: 'opened',
|
|
order_by: 'created_at',
|
|
per_page: 1,
|
|
})
|
|
.then(({ data }) => {
|
|
if (data.length > 0) {
|
|
const currentMR = data[0];
|
|
|
|
commit(types.SET_MERGE_REQUEST, {
|
|
projectPath: projectId,
|
|
mergeRequestId: currentMR.iid,
|
|
mergeRequest: currentMR,
|
|
});
|
|
|
|
commit(types.SET_CURRENT_MERGE_REQUEST, `${currentMR.iid}`);
|
|
}
|
|
})
|
|
.catch((e) => {
|
|
createFlash({
|
|
message: __(`Error fetching merge requests for ${branchId}`),
|
|
fadeTransition: false,
|
|
addBodyClass: true,
|
|
});
|
|
throw e;
|
|
});
|
|
};
|
|
|
|
export const getMergeRequestData = (
|
|
{ commit, dispatch, state },
|
|
{ projectId, mergeRequestId, targetProjectId = null, force = false } = {},
|
|
) =>
|
|
new Promise((resolve, reject) => {
|
|
if (!state.projects[projectId].mergeRequests[mergeRequestId] || force) {
|
|
service
|
|
.getProjectMergeRequestData(targetProjectId || projectId, mergeRequestId)
|
|
.then(({ data }) => {
|
|
commit(types.SET_MERGE_REQUEST, {
|
|
projectPath: projectId,
|
|
mergeRequestId,
|
|
mergeRequest: data,
|
|
});
|
|
commit(types.SET_CURRENT_MERGE_REQUEST, mergeRequestId);
|
|
resolve(data);
|
|
})
|
|
.catch(() => {
|
|
dispatch('setErrorMessage', {
|
|
text: __('An error occurred while loading the merge request.'),
|
|
action: (payload) =>
|
|
dispatch('getMergeRequestData', payload).then(() =>
|
|
dispatch('setErrorMessage', null),
|
|
),
|
|
actionText: __('Please try again'),
|
|
actionPayload: { projectId, mergeRequestId, force },
|
|
});
|
|
reject(new Error(`Merge request not loaded ${projectId}`));
|
|
});
|
|
} else {
|
|
resolve(state.projects[projectId].mergeRequests[mergeRequestId]);
|
|
}
|
|
});
|
|
|
|
export const getMergeRequestChanges = (
|
|
{ commit, dispatch, state },
|
|
{ projectId, mergeRequestId, targetProjectId = null, force = false } = {},
|
|
) =>
|
|
new Promise((resolve, reject) => {
|
|
if (!state.projects[projectId].mergeRequests[mergeRequestId].changes.length || force) {
|
|
service
|
|
.getProjectMergeRequestChanges(targetProjectId || projectId, mergeRequestId)
|
|
.then(({ data }) => {
|
|
commit(types.SET_MERGE_REQUEST_CHANGES, {
|
|
projectPath: projectId,
|
|
mergeRequestId,
|
|
changes: data,
|
|
});
|
|
resolve(data);
|
|
})
|
|
.catch(() => {
|
|
dispatch('setErrorMessage', {
|
|
text: __('An error occurred while loading the merge request changes.'),
|
|
action: (payload) =>
|
|
dispatch('getMergeRequestChanges', payload).then(() =>
|
|
dispatch('setErrorMessage', null),
|
|
),
|
|
actionText: __('Please try again'),
|
|
actionPayload: { projectId, mergeRequestId, force },
|
|
});
|
|
reject(new Error(`Merge request changes not loaded ${projectId}`));
|
|
});
|
|
} else {
|
|
resolve(state.projects[projectId].mergeRequests[mergeRequestId].changes);
|
|
}
|
|
});
|
|
|
|
export const getMergeRequestVersions = (
|
|
{ commit, dispatch, state },
|
|
{ projectId, mergeRequestId, targetProjectId = null, force = false } = {},
|
|
) =>
|
|
new Promise((resolve, reject) => {
|
|
if (!state.projects[projectId].mergeRequests[mergeRequestId].versions.length || force) {
|
|
service
|
|
.getProjectMergeRequestVersions(targetProjectId || projectId, mergeRequestId)
|
|
.then((res) => res.data)
|
|
.then((data) => {
|
|
commit(types.SET_MERGE_REQUEST_VERSIONS, {
|
|
projectPath: projectId,
|
|
mergeRequestId,
|
|
versions: data,
|
|
});
|
|
resolve(data);
|
|
})
|
|
.catch(() => {
|
|
dispatch('setErrorMessage', {
|
|
text: __('An error occurred while loading the merge request version data.'),
|
|
action: (payload) =>
|
|
dispatch('getMergeRequestVersions', payload).then(() =>
|
|
dispatch('setErrorMessage', null),
|
|
),
|
|
actionText: __('Please try again'),
|
|
actionPayload: { projectId, mergeRequestId, force },
|
|
});
|
|
reject(new Error(`Merge request versions not loaded ${projectId}`));
|
|
});
|
|
} else {
|
|
resolve(state.projects[projectId].mergeRequests[mergeRequestId].versions);
|
|
}
|
|
});
|
|
|
|
export const openMergeRequestChanges = async ({ dispatch, getters, state, commit }, changes) => {
|
|
const entryChanges = changes
|
|
.map((change) => ({ entry: state.entries[change.new_path], change }))
|
|
.filter((x) => x.entry);
|
|
|
|
const pathsToOpen = entryChanges
|
|
.slice(0, MAX_MR_FILES_AUTO_OPEN)
|
|
.map(({ change }) => change.new_path);
|
|
|
|
// If there are no changes with entries, do nothing.
|
|
if (!entryChanges.length) {
|
|
return;
|
|
}
|
|
|
|
dispatch('updateActivityBarView', leftSidebarViews.review.name);
|
|
|
|
entryChanges.forEach(({ change, entry }) => {
|
|
commit(types.SET_FILE_MERGE_REQUEST_CHANGE, { file: entry, mrChange: change });
|
|
});
|
|
|
|
// Open paths in order as they appear in MR changes
|
|
pathsToOpen.forEach((path) => {
|
|
commit(types.TOGGLE_FILE_OPEN, path);
|
|
});
|
|
|
|
// Activate first path.
|
|
// We don't `getFileData` here since the editor component kicks that off. Otherwise, we'd fetch twice.
|
|
const [firstPath, ...remainingPaths] = pathsToOpen;
|
|
await dispatch('router/push', getters.getUrlForPath(firstPath));
|
|
await dispatch('setFileActive', firstPath);
|
|
|
|
// Lastly, eagerly fetch the remaining paths for improved user experience.
|
|
await Promise.all(
|
|
remainingPaths.map(async (path) => {
|
|
try {
|
|
await dispatch('getFileData', {
|
|
path,
|
|
makeFileActive: false,
|
|
});
|
|
await dispatch('getRawFileData', { path });
|
|
} catch (e) {
|
|
// If one of the file fetches fails, we dont want to blow up the rest of them.
|
|
// eslint-disable-next-line no-console
|
|
console.error('[gitlab] An unexpected error occurred fetching MR file data', e);
|
|
}
|
|
}),
|
|
);
|
|
};
|
|
|
|
export const openMergeRequest = async (
|
|
{ dispatch, getters },
|
|
{ projectId, targetProjectId, mergeRequestId } = {},
|
|
) => {
|
|
try {
|
|
const mr = await dispatch('getMergeRequestData', {
|
|
projectId,
|
|
targetProjectId,
|
|
mergeRequestId,
|
|
});
|
|
|
|
dispatch('setCurrentBranchId', mr.source_branch);
|
|
|
|
await dispatch('getBranchData', {
|
|
projectId,
|
|
branchId: mr.source_branch,
|
|
});
|
|
|
|
const branch = getters.findBranch(projectId, mr.source_branch);
|
|
|
|
await dispatch('getFiles', {
|
|
projectId,
|
|
branchId: mr.source_branch,
|
|
ref: branch.commit.id,
|
|
});
|
|
|
|
await dispatch('getMergeRequestVersions', {
|
|
projectId,
|
|
targetProjectId,
|
|
mergeRequestId,
|
|
});
|
|
|
|
const { changes } = await dispatch('getMergeRequestChanges', {
|
|
projectId,
|
|
targetProjectId,
|
|
mergeRequestId,
|
|
});
|
|
|
|
await dispatch('openMergeRequestChanges', changes);
|
|
} catch (e) {
|
|
createFlash({ message: __('Error while loading the merge request. Please try again.') });
|
|
throw e;
|
|
}
|
|
};
|