summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/ide/components/commit_sidebar/empty_state.vue22
-rw-r--r--app/assets/javascripts/ide/components/commit_sidebar/success_message.vue39
-rw-r--r--app/assets/javascripts/ide/components/repo_commit_section.vue33
-rw-r--r--app/assets/javascripts/ide/stores/actions.js6
-rw-r--r--app/assets/javascripts/ide/stores/actions/file.js4
-rw-r--r--app/assets/javascripts/ide/stores/modules/commit/actions.js4
-rw-r--r--app/assets/javascripts/ide/stores/mutation_types.js1
-rw-r--r--app/assets/javascripts/ide/stores/mutations.js5
-rw-r--r--app/assets/javascripts/ide/stores/state.js1
-rw-r--r--app/assets/stylesheets/pages/repo.scss19
-rw-r--r--changelogs/unreleased/ide-improve-commit-panel.yml5
-rw-r--r--spec/javascripts/ide/components/commit_sidebar/empty_state_spec.js32
-rw-r--r--spec/javascripts/ide/components/commit_sidebar/success_message_spec.js35
-rw-r--r--spec/javascripts/ide/stores/actions/file_spec.js14
-rw-r--r--spec/javascripts/ide/stores/mutations_spec.js10
15 files changed, 169 insertions, 61 deletions
diff --git a/app/assets/javascripts/ide/components/commit_sidebar/empty_state.vue b/app/assets/javascripts/ide/components/commit_sidebar/empty_state.vue
index 6424b93ce54..1f6bbca13b5 100644
--- a/app/assets/javascripts/ide/components/commit_sidebar/empty_state.vue
+++ b/app/assets/javascripts/ide/components/commit_sidebar/empty_state.vue
@@ -15,17 +15,10 @@ export default {
type: String,
required: true,
},
- committedStateSvgPath: {
- type: String,
- required: true,
- },
},
computed: {
- ...mapState(['lastCommitMsg', 'rightPanelCollapsed']),
+ ...mapState(['lastCommitMsg', 'rightPanelCollapsed', 'changedFiles', 'stagedFiles']),
...mapGetters(['collapseButtonIcon', 'collapseButtonTooltip']),
- statusSvg() {
- return this.lastCommitMsg ? this.committedStateSvgPath : this.noChangesStateSvgPath;
- },
},
methods: {
...mapActions(['toggleRightPanelCollapsed']),
@@ -35,6 +28,7 @@ export default {
<template>
<div
+ v-if="!lastCommitMsg"
class="multi-file-commit-panel-section ide-commit-empty-state js-empty-state"
>
<header
@@ -64,12 +58,11 @@ export default {
v-if="!rightPanelCollapsed"
>
<div class="svg-content svg-80">
- <img :src="statusSvg" />
+ <img :src="noChangesStateSvgPath" />
</div>
<div class="append-right-default prepend-left-default">
<div
class="text-content text-center"
- v-if="!lastCommitMsg"
>
<h4>
{{ __('No changes') }}
@@ -78,15 +71,6 @@ export default {
{{ __('Edit files in the editor and commit changes here') }}
</p>
</div>
- <div
- class="text-content text-center"
- v-else
- >
- <h4>
- {{ __('All changes are committed') }}
- </h4>
- <p v-html="lastCommitMsg"></p>
- </div>
</div>
</div>
</div>
diff --git a/app/assets/javascripts/ide/components/commit_sidebar/success_message.vue b/app/assets/javascripts/ide/components/commit_sidebar/success_message.vue
new file mode 100644
index 00000000000..628a17eddca
--- /dev/null
+++ b/app/assets/javascripts/ide/components/commit_sidebar/success_message.vue
@@ -0,0 +1,39 @@
+<script>
+import { mapState } from 'vuex';
+
+export default {
+ props: {
+ committedStateSvgPath: {
+ type: String,
+ required: true,
+ },
+ },
+ computed: {
+ ...mapState(['lastCommitMsg']),
+ },
+};
+</script>
+
+<template>
+ <div
+ class="multi-file-commit-panel-success-message"
+ aria-live="assertive"
+ >
+ <div class="svg-content svg-80">
+ <img
+ :src="committedStateSvgPath"
+ alt=""
+ />
+ </div>
+ <div class="append-right-default prepend-left-default">
+ <div
+ class="text-content text-center"
+ >
+ <h4>
+ {{ __('All changes are committed') }}
+ </h4>
+ <p v-html="lastCommitMsg"></p>
+ </div>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/ide/components/repo_commit_section.vue b/app/assets/javascripts/ide/components/repo_commit_section.vue
index 877d1b5e026..fa929381744 100644
--- a/app/assets/javascripts/ide/components/repo_commit_section.vue
+++ b/app/assets/javascripts/ide/components/repo_commit_section.vue
@@ -7,6 +7,7 @@ import LoadingButton from '~/vue_shared/components/loading_button.vue';
import CommitFilesList from './commit_sidebar/list.vue';
import EmptyState from './commit_sidebar/empty_state.vue';
import CommitMessageField from './commit_sidebar/message_field.vue';
+import SuccessMessage from './commit_sidebar/success_message.vue';
import * as consts from '../stores/modules/commit/constants';
import Actions from './commit_sidebar/actions.vue';
@@ -16,6 +17,7 @@ export default {
Icon,
CommitFilesList,
EmptyState,
+ SuccessMessage,
Actions,
LoadingButton,
CommitMessageField,
@@ -34,9 +36,15 @@ export default {
},
},
computed: {
- ...mapState(['changedFiles', 'stagedFiles', 'rightPanelCollapsed']),
+ showStageUnstageArea() {
+ return !!(this.someUncommitedChanges || this.lastCommitMsg || !this.unusedSeal);
+ },
+ someUncommitedChanges() {
+ return !!(this.changedFiles.length || this.stagedFiles.length);
+ },
+ ...mapState(['changedFiles', 'stagedFiles', 'rightPanelCollapsed', 'lastCommitMsg', 'unusedSeal']),
...mapState('commit', ['commitMessage', 'submitCommitLoading']),
- ...mapGetters('commit', ['commitButtonDisabled', 'discardDraftButtonDisabled', 'branchName']),
+ ...mapGetters('commit', ['commitButtonDisabled', 'discardDraftButtonDisabled']),
},
methods: {
...mapActions('commit', [
@@ -69,7 +77,7 @@ export default {
</template>
</deprecated-modal>
<template
- v-if="changedFiles.length || stagedFiles.length"
+ v-if="showStageUnstageArea"
>
<commit-files-list
icon-name="unstaged"
@@ -89,11 +97,23 @@ export default {
:show-toggle="false"
:staged-list="true"
/>
+ </template>
+ <empty-state
+ v-if="unusedSeal"
+ :no-changes-state-svg-path="noChangesStateSvgPath"
+ />
+ <div
+ class="multi-file-commit-panel-bottom"
+ >
<form
class="form-horizontal multi-file-commit-form"
@submit.prevent.stop="commitChanges"
v-if="!rightPanelCollapsed"
>
+ <success-message
+ v-if="lastCommitMsg && !someUncommitedChanges"
+ :committed-state-svg-path="committedStateSvgPath"
+ />
<commit-message-field
:text="commitMessage"
@input="updateCommitMessage"
@@ -117,11 +137,6 @@ export default {
</button>
</div>
</form>
- </template>
- <empty-state
- v-else
- :no-changes-state-svg-path="noChangesStateSvgPath"
- :committed-state-svg-path="committedStateSvgPath"
- />
+ </div>
</div>
</template>
diff --git a/app/assets/javascripts/ide/stores/actions.js b/app/assets/javascripts/ide/stores/actions.js
index 4c8c997e376..7358dd9ef92 100644
--- a/app/assets/javascripts/ide/stores/actions.js
+++ b/app/assets/javascripts/ide/stores/actions.js
@@ -149,6 +149,12 @@ export const updateTempFlagForEntry = ({ commit, dispatch, state }, { file, temp
export const toggleFileFinder = ({ commit }, fileFindVisible) =>
commit(types.TOGGLE_FILE_FINDER, fileFindVisible);
+export const burstUnusedSeal = ({ state, commit }) => {
+ if (state.unusedSeal) {
+ commit(types.BURST_UNUSED_SEAL);
+ }
+};
+
export * from './actions/tree';
export * from './actions/file';
export * from './actions/project';
diff --git a/app/assets/javascripts/ide/stores/actions/file.js b/app/assets/javascripts/ide/stores/actions/file.js
index fcdb3b753b2..861830badee 100644
--- a/app/assets/javascripts/ide/stores/actions/file.js
+++ b/app/assets/javascripts/ide/stores/actions/file.js
@@ -117,7 +117,7 @@ export const getRawFileData = ({ state, commit, dispatch }, { path, baseSha }) =
});
};
-export const changeFileContent = ({ state, commit }, { path, content }) => {
+export const changeFileContent = ({ commit, dispatch, state }, { path, content }) => {
const file = state.entries[path];
commit(types.UPDATE_FILE_CONTENT, { path, content });
@@ -128,6 +128,8 @@ export const changeFileContent = ({ state, commit }, { path, content }) => {
} else if (!file.changed && indexOfChangedFile !== -1) {
commit(types.REMOVE_FILE_FROM_CHANGED, path);
}
+
+ dispatch('burstUnusedSeal', {}, { root: true });
};
export const setFileLanguage = ({ getters, commit }, { fileLanguage }) => {
diff --git a/app/assets/javascripts/ide/stores/modules/commit/actions.js b/app/assets/javascripts/ide/stores/modules/commit/actions.js
index 349ff68f1e3..4fbc97d053e 100644
--- a/app/assets/javascripts/ide/stores/modules/commit/actions.js
+++ b/app/assets/javascripts/ide/stores/modules/commit/actions.js
@@ -182,6 +182,10 @@ export const commitChanges = ({ commit, state, getters, dispatch, rootState }) =
}
commit(rootTypes.CLEAR_STAGED_CHANGES, null, { root: true });
+
+ setTimeout(() => {
+ commit(rootTypes.SET_LAST_COMMIT_MSG, '', { root: true });
+ }, 5000);
})
.then(() => dispatch('updateCommitAction', consts.COMMIT_TO_CURRENT_BRANCH));
})
diff --git a/app/assets/javascripts/ide/stores/mutation_types.js b/app/assets/javascripts/ide/stores/mutation_types.js
index f5c12db6db0..87b39379338 100644
--- a/app/assets/javascripts/ide/stores/mutation_types.js
+++ b/app/assets/javascripts/ide/stores/mutation_types.js
@@ -61,3 +61,4 @@ export const REMOVE_PENDING_TAB = 'REMOVE_PENDING_TAB';
export const UPDATE_TEMP_FLAG = 'UPDATE_TEMP_FLAG';
export const TOGGLE_FILE_FINDER = 'TOGGLE_FILE_FINDER';
+export const BURST_UNUSED_SEAL = 'BURST_UNUSED_SEAL';
diff --git a/app/assets/javascripts/ide/stores/mutations.js b/app/assets/javascripts/ide/stores/mutations.js
index 0c1d720df09..539a07116b3 100644
--- a/app/assets/javascripts/ide/stores/mutations.js
+++ b/app/assets/javascripts/ide/stores/mutations.js
@@ -128,6 +128,11 @@ export default {
}),
});
},
+ [types.BURST_UNUSED_SEAL](state) {
+ Object.assign(state, {
+ unusedSeal: false,
+ });
+ },
...projectMutations,
...mergeRequestMutation,
...fileMutations,
diff --git a/app/assets/javascripts/ide/stores/state.js b/app/assets/javascripts/ide/stores/state.js
index 3470bb9aec0..0976d278559 100644
--- a/app/assets/javascripts/ide/stores/state.js
+++ b/app/assets/javascripts/ide/stores/state.js
@@ -18,5 +18,6 @@ export default () => ({
entries: {},
viewer: 'editor',
delayViewerUpdated: false,
+ unusedSeal: true,
fileFindVisible: false,
});
diff --git a/app/assets/stylesheets/pages/repo.scss b/app/assets/stylesheets/pages/repo.scss
index 6342042374f..2c0b20809ba 100644
--- a/app/assets/stylesheets/pages/repo.scss
+++ b/app/assets/stylesheets/pages/repo.scss
@@ -549,6 +549,7 @@
margin-bottom: 0;
border-bottom: 1px solid $white-dark;
padding: $gl-btn-padding 0;
+ min-height: 56px;
}
.multi-file-commit-panel-header-title {
@@ -673,6 +674,24 @@
}
}
+.multi-file-commit-panel-bottom {
+ position: relative;
+
+ .multi-file-commit-panel-success-message {
+ position: absolute;
+ top: 1px;
+ left: 3px;
+ bottom: 0;
+ right: 0;
+ z-index: 10;
+ background: $gray-light;
+ overflow: auto;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ }
+}
+
.dirty-diff {
// !important need to override monaco inline style
width: 4px !important;
diff --git a/changelogs/unreleased/ide-improve-commit-panel.yml b/changelogs/unreleased/ide-improve-commit-panel.yml
new file mode 100644
index 00000000000..f6237db3039
--- /dev/null
+++ b/changelogs/unreleased/ide-improve-commit-panel.yml
@@ -0,0 +1,5 @@
+---
+title: Improve interaction on WebIDE commit panel
+merge_request:
+author:
+type: changed
diff --git a/spec/javascripts/ide/components/commit_sidebar/empty_state_spec.js b/spec/javascripts/ide/components/commit_sidebar/empty_state_spec.js
index b80d08de7b1..53275b78da5 100644
--- a/spec/javascripts/ide/components/commit_sidebar/empty_state_spec.js
+++ b/spec/javascripts/ide/components/commit_sidebar/empty_state_spec.js
@@ -24,42 +24,10 @@ describe('IDE commit panel empty state', () => {
resetStore(vm.$store);
});
- describe('statusSvg', () => {
- it('uses noChangesStateSvgPath when commit message is empty', () => {
- expect(vm.statusSvg).toBe('no-changes');
- expect(vm.$el.querySelector('img').getAttribute('src')).toBe(
- 'no-changes',
- );
- });
-
- it('uses committedStateSvgPath when commit message exists', done => {
- vm.$store.state.lastCommitMsg = 'testing';
-
- Vue.nextTick(() => {
- expect(vm.statusSvg).toBe('committed-state');
- expect(vm.$el.querySelector('img').getAttribute('src')).toBe(
- 'committed-state',
- );
-
- done();
- });
- });
- });
-
it('renders no changes text when last commit message is empty', () => {
expect(vm.$el.textContent).toContain('No changes');
});
- it('renders last commit message when it exists', done => {
- vm.$store.state.lastCommitMsg = 'testing commit message';
-
- Vue.nextTick(() => {
- expect(vm.$el.textContent).toContain('testing commit message');
-
- done();
- });
- });
-
describe('toggle button', () => {
it('calls store action', () => {
spyOn(vm, 'toggleRightPanelCollapsed');
diff --git a/spec/javascripts/ide/components/commit_sidebar/success_message_spec.js b/spec/javascripts/ide/components/commit_sidebar/success_message_spec.js
new file mode 100644
index 00000000000..e1a432b81be
--- /dev/null
+++ b/spec/javascripts/ide/components/commit_sidebar/success_message_spec.js
@@ -0,0 +1,35 @@
+import Vue from 'vue';
+import store from '~/ide/stores';
+import successMessage from '~/ide/components/commit_sidebar/success_message.vue';
+import { createComponentWithStore } from '../../../helpers/vue_mount_component_helper';
+import { resetStore } from '../../helpers';
+
+describe('IDE commit panel successful commit state', () => {
+ let vm;
+
+ beforeEach(() => {
+ const Component = Vue.extend(successMessage);
+
+ vm = createComponentWithStore(Component, store, {
+ committedStateSvgPath: 'committed-state',
+ });
+
+ vm.$mount();
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+
+ resetStore(vm.$store);
+ });
+
+ it('renders last commit message when it exists', done => {
+ vm.$store.state.lastCommitMsg = 'testing commit message';
+
+ Vue.nextTick(() => {
+ expect(vm.$el.textContent).toContain('testing commit message');
+
+ done();
+ });
+ });
+});
diff --git a/spec/javascripts/ide/stores/actions/file_spec.js b/spec/javascripts/ide/stores/actions/file_spec.js
index ce5c525bed7..3ee11bd2f03 100644
--- a/spec/javascripts/ide/stores/actions/file_spec.js
+++ b/spec/javascripts/ide/stores/actions/file_spec.js
@@ -398,6 +398,20 @@ describe('IDE store file actions', () => {
})
.catch(done.fail);
});
+
+ it('bursts unused seal', done => {
+ store
+ .dispatch('changeFileContent', {
+ path: tmpFile.path,
+ content: 'content',
+ })
+ .then(() => {
+ expect(store.state.unusedSeal).toBe(false);
+
+ done();
+ })
+ .catch(done.fail);
+ });
});
describe('discardFileChanges', () => {
diff --git a/spec/javascripts/ide/stores/mutations_spec.js b/spec/javascripts/ide/stores/mutations_spec.js
index 997711d1e19..61efb6372c9 100644
--- a/spec/javascripts/ide/stores/mutations_spec.js
+++ b/spec/javascripts/ide/stores/mutations_spec.js
@@ -116,4 +116,14 @@ describe('Multi-file store mutations', () => {
expect(localState.fileFindVisible).toBe(true);
});
});
+
+ describe('BURST_UNUSED_SEAL', () => {
+ it('updates unusedSeal', () => {
+ expect(localState.unusedSeal).toBe(true);
+
+ mutations.BURST_UNUSED_SEAL(localState);
+
+ expect(localState.unusedSeal).toBe(false);
+ });
+ });
});