Commit 25fd2983 authored by Filipa Lacerda's avatar Filipa Lacerda

Merge branch 'ide-commit-actions-update' into 'master'

Improve commit flow in Web IDE

Closes #46122

See merge request gitlab-org/gitlab-ce!19735
parents 6d4a0325 7e8e5229
......@@ -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
......
<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>
......@@ -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>
......@@ -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
......
......@@ -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
......
......@@ -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 {
......
---
title: Improve Web IDE commit flow
merge_request:
author:
type: changed
......@@ -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();
});
......
......@@ -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);
});
});
......
......@@ -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);
});
......
......@@ -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();
});
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment