Commit 4e15a927 authored by Bryce Johnson's avatar Bryce Johnson

Set up basic architecture for MR widget app.

parent 4d55bca8
(() => {
gl.MergeRequestWidget.approvalsBody = {
props: ['approverNames', 'approvalsLeft', 'canApprove'],
computed: {
approvalsRequiredStringified() {
return this.approvalsLeft === 1 ? "one more approval" :
`${this.approvalsLeft} more approvals`;
},
approverNamesStringified() {
const lastIdx = this.approverNames.length - 1;
return this.approverNames.reduce((memo, curr, index) => {
return index !== lastIdx ? `${memo} ${curr}, ` : `${memo} or ${curr}`;
}, '');
}
},
methods: {
approveMergeRequest() {
this.$emit('user-gives-approval');
},
},
template: `
<div> Hello approval body
<h4> Requires {{ approvalsRequiredStringified }} (from {{ approverNamesStringified }})</h4>
<div class="append-bottom-10">
<button v-if='canApprove' @click='approveMergeRequest' class="btn btn-primary approve-btn">Approve Merge Request</button>
</div>
</div>
`,
};
})();
\ No newline at end of file
(() => {
const PendingApprover = {
data() {
return {
dottedCircleUrl: '/assets/no_avatar.png'
};
},
template: `
<span>
<img width="24" alt="Required Approver" :src="dottedCircleUrl" class="avatar avatar-inline s24">
</span>
`
};
gl.MergeRequestWidget.approvalsFooter = {
props: ['approverNames', 'canApprove'],
methods: {
removeApproval() {
this.$emit('remove-approval');
}
},
components: {
'pending-approver': PendingApprover,
},
template: `
<div>
Hello Approvals Footer
<div>
<div v-for='approver in approverNames'>
{{ approver }}
</div>
<span v-if='canApprove'>
<i class='fa fa-close'></i>
<button @click='removeApproval'>Remove your approval</button>
</span>
</div>
</div>
`
};
})();
(() => {
class MergeRequestWidgetStore {
constructor(el) {
this.dataset = el.dataset;
this.data = {};
// TODO: Break each into their own store
this.initResource();
this.initPermissions();
this.initApprovals();
}
initResource() {
Object.assign(this.data, {
resource: {
canEdit: this.dataset.endpoint
}
});
}
initPermissions() {
Object.assign(this.data, {
permissions: {
canEdit: Boolean(this.dataset.canEdit)
}
});
}
initApprovals() {
const dataset = this.dataset;
Object.assign( this.data, {
approvals: {
approverNames: JSON.parse(dataset.approverNames),
approvalsLeft: Number(dataset.approvalsLeft),
moreApprovals: Number(dataset.approvalsLeft),
}
});
}
}
gl.MergeRequestWidgetStore = MergeRequestWidgetStore;
})()
//= require ./stores/widget_store
//= require ./approvals/approvals_bundle
$(() => {
const el = document.getElementById('merge-request-widget-app');
const Store = new gl.MergeRequestWidgetStore(el);
const app = gl.MergeRequestWidget;
new Vue({
el,
data: Store.data,
components: {
'approvals-body' : app.approvalsBody,
'approvals-footer' : app.approvalsFooter
},
methods: {
unapproveMergeRequest() {
console.log("Parent instance Unapprove MR");
},
approveMergeRequest() {
console.log("Parent instance Approve MR");
}
},
});
});
......@@ -4,6 +4,7 @@
- content_for :page_specific_javascripts do
= page_specific_javascript_tag('lib/vue_resource.js')
= page_specific_javascript_tag('diff_notes/diff_notes_bundle.js')
= page_specific_javascript_tag('merge_request_widget/widget_bundle.js')
.merge-request{'data-url' => merge_request_path(@merge_request)}
= render "projects/merge_requests/show/mr_title"
......
.mr-state-widget
#merge-request-widget-app.mr-state-widget{ 'data-approver-names' => @merge_request.approvers_left.map(&:name),'data-approvals-left' => @merge_request.approvals_left,
'data-more-approvals' => (@merge_request.approvals_left - @merge_request.approvers_left.count),'data-can-edit' => @merge_request.can_approve?(current_user), 'data-endpoint'=> '/myendpoint/tho' }
= render 'projects/merge_requests/widget/heading'
.mr-widget-body
-# After conflicts are resolved, the user is redirected back to the MR page.
......@@ -24,7 +25,7 @@
- elsif @merge_request.work_in_progress?
= render 'projects/merge_requests/widget/open/wip'
- elsif @merge_request.requires_approve? && !@merge_request.approved?
= render 'projects/merge_requests/widget/open/approve'
%approvals-body{ '@give-approval' => 'approveMergeRequest', ':approver-names' => 'approvals.approverNames', ':approvals-left' => 'approvals.approvalsLeft', ':more-approvals' => 'approvals.moreApprovals', ':can-approve' => 'permissions.canEdit' }
- elsif @merge_request.merge_when_build_succeeds?
= render 'projects/merge_requests/widget/open/merge_when_build_succeeds'
- elsif !@merge_request.can_be_merged_by?(current_user)
......@@ -49,6 +50,7 @@
- if @merge_request.approvals.any?
.mr-widget-footer.approved-by-users
Approved by
- @merge_request.approved_by_users.each do |user|
= link_to_member(@project, user, name: false, size: 24)
%approvals-footer{ '@remove-approval' => 'unapproveMergeRequest', ':approver-names' => 'approvals.approverNames', ':approvals-left' => 'approvals.approvalsLeft', ':more-approvals' => 'approvals.moreApprovals', ':can-approve' => 'permissions.canEdit' }
%span{ slot: 'links-to-members'}
- @merge_request.approved_by_users.each do |user|
= link_to_member(@project, user, name: false, size: 24)
%div
%h4
= render_require_section(@merge_request)
- if @merge_request.can_approve?(current_user)
.append-bottom-10
= form_for [:approve, @project.namespace.becomes(Namespace), @project, @merge_request], method: :post do |f|
= f.submit "Approve Merge Request", class: "btn btn-primary approve-btn"
%give-approval{ '@give-approval' => 'approveMergeRequest', ':approverNames' => 'approverNames', ':approvalsLeft' => 'approvalsLeft', ':moreApprovals' => 'moreApprovals', ':canApprove' => 'canApprove' }
.mr-widget-footer.approved-by-users
%remove-approval{ '@remove-approval' => 'unapproveMergeRequest', ':approverNames' => 'approverNames', ':approvalsLeft' => 'approvalsLeft', ':moreApprovals' => 'moreApprovals', ':canApprove' => 'canApprove' }
%span{ slot: 'links-to-members'}
- @merge_request.approved_by_users.each do |user|
= link_to_member(@project, user, name: false, size: 24)
......@@ -95,6 +95,8 @@ module Gitlab
config.assets.precompile << "profile/profile_bundle.js"
config.assets.precompile << "protected_branches/protected_branches_bundle.js"
config.assets.precompile << "diff_notes/diff_notes_bundle.js"
config.assets.precompile << "generic_bundles/vue_resource.js"
config.assets.precompile << "merge_request_widget/widget_bundle.js"
config.assets.precompile << "issuable/issuable_bundle.js"
config.assets.precompile << "boards/boards_bundle.js"
config.assets.precompile << "cycle_analytics/cycle_analytics_bundle.js"
......
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