Merge branch 'acet-mr-widget-nothing-to-commit-state' into 'master'
MRWidget: Implement new design for nothing to commit state. Closes #29320 See merge request !11266
This commit is contained in:
commit
433070dc95
8 changed files with 94 additions and 13 deletions
|
@ -1,17 +1,42 @@
|
||||||
|
import emptyStateSVG from 'icons/_mr_widget_empty_state.svg';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'MRWidgetNothingToMerge',
|
name: 'MRWidgetNothingToMerge',
|
||||||
|
props: {
|
||||||
|
mr: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return { emptyStateSVG };
|
||||||
|
},
|
||||||
template: `
|
template: `
|
||||||
<div class="mr-widget-body">
|
<div class="mr-widget-body empty-state">
|
||||||
<button
|
<div class="row">
|
||||||
type="button"
|
<div class="artwork col-sm-5 col-sm-push-7 col-xs-12 text-center">
|
||||||
class="btn btn-success btn-small"
|
<span v-html="emptyStateSVG"></span>
|
||||||
disabled="true">
|
</div>
|
||||||
Merge
|
<div class="text col-sm-7 col-sm-pull-5 col-xs-12">
|
||||||
</button>
|
<span>
|
||||||
<span class="bold">
|
Merge requests are a place to propose changes you have made to a project
|
||||||
There is nothing to merge from source branch into target branch.
|
and discuss those changes with others.
|
||||||
Please push new commits or use a different branch.
|
</span>
|
||||||
</span>
|
<p>
|
||||||
|
Interested parties can even contribute by pushing commits if they want to.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Currently there are no changes in this merge request's source branch.
|
||||||
|
Please push new commits or use a different branch.
|
||||||
|
</p>
|
||||||
|
<a
|
||||||
|
v-if="mr.newBlobPath"
|
||||||
|
:href="mr.newBlobPath"
|
||||||
|
class="btn btn-inverted btn-save">
|
||||||
|
Create file
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`,
|
`,
|
||||||
};
|
};
|
||||||
|
|
|
@ -58,6 +58,7 @@ export default class MergeRequestStore {
|
||||||
this.statusPath = data.status_path;
|
this.statusPath = data.status_path;
|
||||||
this.emailPatchesPath = data.email_patches_path;
|
this.emailPatchesPath = data.email_patches_path;
|
||||||
this.plainDiffPath = data.plain_diff_path;
|
this.plainDiffPath = data.plain_diff_path;
|
||||||
|
this.newBlobPath = data.new_blob_path;
|
||||||
this.createIssueToResolveDiscussionsPath = data.create_issue_to_resolve_discussions_path;
|
this.createIssueToResolveDiscussionsPath = data.create_issue_to_resolve_discussions_path;
|
||||||
this.mergeCheckPath = data.merge_check_path;
|
this.mergeCheckPath = data.merge_check_path;
|
||||||
this.mergeActionsContentPath = data.commit_change_content_path;
|
this.mergeActionsContentPath = data.commit_change_content_path;
|
||||||
|
|
|
@ -353,6 +353,22 @@
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
margin-left: 12px;
|
margin-left: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.empty-state {
|
||||||
|
.artwork {
|
||||||
|
margin-bottom: $gl-padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
span {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-top: $gl-padding;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mr-widget-footer {
|
.mr-widget-footer {
|
||||||
|
|
|
@ -97,6 +97,14 @@ class MergeRequestEntity < IssuableEntity
|
||||||
presenter(merge_request).target_branch_commits_path
|
presenter(merge_request).target_branch_commits_path
|
||||||
end
|
end
|
||||||
|
|
||||||
|
expose :new_blob_path do |merge_request|
|
||||||
|
if can?(current_user, :push_code, merge_request.project)
|
||||||
|
namespace_project_new_blob_path(merge_request.project.namespace,
|
||||||
|
merge_request.project,
|
||||||
|
merge_request.source_branch)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
expose :conflict_resolution_path do |merge_request|
|
expose :conflict_resolution_path do |merge_request|
|
||||||
presenter(merge_request).conflict_resolution_path
|
presenter(merge_request).conflict_resolution_path
|
||||||
end
|
end
|
||||||
|
|
1
app/views/shared/icons/_mr_widget_empty_state.svg
Normal file
1
app/views/shared/icons/_mr_widget_empty_state.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 9.8 KiB |
|
@ -86,6 +86,7 @@
|
||||||
"email_patches_path": { "type": "string" },
|
"email_patches_path": { "type": "string" },
|
||||||
"plain_diff_path": { "type": "string" },
|
"plain_diff_path": { "type": "string" },
|
||||||
"status_path": { "type": "string" },
|
"status_path": { "type": "string" },
|
||||||
|
"new_blob_path": { "type": "string" },
|
||||||
"merge_check_path": { "type": "string" },
|
"merge_check_path": { "type": "string" },
|
||||||
"ci_environments_status_path": { "type": "string" },
|
"ci_environments_status_path": { "type": "string" },
|
||||||
"merge_commit_message_with_description": { "type": "string" },
|
"merge_commit_message_with_description": { "type": "string" },
|
||||||
|
|
|
@ -4,14 +4,26 @@ import nothingToMergeComponent from '~/vue_merge_request_widget/components/state
|
||||||
describe('MRWidgetNothingToMerge', () => {
|
describe('MRWidgetNothingToMerge', () => {
|
||||||
describe('template', () => {
|
describe('template', () => {
|
||||||
const Component = Vue.extend(nothingToMergeComponent);
|
const Component = Vue.extend(nothingToMergeComponent);
|
||||||
|
const newBlobPath = '/foo';
|
||||||
const vm = new Component({
|
const vm = new Component({
|
||||||
el: document.createElement('div'),
|
el: document.createElement('div'),
|
||||||
|
propsData: {
|
||||||
|
mr: { newBlobPath },
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have correct elements', () => {
|
it('should have correct elements', () => {
|
||||||
expect(vm.$el.classList.contains('mr-widget-body')).toBeTruthy();
|
expect(vm.$el.classList.contains('mr-widget-body')).toBeTruthy();
|
||||||
expect(vm.$el.querySelector('button').getAttribute('disabled')).toBeTruthy();
|
expect(vm.$el.querySelector('a').href).toContain(newBlobPath);
|
||||||
expect(vm.$el.innerText).toContain('There is nothing to merge from source branch into target branch.');
|
expect(vm.$el.innerText).toContain('Currently there are no changes in this merge request\'s source branch');
|
||||||
expect(vm.$el.innerText).toContain('Please push new commits or use a different branch.');
|
expect(vm.$el.innerText).toContain('Please push new commits or use a different branch.');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not show new blob link if there is no link available', () => {
|
||||||
|
vm.mr.newBlobPath = null;
|
||||||
|
Vue.nextTick(() => {
|
||||||
|
expect(vm.$el.querySelector('a')).toEqual(null);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -65,6 +65,23 @@ describe MergeRequestEntity do
|
||||||
.to eq(resource.merge_commit_message(include_description: true))
|
.to eq(resource.merge_commit_message(include_description: true))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'new_blob_path' do
|
||||||
|
context 'when user can push to project' do
|
||||||
|
it 'returns path' do
|
||||||
|
project.add_developer(user)
|
||||||
|
|
||||||
|
expect(subject[:new_blob_path])
|
||||||
|
.to eq("/#{resource.project.full_path}/new/#{resource.source_branch}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user cannot push to project' do
|
||||||
|
it 'returns nil' do
|
||||||
|
expect(subject[:new_blob_path]).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe 'diff_head_sha' do
|
describe 'diff_head_sha' do
|
||||||
before do
|
before do
|
||||||
allow(resource).to receive(:diff_head_sha) { 'sha' }
|
allow(resource).to receive(:diff_head_sha) { 'sha' }
|
||||||
|
|
Loading…
Reference in a new issue