From c3195e83a8ba7ac54516fa9f08340e4dd442f63b Mon Sep 17 00:00:00 2001 From: Jacob Schatz Date: Thu, 12 Oct 2017 21:04:17 +0000 Subject: Add create merge checkbox. --- app/assets/javascripts/api.js | 14 ++ app/assets/javascripts/lib/utils/url_utility.js | 4 +- .../repo/components/repo_commit_section.vue | 91 ++++++++++- app/assets/javascripts/repo/index.js | 3 + .../javascripts/repo/services/repo_service.js | 4 + app/assets/javascripts/repo/stores/repo_store.js | 18 +++ .../vue_shared/components/popup_dialog.vue | 13 +- app/views/shared/repo/_repo.html.haml | 2 + changelogs/unreleased/new-mr-repo-editor.yml | 5 + .../helpers/set_timeout_promise_helper.js | 3 + .../repo/components/repo_commit_section_spec.js | 171 ++++++++++++++------- 11 files changed, 260 insertions(+), 68 deletions(-) create mode 100644 changelogs/unreleased/new-mr-repo-editor.yml create mode 100644 spec/javascripts/helpers/set_timeout_promise_helper.js diff --git a/app/assets/javascripts/api.js b/app/assets/javascripts/api.js index 38d1effc77c..242b3e2b990 100644 --- a/app/assets/javascripts/api.js +++ b/app/assets/javascripts/api.js @@ -15,6 +15,7 @@ const Api = { issuableTemplatePath: '/:namespace_path/:project_path/templates/:type/:key', usersPath: '/api/:version/users.json', commitPath: '/api/:version/projects/:id/repository/commits', + branchSinglePath: '/api/:version/projects/:id/repository/branches/:branch', group(groupId, callback) { const url = Api.buildUrl(Api.groupPath) @@ -123,6 +124,19 @@ const Api = { }); }, + branchSingle(id, branch) { + const url = Api.buildUrl(Api.branchSinglePath) + .replace(':id', id) + .replace(':branch', branch); + + return this.wrapAjaxCall({ + url, + type: 'GET', + contentType: 'application/json; charset=utf-8', + dataType: 'json', + }); + }, + // Return text for a specific license licenseText(key, data, callback) { const url = Api.buildUrl(Api.licensePath) diff --git a/app/assets/javascripts/lib/utils/url_utility.js b/app/assets/javascripts/lib/utils/url_utility.js index 78c7a094127..1aa63216baf 100644 --- a/app/assets/javascripts/lib/utils/url_utility.js +++ b/app/assets/javascripts/lib/utils/url_utility.js @@ -85,7 +85,7 @@ w.gl.utils.getLocationHash = function(url) { return hashIndex === -1 ? null : url.substring(hashIndex + 1); }; -w.gl.utils.refreshCurrentPage = () => gl.utils.visitUrl(document.location.href); +w.gl.utils.refreshCurrentPage = () => gl.utils.visitUrl(window.location.href); // eslint-disable-next-line import/prefer-default-export export function visitUrl(url, external = false) { @@ -96,7 +96,7 @@ export function visitUrl(url, external = false) { otherWindow.opener = null; otherWindow.location = url; } else { - document.location.href = url; + window.location.href = url; } } diff --git a/app/assets/javascripts/repo/components/repo_commit_section.vue b/app/assets/javascripts/repo/components/repo_commit_section.vue index 6d8cc964eb2..c0dc4c8cd8b 100644 --- a/app/assets/javascripts/repo/components/repo_commit_section.vue +++ b/app/assets/javascripts/repo/components/repo_commit_section.vue @@ -3,11 +3,17 @@ import Flash from '../../flash'; import Store from '../stores/repo_store'; import RepoMixin from '../mixins/repo_mixin'; import Service from '../services/repo_service'; +import PopupDialog from '../../vue_shared/components/popup_dialog.vue'; +import { visitUrl } from '../../lib/utils/url_utility'; export default { + mixins: [RepoMixin], + data: () => Store, - mixins: [RepoMixin], + components: { + PopupDialog, + }, computed: { showCommitable() { @@ -28,7 +34,16 @@ export default { }, methods: { - makeCommit() { + commitToNewBranch(status) { + if (status) { + this.showNewBranchDialog = false; + this.tryCommit(null, true, true); + } else { + // reset the state + } + }, + + makeCommit(newBranch) { // see https://docs.gitlab.com/ce/api/commits.html#create-a-commit-with-multiple-files-and-actions const commitMessage = this.commitMessage; const actions = this.changedFiles.map(f => ({ @@ -36,19 +51,63 @@ export default { file_path: f.path, content: f.newContent, })); + const branch = newBranch ? `${this.currentBranch}-${this.currentShortHash}` : this.currentBranch; const payload = { - branch: Store.currentBranch, + branch, commit_message: commitMessage, actions, }; - Store.submitCommitsLoading = true; + if (newBranch) { + payload.start_branch = this.currentBranch; + } + this.submitCommitsLoading = true; Service.commitFiles(payload) - .then(this.resetCommitState) - .catch(() => Flash('An error occurred while committing your changes')); + .then(() => { + this.resetCommitState(); + if (this.startNewMR) { + this.redirectToNewMr(branch); + } else { + this.redirectToBranch(branch); + } + }) + .catch(() => { + Flash('An error occurred while committing your changes'); + }); + }, + + tryCommit(e, skipBranchCheck = false, newBranch = false) { + if (skipBranchCheck) { + this.makeCommit(newBranch); + } else { + Store.setBranchHash() + .then(() => { + if (Store.branchChanged) { + Store.showNewBranchDialog = true; + return; + } + this.makeCommit(newBranch); + }) + .catch(() => { + Flash('An error occurred while committing your changes'); + }); + } + }, + + redirectToNewMr(branch) { + visitUrl(this.newMrTemplateUrl.replace('{{source_branch}}', branch)); + }, + + redirectToBranch(branch) { + visitUrl(this.customBranchURL.replace('{{branch}}', branch)); }, resetCommitState() { this.submitCommitsLoading = false; + this.openedFiles = this.openedFiles.map((file) => { + const f = file; + f.changed = false; + return f; + }); this.changedFiles = []; this.commitMessage = ''; this.editMode = false; @@ -62,9 +121,17 @@ export default {
+
+ @submit.prevent="tryCommit">
+
+
+ +
+
diff --git a/app/assets/javascripts/repo/index.js b/app/assets/javascripts/repo/index.js index 7d0123e3d3a..1a09f411b22 100644 --- a/app/assets/javascripts/repo/index.js +++ b/app/assets/javascripts/repo/index.js @@ -31,8 +31,11 @@ function setInitialStore(data) { Store.projectUrl = data.projectUrl; Store.canCommit = data.canCommit; Store.onTopOfBranch = data.onTopOfBranch; + Store.newMrTemplateUrl = decodeURIComponent(data.newMrTemplateUrl); + Store.customBranchURL = decodeURIComponent(data.blobUrl); Store.currentBranch = $('button.dropdown-menu-toggle').attr('data-ref'); Store.checkIsCommitable(); + Store.setBranchHash(); } function initRepo(el) { diff --git a/app/assets/javascripts/repo/services/repo_service.js b/app/assets/javascripts/repo/services/repo_service.js index 830685f7e6e..d68d71a4629 100644 --- a/app/assets/javascripts/repo/services/repo_service.js +++ b/app/assets/javascripts/repo/services/repo_service.js @@ -64,6 +64,10 @@ const RepoService = { return urlArray.join('/'); }, + getBranch() { + return Api.branchSingle(Store.projectId, Store.currentBranch); + }, + commitFiles(payload) { return Api.commitMultiple(Store.projectId, payload) .then(this.commitFlash); diff --git a/app/assets/javascripts/repo/stores/repo_store.js b/app/assets/javascripts/repo/stores/repo_store.js index c633f538c1b..f8d29af7ffe 100644 --- a/app/assets/javascripts/repo/stores/repo_store.js +++ b/app/assets/javascripts/repo/stores/repo_store.js @@ -23,6 +23,7 @@ const RepoStore = { title: '', status: false, }, + showNewBranchDialog: false, activeFile: Helper.getDefaultActiveFile(), activeFileIndex: 0, activeLine: -1, @@ -31,6 +32,12 @@ const RepoStore = { isCommitable: false, binary: false, currentBranch: '', + startNewMR: false, + currentHash: '', + currentShortHash: '', + customBranchURL: '', + newMrTemplateUrl: '', + branchChanged: false, commitMessage: '', binaryTypes: { png: false, @@ -49,6 +56,17 @@ const RepoStore = { }); }, + setBranchHash() { + return Service.getBranch() + .then((data) => { + if (RepoStore.currentHash !== '' && data.commit.id !== RepoStore.currentHash) { + RepoStore.branchChanged = true; + } + RepoStore.currentHash = data.commit.id; + RepoStore.currentShortHash = data.commit.short_id; + }); + }, + // mutations checkIsCommitable() { RepoStore.isCommitable = RepoStore.onTopOfBranch && RepoStore.canCommit; diff --git a/app/assets/javascripts/vue_shared/components/popup_dialog.vue b/app/assets/javascripts/vue_shared/components/popup_dialog.vue index 9279b50cd55..7d8c5936b7d 100644 --- a/app/assets/javascripts/vue_shared/components/popup_dialog.vue +++ b/app/assets/javascripts/vue_shared/components/popup_dialog.vue @@ -16,6 +16,11 @@ export default { required: false, default: 'primary', }, + closeKind: { + type: String, + required: false, + default: 'default', + }, closeButtonLabel: { type: String, required: false, @@ -33,6 +38,11 @@ export default { [`btn-${this.kind}`]: true, }; }, + btnCancelKindClass() { + return { + [`btn-${this.closeKind}`]: true, + }; + }, }, methods: { @@ -70,7 +80,8 @@ export default {