From 2aa47e10d4efd1c2e70cbdd1ebc6ef3b0dbc1fbd Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Mon, 3 Sep 2018 11:57:41 +0100 Subject: Improved IDE commit flow Closes #48182 --- .../components/commit_sidebar/editor_header.vue | 78 ++++++++++++++++++++++ .../ide/components/commit_sidebar/list.vue | 34 +++++----- .../ide/components/commit_sidebar/stage_button.vue | 53 +++++++++------ .../components/commit_sidebar/unstage_button.vue | 4 +- app/assets/javascripts/ide/components/ide.vue | 9 ++- .../ide/components/repo_commit_section.vue | 2 + app/assets/stylesheets/framework/buttons.scss | 4 ++ app/assets/stylesheets/page_bundles/ide.scss | 12 ++-- locale/gitlab.pot | 18 ++++- 9 files changed, 165 insertions(+), 49 deletions(-) create mode 100644 app/assets/javascripts/ide/components/commit_sidebar/editor_header.vue diff --git a/app/assets/javascripts/ide/components/commit_sidebar/editor_header.vue b/app/assets/javascripts/ide/components/commit_sidebar/editor_header.vue new file mode 100644 index 00000000000..c3ca147e850 --- /dev/null +++ b/app/assets/javascripts/ide/components/commit_sidebar/editor_header.vue @@ -0,0 +1,78 @@ + + + diff --git a/app/assets/javascripts/ide/components/commit_sidebar/list.vue b/app/assets/javascripts/ide/components/commit_sidebar/list.vue index d0fb0e3d99e..9b4cea35538 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/list.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/list.vue @@ -56,6 +56,11 @@ export default { type: String, required: true, }, + emptyStateText: { + type: String, + required: false, + default: __('No changes'), + }, }, computed: { titleText() { @@ -91,17 +96,20 @@ export default { :name="iconName" :size="18" /> - {{ titleText }} + + {{ titleText }} +
- - {{ filesLength }} -
@@ -143,9 +143,9 @@ export default {

- {{ __('No changes') }} + {{ emptyStateText }}

diff --git a/app/assets/javascripts/ide/components/commit_sidebar/stage_button.vue b/app/assets/javascripts/ide/components/commit_sidebar/stage_button.vue index e6044401c9f..13e66e4bcf5 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/stage_button.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/stage_button.vue @@ -1,11 +1,14 @@ @@ -25,51 +39,48 @@ export default { diff --git a/app/assets/javascripts/ide/components/commit_sidebar/unstage_button.vue b/app/assets/javascripts/ide/components/commit_sidebar/unstage_button.vue index 9cec73ec00e..4a24cf65e5a 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/unstage_button.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/unstage_button.vue @@ -39,8 +39,8 @@ export default { @click="unstageChange(path)" > diff --git a/app/assets/javascripts/ide/components/ide.vue b/app/assets/javascripts/ide/components/ide.vue index 6a5ab35a16a..a3add3b778f 100644 --- a/app/assets/javascripts/ide/components/ide.vue +++ b/app/assets/javascripts/ide/components/ide.vue @@ -10,6 +10,7 @@ import RepoEditor from './repo_editor.vue'; import FindFile from './file_finder/index.vue'; import RightPane from './panes/right.vue'; import ErrorMessage from './error_message.vue'; +import CommitEditorHeader from './commit_sidebar/editor_header.vue'; const originalStopCallback = Mousetrap.stopCallback; @@ -23,6 +24,7 @@ export default { FindFile, RightPane, ErrorMessage, + CommitEditorHeader, }, computed: { ...mapState([ @@ -34,7 +36,7 @@ export default { 'currentProjectId', 'errorMessage', ]), - ...mapGetters(['activeFile', 'hasChanges', 'someUncommitedChanges']), + ...mapGetters(['activeFile', 'hasChanges', 'someUncommitedChanges', 'isCommitModeActive']), }, mounted() { window.onbeforeunload = e => this.onBeforeUnload(e); @@ -96,7 +98,12 @@ export default { diff --git a/app/assets/javascripts/ide/components/repo_commit_section.vue b/app/assets/javascripts/ide/components/repo_commit_section.vue index e24469f17ed..d3b24c5b793 100644 --- a/app/assets/javascripts/ide/components/repo_commit_section.vue +++ b/app/assets/javascripts/ide/components/repo_commit_section.vue @@ -97,7 +97,7 @@ export default { :active-file-key="activeFileKey" :empty-state-text="__('There are no unstaged changes')" action="stageAllChanges" - action-btn-icon="mobile-issue-close" + action-btn-icon="stage-all" item-action-component="stage-button" class="is-first" icon-name="unstaged" @@ -111,7 +111,7 @@ export default { :active-file-key="activeFileKey" :empty-state-text="__('There are no staged changes')" action="unstageAllChanges" - action-btn-icon="history" + action-btn-icon="unstage-all" item-action-component="unstage-button" icon-name="staged" /> diff --git a/app/assets/javascripts/ide/stores/actions/file.js b/app/assets/javascripts/ide/stores/actions/file.js index 28b9d0df201..30dcf7ef4df 100644 --- a/app/assets/javascripts/ide/stores/actions/file.js +++ b/app/assets/javascripts/ide/stores/actions/file.js @@ -5,7 +5,7 @@ import service from '../../services'; import * as types from '../mutation_types'; import router from '../../ide_router'; import { setPageTitle } from '../utils'; -import { viewerTypes } from '../../constants'; +import { viewerTypes, stageKeys } from '../../constants'; export const closeFile = ({ commit, state, dispatch }, file) => { const { path } = file; @@ -208,8 +208,9 @@ export const discardFileChanges = ({ dispatch, state, commit, getters }, path) = eventHub.$emit(`editor.update.model.dispose.unstaged-${file.key}`, file.content); }; -export const stageChange = ({ commit, state }, path) => { +export const stageChange = ({ commit, state, dispatch }, path) => { const stagedFile = state.stagedFiles.find(f => f.path === path); + const openFile = state.openFiles.find(f => f.path === path); commit(types.STAGE_CHANGE, path); commit(types.SET_LAST_COMMIT_MSG, ''); @@ -217,21 +218,39 @@ export const stageChange = ({ commit, state }, path) => { if (stagedFile) { eventHub.$emit(`editor.update.model.new.content.staged-${stagedFile.key}`, stagedFile.content); } + + if (openFile && openFile.active) { + const file = state.stagedFiles.find(f => f.path === path); + + dispatch('openPendingTab', { + file, + keyPrefix: stageKeys.staged, + }); + } }; -export const unstageChange = ({ commit }, path) => { +export const unstageChange = ({ commit, dispatch, state }, path) => { + const openFile = state.openFiles.find(f => f.path === path); + commit(types.UNSTAGE_CHANGE, path); + + if (openFile && openFile.active) { + const file = state.changedFiles.find(f => f.path === path); + + dispatch('openPendingTab', { + file, + keyPrefix: stageKeys.unstaged, + }); + } }; -export const openPendingTab = ({ commit, getters, dispatch, state }, { file, keyPrefix }) => { +export const openPendingTab = ({ commit, getters, state }, { file, keyPrefix }) => { if (getters.activeFile && getters.activeFile.key === `${keyPrefix}-${file.key}`) return false; state.openFiles.forEach(f => eventHub.$emit(`editor.update.model.dispose.${f.key}`)); commit(types.ADD_PENDING_TAB, { file, keyPrefix }); - dispatch('scrollToTab'); - router.push(`/project/${file.projectId}/tree/${state.currentBranchId}/`); return true; diff --git a/app/assets/stylesheets/page_bundles/ide.scss b/app/assets/stylesheets/page_bundles/ide.scss index 0f0890f9fb6..f4c99016696 100644 --- a/app/assets/stylesheets/page_bundles/ide.scss +++ b/app/assets/stylesheets/page_bundles/ide.scss @@ -574,17 +574,6 @@ $ide-tree-text-start: $ide-activity-bar-width + $ide-tree-padding; padding: 12px 0; } -.multi-file-commit-panel-header-title { - display: flex; - flex: 1; - align-items: center; - - svg { - margin-right: $gl-btn-padding; - color: $theme-gray-700; - } -} - .multi-file-commit-panel-collapse-btn { border-left: 1px solid $white-dark; margin-left: auto; diff --git a/package.json b/package.json index 7e6ddf0fca7..d5b747b4131 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "webpack-prod": "NODE_ENV=production webpack --config config/webpack.config.js" }, "dependencies": { - "@gitlab-org/gitlab-svgs": "^1.28.0", + "@gitlab-org/gitlab-svgs": "^1.29.0", "@gitlab-org/gitlab-ui": "1.0.5", "autosize": "^4.0.0", "axios": "^0.17.1", diff --git a/spec/javascripts/ide/components/commit_sidebar/stage_button_spec.js b/spec/javascripts/ide/components/commit_sidebar/stage_button_spec.js index a5b906da8a1..e09ccbe2a63 100644 --- a/spec/javascripts/ide/components/commit_sidebar/stage_button_spec.js +++ b/spec/javascripts/ide/components/commit_sidebar/stage_button_spec.js @@ -29,7 +29,7 @@ describe('IDE stage file button', () => { }); it('renders button to discard & stage', () => { - expect(vm.$el.querySelectorAll('.btn').length).toBe(2); + expect(vm.$el.querySelectorAll('.btn-blank').length).toBe(2); }); it('calls store with stage button', () => { @@ -39,7 +39,7 @@ describe('IDE stage file button', () => { }); it('calls store with discard button', () => { - vm.$el.querySelector('.dropdown-menu button').click(); + vm.$el.querySelector('.btn-danger').click(); expect(vm.discardFileChanges).toHaveBeenCalledWith(f.path); }); diff --git a/spec/javascripts/ide/components/repo_commit_section_spec.js b/spec/javascripts/ide/components/repo_commit_section_spec.js index 30cd92b2ca4..d09ccd7ac34 100644 --- a/spec/javascripts/ide/components/repo_commit_section_spec.js +++ b/spec/javascripts/ide/components/repo_commit_section_spec.js @@ -111,7 +111,7 @@ describe('RepoCommitSection', () => { .then(vm.$nextTick) .then(() => { expect(vm.$el.querySelector('.ide-commit-list-container').textContent).toContain( - 'No changes', + 'There are no unstaged changes', ); }) .then(done) @@ -133,7 +133,7 @@ describe('RepoCommitSection', () => { }); it('discards a single file', done => { - vm.$el.querySelector('.multi-file-discard-btn .dropdown-menu button').click(); + vm.$el.querySelector('.multi-file-commit-list li:first-child .js-modal-primary-action').click(); Vue.nextTick(() => { expect(vm.$el.querySelector('.ide-commit-list-container').textContent).not.toContain('file1'); diff --git a/yarn.lock b/yarn.lock index 6f96e5ff228..aa3ed1aa7eb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -82,9 +82,9 @@ version "1.27.0" resolved "https://registry.yarnpkg.com/@gitlab-org/gitlab-svgs/-/gitlab-svgs-1.27.0.tgz#638e70399ebd59e503732177316bb9a18bf7a13f" -"@gitlab-org/gitlab-svgs@^1.28.0": - version "1.28.0" - resolved "https://registry.yarnpkg.com/@gitlab-org/gitlab-svgs/-/gitlab-svgs-1.28.0.tgz#f689dfd46504df0a75027d6dd4ea01a71cd46f88" +"@gitlab-org/gitlab-svgs@^1.29.0": + version "1.29.0" + resolved "https://registry.yarnpkg.com/@gitlab-org/gitlab-svgs/-/gitlab-svgs-1.29.0.tgz#03b65b513f9099bbda6ecf94d673a2952f8c6c70" "@gitlab-org/gitlab-ui@1.0.5": version "1.0.5" -- cgit v1.2.1 From ebc15f4318ed23ccdfe7dc543721968ae92daae0 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Tue, 4 Sep 2018 09:00:25 +0100 Subject: design improvements --- .../ide/components/commit_sidebar/list.vue | 8 +++--- .../ide/components/commit_sidebar/list_item.vue | 29 ++++++++++++------- .../ide/components/commit_sidebar/stage_button.vue | 8 ++++-- .../components/commit_sidebar/unstage_button.vue | 3 +- app/assets/stylesheets/page_bundles/ide.scss | 33 ++++++++++++++++------ 5 files changed, 54 insertions(+), 27 deletions(-) diff --git a/app/assets/javascripts/ide/components/commit_sidebar/list.vue b/app/assets/javascripts/ide/components/commit_sidebar/list.vue index 92cd46e9385..a69df0956bc 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/list.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/list.vue @@ -97,7 +97,7 @@ export default { class="ide-commit-list-container" >
diff --git a/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue b/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue index 391004dcd3c..10c78a80302 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue @@ -2,6 +2,7 @@ import { mapActions } from 'vuex'; import tooltip from '~/vue_shared/directives/tooltip'; import Icon from '~/vue_shared/components/icon.vue'; +import FileIcon from '~/vue_shared/components/file_icon.vue'; import StageButton from './stage_button.vue'; import UnstageButton from './unstage_button.vue'; import { viewerTypes } from '../../constants'; @@ -12,6 +13,7 @@ export default { Icon, StageButton, UnstageButton, + FileIcon, }, directives: { tooltip, @@ -48,7 +50,7 @@ export default { return `${getCommitIconMap(this.file).icon}${suffix}`; }, iconClass() { - return `${getCommitIconMap(this.file).class} append-right-8`; + return `${getCommitIconMap(this.file).class} ml-auto mr-auto`; }, fullKey() { return `${this.keyPrefix}-${this.file.key}`; @@ -105,17 +107,24 @@ export default { @click="openFileInEditor" > - {{ file.name }} +
+
+ +
+ +
- diff --git a/app/assets/javascripts/ide/components/commit_sidebar/stage_button.vue b/app/assets/javascripts/ide/components/commit_sidebar/stage_button.vue index 13e66e4bcf5..fb8392d2e1b 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/stage_button.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/stage_button.vue @@ -46,15 +46,16 @@ export default { :aria-label="__('Stage changes')" :title="__('Stage changes')" type="button" - class="btn btn-blank append-right-8 d-flex align-items-center" + class="btn btn-blank d-flex align-items-center" data-container="body" data-boundary="viewport" data-placement="bottom" - @click="stageChange(path)" + @click.stop.prevent="stageChange(path)" > diff --git a/app/assets/stylesheets/page_bundles/ide.scss b/app/assets/stylesheets/page_bundles/ide.scss index f4c99016696..2eadc55bdfd 100644 --- a/app/assets/stylesheets/page_bundles/ide.scss +++ b/app/assets/stylesheets/page_bundles/ide.scss @@ -567,9 +567,7 @@ $ide-tree-text-start: $ide-activity-bar-width + $ide-tree-padding; } .multi-file-commit-panel-header { - display: flex; - align-items: center; - margin-bottom: 0; + height: 48px; border-bottom: 1px solid $white-dark; padding: 12px 0; } @@ -583,8 +581,6 @@ $ide-tree-text-start: $ide-activity-bar-width + $ide-tree-padding; flex: 1; overflow: auto; padding: $grid-size 0; - margin-left: -$grid-size; - margin-right: -$grid-size; min-height: 60px; &.form-text.text-muted { @@ -649,6 +645,8 @@ $ide-tree-text-start: $ide-activity-bar-width + $ide-tree-padding; .multi-file-commit-list-path { cursor: pointer; + height: 32px; + padding-right: 0; &.is-active { background-color: $white-normal; @@ -657,6 +655,10 @@ $ide-tree-text-start: $ide-activity-bar-width + $ide-tree-padding; &:hover, &:focus { outline: 0; + + .multi-file-discard-btn { + display: flex; + } } svg { @@ -676,13 +678,16 @@ $ide-tree-text-start: $ide-activity-bar-width + $ide-tree-padding; } .multi-file-discard-btn { - top: 4px; - right: 8px; - bottom: 4px; + display: none; svg { top: 0; } + + .btn { + width: 32px; + height: 32px; + } } .multi-file-commit-form { @@ -797,6 +802,10 @@ $ide-tree-text-start: $ide-activity-bar-width + $ide-tree-padding; } .ide-staged-action-btn { + width: 32px; + height: 32px; + color: inherit; + > svg { top: 0; } @@ -1443,7 +1452,13 @@ $ide-tree-text-start: $ide-activity-bar-width + $ide-tree-padding; } .ide-commit-editor-header { + height: 65px; padding: 8px 16px; - background-color: $white-normal; + background-color: $theme-gray-50; box-shadow: inset 0 -1px $white-dark; } + +.ide-commit-list-changed-icon { + width: 32px; + height: 32px; +} -- cgit v1.2.1 From 93e84c8f28f9bad8c09a720ce008dba1f50aadcd Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Tue, 4 Sep 2018 09:03:36 +0100 Subject: fixed tests --- locale/gitlab.pot | 6 ++++++ spec/javascripts/ide/stores/actions/file_spec.js | 15 --------------- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/locale/gitlab.pot b/locale/gitlab.pot index a9b0d8a4662..0faad99ff11 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -2304,6 +2304,9 @@ msgstr "" msgid "Discard" msgstr "" +msgid "Discard all changes" +msgstr "" + msgid "Discard changes" msgstr "" @@ -6655,6 +6658,9 @@ msgstr "" msgid "You will loose all changes you've made to this file. This action cannot be undone." msgstr "" +msgid "You will loose all the unstaged changes you've made in this project. This action cannot be undone." +msgstr "" + msgid "You will not get any notifications via email" msgstr "" diff --git a/spec/javascripts/ide/stores/actions/file_spec.js b/spec/javascripts/ide/stores/actions/file_spec.js index bca2033ff97..1ca811e996b 100644 --- a/spec/javascripts/ide/stores/actions/file_spec.js +++ b/spec/javascripts/ide/stores/actions/file_spec.js @@ -692,21 +692,6 @@ describe('IDE store file actions', () => { .then(done) .catch(done.fail); }); - - it('calls scrollToTab', done => { - const scrollToTabSpy = jasmine.createSpy('scrollToTab'); - const oldScrollToTab = store._actions.scrollToTab; // eslint-disable-line - store._actions.scrollToTab = [scrollToTabSpy]; // eslint-disable-line - - store - .dispatch('openPendingTab', { file: f, keyPrefix: 'pending' }) - .then(() => { - expect(scrollToTabSpy).toHaveBeenCalled(); - store._actions.scrollToTab = oldScrollToTab; // eslint-disable-line - }) - .then(done) - .catch(done.fail); - }); }); describe('removePendingTab', () => { -- cgit v1.2.1 From cfb67193bf7cc9377d82cc6fa99d232627a64600 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Tue, 4 Sep 2018 09:30:46 +0100 Subject: fixed discard modal not showing --- .../ide/components/commit_sidebar/stage_button.vue | 4 ++-- .../ide/components/commit_sidebar/unstage_button.vue | 2 +- app/assets/stylesheets/page_bundles/ide.scss | 15 ++++++++------- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/app/assets/javascripts/ide/components/commit_sidebar/stage_button.vue b/app/assets/javascripts/ide/components/commit_sidebar/stage_button.vue index fb8392d2e1b..62469e9f98a 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/stage_button.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/stage_button.vue @@ -46,7 +46,7 @@ export default { :aria-label="__('Stage changes')" :title="__('Stage changes')" type="button" - class="btn btn-blank d-flex align-items-center" + class="btn btn-blank align-items-center" data-container="body" data-boundary="viewport" data-placement="bottom" @@ -63,7 +63,7 @@ export default { :aria-label="__('Discard changes')" :title="__('Discard changes')" type="button" - class="btn btn-blank d-flex align-items-center" + class="btn btn-blank align-items-center" data-container="body" data-boundary="viewport" data-placement="bottom" diff --git a/app/assets/javascripts/ide/components/commit_sidebar/unstage_button.vue b/app/assets/javascripts/ide/components/commit_sidebar/unstage_button.vue index 95c80c31d41..18830ab81ff 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/unstage_button.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/unstage_button.vue @@ -32,7 +32,7 @@ export default { :aria-label="__('Unstage changes')" :title="__('Unstage changes')" type="button" - class="btn btn-blank d-flex align-items-center" + class="btn btn-blank align-items-center" data-container="body" data-boundary="viewport" data-placement="bottom" diff --git a/app/assets/stylesheets/page_bundles/ide.scss b/app/assets/stylesheets/page_bundles/ide.scss index 2eadc55bdfd..35ba1fca2b7 100644 --- a/app/assets/stylesheets/page_bundles/ide.scss +++ b/app/assets/stylesheets/page_bundles/ide.scss @@ -657,7 +657,9 @@ $ide-tree-text-start: $ide-activity-bar-width + $ide-tree-padding; outline: 0; .multi-file-discard-btn { - display: flex; + > .btn { + display: flex; + } } } @@ -678,16 +680,15 @@ $ide-tree-text-start: $ide-activity-bar-width + $ide-tree-padding; } .multi-file-discard-btn { - display: none; + > .btn { + display: none; + width: 32px; + height: 32px; + } svg { top: 0; } - - .btn { - width: 32px; - height: 32px; - } } .multi-file-commit-form { -- cgit v1.2.1 From 04f4b86826b27219b0384605e11d145ff0671682 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Tue, 4 Sep 2018 09:37:38 +0100 Subject: update state when staging/unstaging all --- .../ide/components/commit_sidebar/list.vue | 4 ++-- .../ide/components/commit_sidebar/stage_button.vue | 2 +- .../ide/components/commit_sidebar/unstage_button.vue | 2 +- app/assets/javascripts/ide/stores/actions.js | 19 +++++++++++++++++-- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/app/assets/javascripts/ide/components/commit_sidebar/list.vue b/app/assets/javascripts/ide/components/commit_sidebar/list.vue index a69df0956bc..daae3be7d44 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/list.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/list.vue @@ -137,8 +137,8 @@ export default {