summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilipa Lacerda <filipa@gitlab.com>2018-06-15 16:59:56 +0000
committerFilipa Lacerda <filipa@gitlab.com>2018-06-15 16:59:56 +0000
commit25fd298314bf368ca88276c444e64883d045b899 (patch)
treedb45aac349cc4a30974f80cf93cd00a57d71fe3f
parent6d4a0325f13069fd5c69a3a6520de73f67783200 (diff)
parent7e8e5229cc0ef547a29e74c684dfde5106d57641 (diff)
downloadgitlab-ce-25fd298314bf368ca88276c444e64883d045b899.tar.gz
Merge branch 'ide-commit-actions-update' into 'master'
Improve commit flow in Web IDE Closes #46122 See merge request gitlab-org/gitlab-ce!19735
-rw-r--r--app/assets/javascripts/ide/components/commit_sidebar/list.vue63
-rw-r--r--app/assets/javascripts/ide/components/commit_sidebar/list_item.vue26
-rw-r--r--app/assets/javascripts/ide/components/commit_sidebar/stage_button.vue30
-rw-r--r--app/assets/javascripts/ide/components/commit_sidebar/unstage_button.vue4
-rw-r--r--app/assets/javascripts/ide/components/repo_commit_section.vue12
-rw-r--r--app/assets/stylesheets/pages/repo.scss60
-rw-r--r--changelogs/unreleased/ide-commit-actions-update.yml5
-rw-r--r--spec/javascripts/ide/components/commit_sidebar/list_item_spec.js4
-rw-r--r--spec/javascripts/ide/components/commit_sidebar/list_spec.js3
-rw-r--r--spec/javascripts/ide/components/commit_sidebar/stage_button_spec.js2
-rw-r--r--spec/javascripts/ide/components/repo_commit_section_spec.js20
11 files changed, 133 insertions, 96 deletions
diff --git a/app/assets/javascripts/ide/components/commit_sidebar/list.vue b/app/assets/javascripts/ide/components/commit_sidebar/list.vue
index 3d59410cbc2..d0fb0e3d99e 100644
--- a/app/assets/javascripts/ide/components/commit_sidebar/list.vue
+++ b/app/assets/javascripts/ide/components/commit_sidebar/list.vue
@@ -34,6 +34,10 @@ export default {
type: String,
required: true,
},
+ actionBtnIcon: {
+ type: String,
+ required: true,
+ },
itemActionComponent: {
type: String,
required: true,
@@ -53,26 +57,21 @@ export default {
required: true,
},
},
- data() {
- return {
- showActionButton: false,
- };
- },
computed: {
titleText() {
return sprintf(__('%{title} changes'), {
title: this.title,
});
},
+ filesLength() {
+ return this.fileList.length;
+ },
},
methods: {
...mapActions(['stageAllChanges', 'unstageAllChanges']),
actionBtnClicked() {
this[this.action]();
},
- setShowActionButton(show) {
- this.showActionButton = show;
- },
},
};
</script>
@@ -83,8 +82,6 @@ export default {
>
<header
class="multi-file-commit-panel-header"
- @mouseenter="setShowActionButton(true)"
- @mouseleave="setShowActionButton(false)"
>
<div
class="multi-file-commit-panel-header-title"
@@ -95,24 +92,40 @@ export default {
:size="18"
/>
{{ titleText }}
- <span
- v-show="!showActionButton"
- class="ide-commit-file-count"
- >
- {{ fileList.length }}
- </span>
- <button
- v-show="showActionButton"
- type="button"
- class="btn btn-blank btn-link ide-staged-action-btn"
- @click="actionBtnClicked"
- >
- {{ actionBtnText }}
- </button>
+ <div class="d-flex ml-auto">
+ <button
+ v-tooltip
+ v-show="filesLength"
+ :class="{
+ 'd-flex': filesLength
+ }"
+ :title="actionBtnText"
+ type="button"
+ class="btn btn-default ide-staged-action-btn p-0 order-1 align-items-center"
+ data-placement="bottom"
+ data-container="body"
+ data-boundary="viewport"
+ @click="actionBtnClicked"
+ >
+ <icon
+ :name="actionBtnIcon"
+ :size="12"
+ class="ml-auto mr-auto"
+ />
+ </button>
+ <span
+ :class="{
+ 'rounded-right': !filesLength
+ }"
+ class="ide-commit-file-count order-0 rounded-left text-center"
+ >
+ {{ filesLength }}
+ </span>
+ </div>
</div>
</header>
<ul
- v-if="fileList.length"
+ v-if="filesLength"
class="multi-file-commit-list list-unstyled append-bottom-0"
>
<li
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 2ecf9af4bf0..5cda7967130 100644
--- a/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue
+++ b/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue
@@ -1,5 +1,6 @@
<script>
import { mapActions } from 'vuex';
+import tooltip from '~/vue_shared/directives/tooltip';
import Icon from '~/vue_shared/components/icon.vue';
import StageButton from './stage_button.vue';
import UnstageButton from './unstage_button.vue';
@@ -11,6 +12,9 @@ export default {
StageButton,
UnstageButton,
},
+ directives: {
+ tooltip,
+ },
props: {
file: {
type: Object,
@@ -50,6 +54,9 @@ export default {
isActive() {
return this.activeFileKey === this.fullKey;
},
+ tooltipTitle() {
+ return this.file.path === this.file.name ? '' : this.file.path;
+ },
},
methods: {
...mapActions([
@@ -81,29 +88,30 @@ export default {
</script>
<template>
- <div
- :class="{
- 'is-active': isActive
- }"
- class="multi-file-commit-list-item"
- >
+ <div class="multi-file-commit-list-item position-relative">
<button
+ v-tooltip
+ :title="tooltipTitle"
+ :class="{
+ 'is-active': isActive
+ }"
type="button"
- class="multi-file-commit-list-path"
+ class="multi-file-commit-list-path w-100 border-0 ml-0 mr-0"
@dblclick="fileAction"
@click="openFileInEditor"
>
- <span class="multi-file-commit-list-file-path">
+ <span class="multi-file-commit-list-file-path d-flex align-items-center">
<icon
:name="iconName"
:size="16"
:css-classes="iconClass"
- />{{ file.path }}
+ />{{ file.name }}
</span>
</button>
<component
:is="actionComponent"
:path="file.path"
+ class="d-flex position-absolute"
/>
</div>
</template>
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 a786ec80ac2..7014b9f605e 100644
--- a/app/assets/javascripts/ide/components/commit_sidebar/stage_button.vue
+++ b/app/assets/javascripts/ide/components/commit_sidebar/stage_button.vue
@@ -25,15 +25,17 @@ export default {
<template>
<div
v-once
- class="multi-file-discard-btn"
+ class="multi-file-discard-btn dropdown"
>
<button
v-tooltip
:aria-label="__('Stage changes')"
:title="__('Stage changes')"
type="button"
- class="btn btn-blank append-right-5"
+ class="btn btn-blank append-right-5 d-flex align-items-center"
data-container="body"
+ data-boundary="viewport"
+ data-placement="bottom"
@click.stop="stageChange(path)"
>
<icon
@@ -43,17 +45,31 @@ export default {
</button>
<button
v-tooltip
- :aria-label="__('Discard changes')"
- :title="__('Discard changes')"
+ :title="__('More actions')"
type="button"
- class="btn btn-blank"
+ class="btn btn-blank d-flex align-items-center"
data-container="body"
- @click.stop="discardFileChanges(path)"
+ data-boundary="viewport"
+ data-placement="bottom"
+ data-toggle="dropdown"
+ data-display="static"
>
<icon
:size="12"
- name="remove"
+ name="more"
/>
</button>
+ <div class="dropdown-menu dropdown-menu-right">
+ <ul>
+ <li>
+ <button
+ type="button"
+ @click.stop="discardFileChanges(path)"
+ >
+ {{ __('Discard changes') }}
+ </button>
+ </li>
+ </ul>
+ </div>
</div>
</template>
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 34b366f63ac..9cec73ec00e 100644
--- a/app/assets/javascripts/ide/components/commit_sidebar/unstage_button.vue
+++ b/app/assets/javascripts/ide/components/commit_sidebar/unstage_button.vue
@@ -32,8 +32,10 @@ export default {
:aria-label="__('Unstage changes')"
:title="__('Unstage changes')"
type="button"
- class="btn btn-blank"
+ class="btn btn-blank d-flex align-items-center"
data-container="body"
+ data-boundary="viewport"
+ data-placement="bottom"
@click="unstageChange(path)"
>
<icon
diff --git a/app/assets/javascripts/ide/components/repo_commit_section.vue b/app/assets/javascripts/ide/components/repo_commit_section.vue
index 01df0019fd4..c2c678ff0be 100644
--- a/app/assets/javascripts/ide/components/repo_commit_section.vue
+++ b/app/assets/javascripts/ide/components/repo_commit_section.vue
@@ -93,23 +93,25 @@ export default {
:title="__('Unstaged')"
:key-prefix="$options.stageKeys.unstaged"
:file-list="changedFiles"
- :action-btn-text="__('Stage all')"
+ :action-btn-text="__('Stage all changes')"
:active-file-key="activeFileKey"
- class="is-first"
- icon-name="unstaged"
action="stageAllChanges"
+ action-btn-icon="mobile-issue-close"
item-action-component="stage-button"
+ class="is-first"
+ icon-name="unstaged"
/>
<commit-files-list
:title="__('Staged')"
:key-prefix="$options.stageKeys.staged"
:file-list="stagedFiles"
- :action-btn-text="__('Unstage all')"
+ :action-btn-text="__('Unstage all changes')"
:staged-list="true"
:active-file-key="activeFileKey"
- icon-name="staged"
action="unstageAllChanges"
+ action-btn-icon="history"
item-action-component="unstage-button"
+ icon-name="staged"
/>
</template>
<empty-state
diff --git a/app/assets/stylesheets/pages/repo.scss b/app/assets/stylesheets/pages/repo.scss
index 4b8a3db1d06..0a56153203c 100644
--- a/app/assets/stylesheets/pages/repo.scss
+++ b/app/assets/stylesheets/pages/repo.scss
@@ -540,36 +540,12 @@
margin-right: -$grid-size;
min-height: 60px;
- .multi-file-commit-list-item {
- margin-left: 0;
- margin-right: 0;
- }
-
&.form-text.text-muted {
margin-left: 0;
right: 0;
}
}
-.multi-file-commit-list-item {
- &.is-active {
- background-color: $white-normal;
- }
-
- .multi-file-discard-btn {
- display: none;
- margin-top: -2px;
- margin-left: auto;
- color: $gl-link-color;
- }
-
- &:hover {
- .multi-file-discard-btn {
- display: flex;
- }
- }
-}
-
.multi-file-addition,
.multi-file-addition-solid {
color: $green-500;
@@ -599,7 +575,7 @@
}
}
-.multi-file-commit-list-item,
+.multi-file-commit-list-path,
.ide-file-list .file {
display: flex;
align-items: center;
@@ -616,11 +592,9 @@
}
.multi-file-commit-list-path {
- padding: 0;
- background: none;
- border: 0;
- text-align: left;
- width: 100%;
+ &.is-active {
+ background-color: $white-normal;
+ }
&:hover,
&:focus {
@@ -635,7 +609,7 @@
}
.multi-file-commit-list-file-path {
- @include str-truncated(100%);
+ @include str-truncated(calc(100% - 30px));
&:hover {
text-decoration: underline;
@@ -646,6 +620,16 @@
}
}
+.multi-file-discard-btn {
+ top: 4px;
+ right: 8px;
+ bottom: 4px;
+
+ svg {
+ top: 0;
+ }
+}
+
.multi-file-commit-form {
position: relative;
background-color: $white-light;
@@ -840,18 +824,20 @@
}
.ide-staged-action-btn {
- margin-left: auto;
- line-height: 22px;
+ width: 22px;
+ margin-left: -1px;
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+
+ > svg {
+ top: 0;
+ }
}
.ide-commit-file-count {
min-width: 22px;
- margin-left: auto;
background-color: $gray-light;
- border-radius: $border-radius-default;
border: 1px solid $white-dark;
- line-height: 20px;
- text-align: center;
}
.ide-commit-radios {
diff --git a/changelogs/unreleased/ide-commit-actions-update.yml b/changelogs/unreleased/ide-commit-actions-update.yml
new file mode 100644
index 00000000000..35bee94e156
--- /dev/null
+++ b/changelogs/unreleased/ide-commit-actions-update.yml
@@ -0,0 +1,5 @@
+---
+title: Improve Web IDE commit flow
+merge_request:
+author:
+type: changed
diff --git a/spec/javascripts/ide/components/commit_sidebar/list_item_spec.js b/spec/javascripts/ide/components/commit_sidebar/list_item_spec.js
index 8f7cf24c22f..bf96170f703 100644
--- a/spec/javascripts/ide/components/commit_sidebar/list_item_spec.js
+++ b/spec/javascripts/ide/components/commit_sidebar/list_item_spec.js
@@ -93,14 +93,14 @@ describe('Multi-file editor commit sidebar list item', () => {
describe('is active', () => {
it('does not add active class when dont keys match', () => {
- expect(vm.$el.classList).not.toContain('is-active');
+ expect(vm.$el.querySelector('.is-active')).toBe(null);
});
it('adds active class when keys match', done => {
vm.keyPrefix = 'staged';
vm.$nextTick(() => {
- expect(vm.$el.classList).toContain('is-active');
+ expect(vm.$el.querySelector('.is-active')).not.toBe(null);
done();
});
diff --git a/spec/javascripts/ide/components/commit_sidebar/list_spec.js b/spec/javascripts/ide/components/commit_sidebar/list_spec.js
index 6fb52378386..b786be55019 100644
--- a/spec/javascripts/ide/components/commit_sidebar/list_spec.js
+++ b/spec/javascripts/ide/components/commit_sidebar/list_spec.js
@@ -16,6 +16,7 @@ describe('Multi-file editor commit sidebar list', () => {
iconName: 'staged',
action: 'stageAllChanges',
actionBtnText: 'stage all',
+ actionBtnIcon: 'history',
itemActionComponent: 'stage-button',
activeFileKey: 'staged-testing',
keyPrefix: 'staged',
@@ -42,7 +43,7 @@ describe('Multi-file editor commit sidebar list', () => {
});
it('renders list', () => {
- expect(vm.$el.querySelectorAll('li').length).toBe(1);
+ expect(vm.$el.querySelectorAll('.multi-file-commit-list > li').length).toBe(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 6bf8710bda7..a5b906da8a1 100644
--- a/spec/javascripts/ide/components/commit_sidebar/stage_button_spec.js
+++ b/spec/javascripts/ide/components/commit_sidebar/stage_button_spec.js
@@ -39,7 +39,7 @@ describe('IDE stage file button', () => {
});
it('calls store with discard button', () => {
- vm.$el.querySelectorAll('.btn')[1].click();
+ vm.$el.querySelector('.dropdown-menu button').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 531bcd6e540..6bf309fb4bf 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', () => {
});
it('renders a commit section', () => {
- const changedFileElements = [...vm.$el.querySelectorAll('.multi-file-commit-list li')];
+ const changedFileElements = [...vm.$el.querySelectorAll('.multi-file-commit-list > li')];
const allFiles = vm.$store.state.changedFiles.concat(vm.$store.state.stagedFiles);
expect(changedFileElements.length).toEqual(4);
@@ -140,22 +140,26 @@ describe('RepoCommitSection', () => {
vm.$el.querySelector('.multi-file-discard-btn .btn').click();
Vue.nextTick(() => {
- expect(vm.$el.querySelector('.ide-commit-list-container').querySelectorAll('li').length).toBe(
- 1,
- );
+ expect(
+ vm.$el
+ .querySelector('.ide-commit-list-container')
+ .querySelectorAll('.multi-file-commit-list > li').length,
+ ).toBe(1);
done();
});
});
it('discards a single file', done => {
- vm.$el.querySelectorAll('.multi-file-discard-btn .btn')[1].click();
+ vm.$el.querySelector('.multi-file-discard-btn .dropdown-menu button').click();
Vue.nextTick(() => {
expect(vm.$el.querySelector('.ide-commit-list-container').textContent).not.toContain('file1');
- expect(vm.$el.querySelector('.ide-commit-list-container').querySelectorAll('li').length).toBe(
- 1,
- );
+ expect(
+ vm.$el
+ .querySelector('.ide-commit-list-container')
+ .querySelectorAll('.multi-file-commit-list > li').length,
+ ).toBe(1);
done();
});