Skip to content
Snippets Groups Projects
Unverified Commit 91e1f3c9 authored by Phil Hughes's avatar Phil Hughes
Browse files

Started adding ability for users to create new branch in IDE

parent fec98d0f
No related branches found
No related tags found
No related merge requests found
Showing
with 298 additions and 149 deletions
<script>
import { mapActions, mapState, mapGetters } from 'vuex';
import * as consts from '../../stores/modules/commit/constants';
export default {
data() {
return {
COMMIT_TO_CURRENT_BRANCH: consts.COMMIT_TO_CURRENT_BRANCH,
COMMIT_TO_NEW_BRANCH: consts.COMMIT_TO_NEW_BRANCH,
COMMIT_TO_NEW_BRANCH_MR: consts.COMMIT_TO_NEW_BRANCH_MR,
};
},
computed: {
...mapState([
'currentBranchId',
]),
...mapState('commit', [
'commitAction',
]),
...mapGetters('commit', [
'newBranchName',
]),
},
methods: {
...mapActions('commit', [
'updateCommitAction',
'updateBranchName',
]),
},
};
</script>
<template>
<div>
<fieldset>
<label>
<input
type="radio"
name="commit-action"
:value="COMMIT_TO_CURRENT_BRANCH"
@change="updateCommitAction($event.target.value)"
checked
/>
Commit to <strong>{{ currentBranchId }}</strong> branch
</label>
</fieldset>
<fieldset>
<label>
<input
type="radio"
name="commit-action"
:value="COMMIT_TO_NEW_BRANCH"
@change="updateCommitAction($event.target.value)"
/>
Create a new branch
</label>
<template v-if="commitAction === '2'">
<input
type="text"
class="form-control input-sm"
:placeholder="newBranchName"
@input="updateBranchName($event.target.value)"
/>
</template>
</fieldset>
<fieldset>
<label>
<input
type="radio"
name="commit-action"
:value="COMMIT_TO_NEW_BRANCH_MR"
@change="updateCommitAction($event.target.value)"
/>
Create a new branch and merge request
</label>
</fieldset>
</div>
</template>
<script>
import { mapState, mapActions } from 'vuex';
import { mapState, mapActions, mapGetters } from 'vuex';
import tooltip from '../../vue_shared/directives/tooltip';
import icon from '../../vue_shared/components/icon.vue';
import modal from '../../vue_shared/components/modal.vue';
import commitFilesList from './commit_sidebar/list.vue';
import Actions from './commit_sidebar/actions.vue';
import LoadingButton from '../../vue_shared/components/loading_button.vue';
 
export default {
components: {
modal,
icon,
commitFilesList,
Actions,
LoadingButton,
},
directives: {
tooltip,
Loading
Loading
@@ -27,9 +31,6 @@ export default {
data() {
return {
showNewBranchModal: false,
submitCommitsLoading: false,
startNewMR: false,
commitMessage: '',
};
},
computed: {
Loading
Loading
@@ -40,12 +41,15 @@ export default {
'lastCommitMsg',
'changedFiles',
]),
commitButtonDisabled() {
return this.commitMessage === '' || this.submitCommitsLoading || !this.changedFiles.length;
},
commitMessageCount() {
return this.commitMessage.length;
},
...mapState('commit', [
'commitMessage',
'submitCommitLoading',
]),
...mapGetters('commit', [
'commitButtonDisabled',
'discardDraftButtonDisabled',
'branchName',
]),
statusSvg() {
return this.lastCommitMsg ? this.committedStateSvgPath : this.noChangesStateSvgPath;
},
Loading
Loading
@@ -53,42 +57,19 @@ export default {
methods: {
...mapActions([
'checkCommitStatus',
'commitChanges',
'getTreeData',
'setPanelCollapsedStatus',
]),
makeCommit(newBranch = false) {
const createNewBranch = newBranch || this.startNewMR;
const payload = {
branch: createNewBranch ?
`${this.currentBranchId}-${new Date().getTime().toString()}` :
this.currentBranchId,
commit_message: this.commitMessage,
actions: this.changedFiles.map(f => ({
action: f.tempFile ? 'create' : 'update',
file_path: f.path,
content: f.content,
encoding: f.base64 ? 'base64' : 'text',
})),
start_branch: createNewBranch ? this.currentBranchId : undefined,
};
this.showNewBranchModal = false;
this.submitCommitsLoading = true;
this.commitChanges({ payload, newMr: this.startNewMR })
.then(() => {
this.submitCommitsLoading = false;
this.commitMessage = '';
this.startNewMR = false;
})
.catch(() => {
this.submitCommitsLoading = false;
});
...mapActions('commit', [
'updateCommitMessage',
'discardDraft',
'commitChanges',
]),
makeCommit() {
this.commitChanges();
},
tryCommit() {
this.submitCommitsLoading = true;
this.submitCommitLoading = true;
 
this.checkCommitStatus()
.then((branchChanged) => {
Loading
Loading
@@ -99,7 +80,7 @@ export default {
}
})
.catch(() => {
this.submitCommitsLoading = false;
this.submitCommitLoading = false;
});
},
toggleCollapsed() {
Loading
Loading
@@ -140,51 +121,36 @@ you started editing. Would you like to create a new branch?`)"
>
<form
class="form-horizontal multi-file-commit-form"
@submit.prevent="tryCommit"
@submit.prevent.stop="makeCommit"
v-if="!rightPanelCollapsed"
>
<div class="multi-file-commit-fieldset">
<textarea
class="form-control multi-file-commit-message ref-name"
class="form-control multi-file-commit-message"
name="commit-message"
v-model="commitMessage"
placeholder="Commit message"
:value="commitMessage"
placeholder="Write a commit message..."
@input="updateCommitMessage($event.target.value)"
>
</textarea>
</div>
<div class="multi-file-commit-fieldset">
<label
v-tooltip
title="Create a new merge request with these changes"
data-container="body"
data-placement="top"
>
<input
type="checkbox"
v-model="startNewMR"
/>
{{ __('Merge Request') }}
</label>
<button
type="submit"
<div class="clearfix prepend-top-15">
<actions />
<loading-button
:loading="submitCommitLoading"
:disabled="commitButtonDisabled"
class="btn btn-default btn-sm append-right-10 prepend-left-10"
:class="{ disabled: submitCommitsLoading }"
container-class="btn btn-success btn-sm pull-left"
:label="__('Commit')"
@click="makeCommit"
/>
<button
type="button"
class="btn btn-default btn-sm pull-right"
:disabled="discardDraftButtonDisabled"
@click="discardDraft"
>
<i
v-if="submitCommitsLoading"
class="js-commit-loading-icon fa fa-spinner fa-spin"
aria-hidden="true"
aria-label="loading"
>
</i>
{{ __('Commit') }}
Discard draft
</button>
<div
class="multi-file-commit-message-count"
>
{{ commitMessageCount }}
</div>
</div>
</form>
</template>
Loading
Loading
Loading
Loading
@@ -3,7 +3,6 @@ import { visitUrl } from '../../lib/utils/url_utility';
import flash from '../../flash';
import service from '../services';
import * as types from './mutation_types';
import { stripHtml } from '../../lib/utils/text_utility';
 
export const redirectToUrl = (_, url) => visitUrl(url);
 
Loading
Loading
@@ -67,68 +66,6 @@ export const checkCommitStatus = ({ state }) =>
})
.catch(() => flash('Error checking branch data. Please try again.', 'alert', document, null, false, true));
 
export const commitChanges = (
{ commit, state, dispatch },
{ payload, newMr },
) =>
service
.commit(state.currentProjectId, payload)
.then(({ data }) => {
const { branch } = payload;
if (!data.short_id) {
flash(data.message, 'alert', document, null, false, true);
return;
}
const selectedProject = state.projects[state.currentProjectId];
const lastCommit = {
commit_path: `${selectedProject.web_url}/commit/${data.id}`,
commit: {
message: data.message,
authored_date: data.committed_date,
},
};
let commitMsg = `Your changes have been committed. Commit ${data.short_id}`;
if (data.stats) {
commitMsg += ` with ${data.stats.additions} additions, ${data.stats.deletions} deletions.`;
}
commit(types.SET_LAST_COMMIT_MSG, commitMsg);
if (newMr) {
dispatch('discardAllChanges');
dispatch(
'redirectToUrl',
`${selectedProject.web_url}/merge_requests/new?merge_request%5Bsource_branch%5D=${branch}`,
);
} else {
commit(types.SET_BRANCH_WORKING_REFERENCE, {
projectId: state.currentProjectId,
branchId: state.currentBranchId,
reference: data.id,
});
state.changedFiles.forEach((entry) => {
commit(types.SET_LAST_COMMIT_DATA, {
entry,
lastCommit,
});
});
dispatch('discardAllChanges');
window.scrollTo(0, 0);
}
})
.catch((err) => {
let errMsg = 'Error committing changes. Please try again.';
if (err.response.data && err.response.data.message) {
errMsg += ` (${stripHtml(err.response.data.message)})`;
}
flash(errMsg, 'alert', document, null, false, true);
window.dispatchEvent(new Event('resize'));
});
export const createTempEntry = (
{ state, dispatch },
{ projectId, branchId, parent, name, type, content = '', base64 = false },
Loading
Loading
Loading
Loading
@@ -4,6 +4,7 @@ import state from './state';
import * as actions from './actions';
import * as getters from './getters';
import mutations from './mutations';
import commitModule from './modules/commit';
 
Vue.use(Vuex);
 
Loading
Loading
@@ -12,4 +13,7 @@ export default new Vuex.Store({
actions,
mutations,
getters,
modules: {
commit: commitModule,
},
});
import * as types from './mutation_types';
import * as rootTypes from '../../mutation_types';
import service from '../../../services';
import flash from '../../../../flash';
import { stripHtml } from '../../../../lib/utils/text_utility';
export const updateCommitMessage = ({ commit }, message) => {
commit(types.UPDATE_COMMIT_MESSAGE, message);
};
export const discardDraft = ({ commit }) => {
commit(types.UPDATE_COMMIT_MESSAGE, '');
};
export const updateCommitAction = ({ commit }, commitAction) => {
commit(types.UPDATE_COMMIT_ACTION, commitAction);
};
export const updateBranchName = ({ commit }, branchName) => {
commit(types.UPDATE_NEW_BRANCH_NAME, branchName);
};
export const commitChanges = ({ commit, state, getters, dispatch, rootState }) => {
const payload = {
branch: getters.branchName,
commit_message: state.commitMessage,
actions: rootState.changedFiles.map(f => ({
action: f.tempFile ? 'create' : 'update',
file_path: f.path,
content: f.content,
encoding: f.base64 ? 'base64' : 'text',
})),
start_branch: undefined,
};
commit(types.UPDATE_LOADING, true);
console.log(payload);
return;
service
.commit(state.currentProjectId, payload)
.then(({ data }) => {
const { branch } = payload;
if (!data.short_id) {
flash(data.message, 'alert', document, null, false, true);
return;
}
const selectedProject = state.projects[state.currentProjectId];
const lastCommit = {
commit_path: `${selectedProject.web_url}/commit/${data.id}`,
commit: {
message: data.message,
authored_date: data.committed_date,
},
};
let commitMsg = `Your changes have been committed. Commit ${data.short_id}`;
if (data.stats) {
commitMsg += ` with ${data.stats.additions} additions, ${data.stats.deletions} deletions.`;
}
commit(rootTypes.SET_LAST_COMMIT_MSG, commitMsg, { root: true });
if (false) {
dispatch('discardAllChanges', null, { root: true });
dispatch(
'redirectToUrl',
`${selectedProject.web_url}/merge_requests/new?merge_request[source_branch]=${branch}&merge_request[target_branch]=${rottState.currentBranchId}`,
{ root: true },
);
} else {
commit(rootTypes.SET_BRANCH_WORKING_REFERENCE, {
projectId: state.currentProjectId,
branchId: state.currentBranchId,
reference: data.id,
}, { root: true });
state.changedFiles.forEach((entry) => {
commit(rootTypes.SET_LAST_COMMIT_DATA, {
entry,
lastCommit,
}, { root: true });
});
dispatch('discardAllChanges', null, { root: true });
window.scrollTo(0, 0);
}
})
.catch((err) => {
let errMsg = 'Error committing changes. Please try again.';
if (err.response.data && err.response.data.message) {
errMsg += ` (${stripHtml(err.response.data.message)})`;
}
flash(errMsg, 'alert', document, null, false, true);
window.dispatchEvent(new Event('resize'));
});
};
export const COMMIT_TO_CURRENT_BRANCH = '1';
export const COMMIT_TO_NEW_BRANCH = '2';
export const COMMIT_TO_NEW_BRANCH_MR = '3';
import * as consts from './constants';
export const discardDraftButtonDisabled = state => state.commitMessage === '' || state.submitCommitLoading;
export const commitButtonDisabled = (state, getters, rootState) =>
getters.discardDraftButtonDisabled || !rootState.changedFiles.length;
export const newBranchName = (state, getters, rootState) =>
`${gon.current_username}-${rootState.currentBranchId}-patch-${`${new Date().getTime()}`.substr(-5)}`;
export const branchName = (state, getters, rootState) => {
if (
state.commitAction === consts.COMMIT_TO_NEW_BRANCH ||
state.commitAction === consts.COMMIT_TO_NEW_BRANCH_MR
) {
if (state.newBranchName === '') {
return getters.newBranchName;
}
return state.newBranchName;
}
return rootState.currentBranchId;
};
import state from './state';
import mutations from './mutations';
import * as actions from './actions';
import * as getters from './getters';
export default {
namespaced: true,
state: state(),
mutations,
actions,
getters,
};
export const UPDATE_COMMIT_MESSAGE = 'UPDATE_COMMIT_MESSAGE';
export const UPDATE_COMMIT_ACTION = 'UPDATE_COMMIT_ACTION';
export const UPDATE_NEW_BRANCH_NAME = 'UPDATE_NEW_BRANCH_NAME';
export const UPDATE_LOADING = 'UPDATE_LOADING';
import * as types from './mutation_types';
export default {
[types.UPDATE_COMMIT_MESSAGE](state, commitMessage) {
Object.assign(state, {
commitMessage,
});
},
[types.UPDATE_COMMIT_ACTION](state, commitAction) {
Object.assign(state, {
commitAction,
});
},
[types.UPDATE_NEW_BRANCH_NAME](state, newBranchName) {
Object.assign(state, {
newBranchName,
});
},
[types.UPDATE_LOADING](state, submitCommitLoading) {
Object.assign(state, {
submitCommitLoading,
});
},
};
export default () => ({
commitMessage: '',
commitAction: '1',
newBranchName: '',
submitCommitLoading: false,
});
Loading
Loading
@@ -19,6 +19,7 @@
.ide-view {
display: flex;
height: calc(100vh - #{$header-height});
margin-top: 40px;
color: $almost-black;
border-top: 1px solid $white-dark;
border-bottom: 1px solid $white-dark;
Loading
Loading
@@ -467,16 +468,6 @@ table.table tr td.multi-file-table-name {
border-top: 1px solid $white-dark;
}
 
.multi-file-commit-fieldset {
display: flex;
align-items: center;
padding-bottom: 12px;
.btn {
flex: 1;
}
}
.multi-file-commit-message.form-control {
height: 80px;
resize: none;
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment