Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
7a660f80
Commit
7a660f80
authored
Dec 01, 2016
by
Bryce Johnson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Check in arbitrary checkpoint.
parent
385257cc
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
88 additions
and
35 deletions
+88
-35
app/assets/javascripts/merge_request_widget/approvals/components/approvals_body.js.es6
...request_widget/approvals/components/approvals_body.js.es6
+8
-4
app/assets/javascripts/merge_request_widget/approvals/components/approvals_footer.js.es6
...quest_widget/approvals/components/approvals_footer.js.es6
+11
-3
app/assets/javascripts/merge_request_widget/approvals/services/approvals_api.js.es6
...ge_request_widget/approvals/services/approvals_api.js.es6
+14
-16
app/assets/javascripts/merge_request_widget/approvals/stores/approvals_store.js.es6
...ge_request_widget/approvals/stores/approvals_store.js.es6
+47
-3
app/assets/javascripts/merge_request_widget/widget_bundle.js.es6
...ets/javascripts/merge_request_widget/widget_bundle.js.es6
+2
-2
app/assets/javascripts/merge_request_widget/widget_store.js.es6
...sets/javascripts/merge_request_widget/widget_store.js.es6
+1
-1
app/views/projects/merge_requests/widget/_open.html.haml
app/views/projects/merge_requests/widget/_open.html.haml
+5
-6
No files found.
app/assets/javascripts/merge_request_widget/approvals/components/approvals_body.js.es6
View file @
7a660f80
//= require ../stores/approvals_store
//= require ../services/approvals_api
(() => {
const app = gl.MergeRequestWidget;
const api = gl.MergeRequestWidget.ApprovalsApi;
const api = app.ApprovalsApi;
const componentRegistry = app.Components || (app.Components = {});
componentRegistry.approvalsBody = {
name: 'ApprovalsBody',
props: ['approverNames', 'approvalsLeft', '
canApprove
'],
props: ['approverNames', 'approvalsLeft', '
userCanApprove', 'userHasApproved
'],
data() {
return {
loading: true,
...
...
@@ -26,6 +28,9 @@
return newList;
}, '');
},
showApproveButton() {
return this.userCanApprove && !this.userHasApproved;
},
},
methods: {
approveMergeRequest() {
...
...
@@ -41,9 +46,8 @@
<div>
<div>
<h4> Requires {{ approvalsRequiredStringified }} (from {{ approverNamesStringified }})</h4>
<div class='append-bottom-10'>
<div
v-if='showApproveButton'
class='append-bottom-10'>
<button
v-if='canApprove'
@click='approveMergeRequest'
class='btn btn-primary approve-btn'>
Approve Merge Request
...
...
app/assets/javascripts/merge_request_widget/approvals/components/approvals_footer.js.es6
View file @
7a660f80
...
...
@@ -9,12 +9,20 @@
componentRegistry.approvalsFooter = {
name: 'ApprovalsFooter',
props: ['
canUpdateMergeRequest', 'hasApprovedMergeRequest', 'approvedByUsers
'],
props: ['
userCanApprove', 'userHasApproved', 'approvedByUsers', 'approvalsLeft
'],
data() {
return {
loading: true,
};
},
computed: {
hasApprovers() {
return this.approvedByUsers && this.approvedByUsers.length;
},
showUnapproveButton() {
return this.userCanApprove && this.userHasApproved;
},
},
methods: {
removeApproval() {
return api.unapproveMergeRequest();
...
...
@@ -26,7 +34,7 @@
});
},
template: `
<div>
<div
v-if='hasApprovers' class='mr-widget-footer approved-by-users'
>
<div v-for='approver in approvedByUsers'>
<link-to-member-avatar
:avatar-url='approver.avatar.url'
...
...
@@ -34,7 +42,7 @@
:username='approver.username'>
</link-to-member-avatar>
</div>
<span>
<span
v-if='showUnapproveButton'
>
<i class='fa fa-close'></i>
<button @click='removeApproval'>Remove your approval</button>
</span>
...
...
app/assets/javascripts/merge_request_widget/approvals/services/approvals_api.js.es6
View file @
7a660f80
//= require ../stores/approvals_store
// TODO: Determine whether component-specific store should be accessed here as a member
((MergeRequestWidget) => {
function mockApprovalRequest(payload) {
const currentPayload = Object.assign({}, payload.data);
const currentStore = gl.MergeRequestWidget.Store.data.approvals;
const parsedStore = JSON.parse(JSON.stringify(currentStore));
const mockResp = Object.assign(currentPayload, parsedStore);
const store = gl.MergeRequestWidget.Store;
return new Promise((resolve) => {
const approvalsStore = store.data.approvals;
setTimeout(() => {
resolve(
mockResp
);
resolve(
approvalsStore
);
}, 100);
});
}
class ApprovalsApi {
constructor() {
this.store =
null
;
this.store =
gl.MergeRequestWidget.ApprovalsStore
;
this.isFetching = false;
this.hasBeenFetched = true;
}
...
...
@@ -32,22 +32,20 @@
approveMergeRequest() {
const payload = {
type: 'PUT',
data: {
approve: true,
},
type: 'POST',
};
return this.genericApprovalRequest(payload);
return this.genericApprovalRequest(payload).then(() => {
gl.MergeRequestWidget.ApprovalsStore.approve();
});
}
unapproveMergeRequest() {
const payload = {
type: 'PUT',
data: {
approve: false,
},
type: 'DELETE',
};
return this.genericApprovalRequest(payload);
return this.genericApprovalRequest(payload).then(() => {
gl.MergeRequestWidget.ApprovalsStore.unapprove();
});
}
genericApprovalRequest(payload = {}) {
...
...
app/assets/javascripts/merge_request_widget/approvals/stores/approvals_store.js.es6
View file @
7a660f80
(() => {
let singleton;
const adminUser =
'{"id":1,"email":"admin@example.com","created_at":"2016-10-17T17:21:34.545Z","updated_at":"2016-12-01T12:40:12.884Z","name":"Administrator","admin":true,"projects_limit":100,"skype":"","linkedin":"","twitter":"","authentication_token":"9PQj4RxcKbyQwG5uAykL","theme_id":2,"bio":"","username":"root","can_create_group":true,"can_create_team":false,"state":"active","color_scheme_id":1,"password_expires_at":null,"created_by_id":null,"last_credential_check_at":null,"avatar":{"url":"/uploads/user/avatar/1/avatar.png"},"hide_no_ssh_key":true,"website_url":"","admin_email_unsubscribed_at":null,"notification_email":"admin@example.com","hide_no_password":false,"password_automatically_set":false,"location":"","encrypted_otp_secret":null,"encrypted_otp_secret_iv":null,"encrypted_otp_secret_salt":null,"otp_required_for_login":false,"otp_backup_codes":null,"public_email":"","dashboard":"projects","project_view":"readme","consumed_timestep":null,"layout":"fixed","hide_project_limit":false,"note":null,"otp_grace_period_started_at":null,"ldap_email":false,"external":false,"organization":"","incoming_email_token":"3rkrn7wdxmeyds49fdmlk7376","authorized_projects_populated":true}';
class ApprovalsStore {
constructor(rootEl) {
...
...
@@ -13,18 +15,60 @@
init(rootEl) {
this.data = {};
const dataset = rootEl.dataset;
const approverNames = JSON.parse(dataset.approverNames);
this.assignToData({
approvedByUsers: JSON.parse(dataset.approvedByUsers),
approverNames: JSON.parse(dataset.approverNames),
approvalsRequired: Number(dataset.approvalsRequired),
approverNames,
approvalsLeft: Number(dataset.approvalsLeft),
moreApprovals: Number(dataset.moreApprovals),
userHasApproved: Boolean(true),
userCanApprove: Boolean(true),
});
}
assignToData(val) {
Object.assign(this.data, val);
}
/** TODO: remove after backend integerated */
approve() {
const approvedByUsers = this.data.approvedByUsers;
const approverNames = this.data.approverNames;
const userCanApprove = this.data.userCanApprove;
const index = approverNames.indexOf("Administrator");
approverNames.splice(index, 1);
approvedByUsers.push(JSON.parse(adminUser));
this.assignToData({
approverNames,
approvedByUsers,
userHasApproved: true,
userCanApprove: true,
approvalsLeft: this.data.approvalsLeft -= 1
});
}
unapprove() {
debugger;
const approverNames = this.data.approverNames;
const approvedByUsers = this.data.approvedByUsers;
approverNames.push("Administrator");
approvedByUsers.pop(0);
this.assignToData({
approverNames,
approvedByUsers,
userHasApproved: false,
userCanApprove: true,
approvalsLeft: this.data.approvalsLeft += 1
});
}
}
gl.MergeRequestWidget.ApprovalsStore = ApprovalsStore;
})();
// TODO: Document the weirdness of shared data because of the UI
app/assets/javascripts/merge_request_widget/widget_bundle.js.es6
View file @
7a660f80
//= require ./
stores/
widget_store
//= require ./
services/widget_service
//= require ./widget_store
//= require ./
approvals/services/approvals_api
//= require ./approvals/approvals_bundle
((MergeRequestWidget) => {
...
...
app/assets/javascripts/merge_request_widget/
stores/
widget_store.js.es6
→
app/assets/javascripts/merge_request_widget/widget_store.js.es6
View file @
7a660f80
//= require .
.
/approvals/stores/approvals_store
//= require ./approvals/stores/approvals_store
((MergeRequestWidget) => {
let singleton;
...
...
app/views/projects/merge_requests/widget/_open.html.haml
View file @
7a660f80
-
approvers_names
=
@merge_request
.
approvers_left
.
map
(
&
:name
).
to_json
-
more_approvals
=
@merge_request
.
approvals_left
-
@merge_request
.
approvers_left
.
count
-
approvals_required
=
@merge_request
.
approvals_required
-
approvals_left
=
@merge_request
.
approvals_left
-
content_for
:page_specific_javascripts
do
=
page_specific_javascript_tag
(
'merge_request_widget/widget_bundle.js'
)
#merge-request-widget-app
.mr-state-widget
{
'data-approved-by-users'
=>
@merge_request
.
approved_by_users
.
to_json
,
'data-approver-names'
=>
approvers_names
,
'data-approvals-left'
=>
approvals_left
,
'data-
more-approvals'
=>
more_approvals
,
'data-endpoint'
=>
'/myendpoint/tho'
}
#merge-request-widget-app
.mr-state-widget
{
'data-approved-by-users'
=>
@merge_request
.
approved_by_users
.
to_json
,
'data-approver-names'
=>
approvers_names
,
'data-approvals-left'
=>
approvals_left
,
'data-
approvals-required'
=>
approvals_required
,
'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.
...
...
@@ -30,7 +30,7 @@
-
elsif
@merge_request
.
work_in_progress?
=
render
'projects/merge_requests/widget/open/wip'
-
elsif
@merge_request
.
requires_approve?
&&
!
@merge_request
.
approved?
%approvals-body
{
':approver-names'
=>
'approvals.approverNames'
,
':approvals-left'
=>
'approvals.approvalsLeft'
,
':
canApprove'
=>
'approvals.canApprove
'
}
%approvals-body
{
':approver-names'
=>
'approvals.approverNames'
,
':approvals-left'
=>
'approvals.approvalsLeft'
,
':
user-can-approve'
=>
'approvals.userCanApprove'
,
':user-has-approved'
=>
'approvals.userHasApproved
'
}
-
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
)
...
...
@@ -54,7 +54,6 @@
=
mr_assign_issues_link
-
if
@merge_request
.
approvals
.
any?
.mr-widget-footer.approved-by-users
%approvals-footer
{
':approver-names'
=>
'approvals.approverNames'
,
':approvals-left'
=>
'approvals.approvalsLeft'
,
':canApprove'
=>
'approvals.canApprove'
,
':approved-by-users'
=>
'approvals.approvedByUsers'
}
=
icon
(
'spinner spin'
,
class:
'loading-icon'
)
%approvals-footer
{
':approved-by-users'
=>
'approvals.approvedByUsers'
,
':approver-names'
=>
'approvals.approverNames'
,
':approvals-left'
=>
'approvals.approvalsLeft'
,
':user-can-approve'
=>
'approvals.userCanApprove'
,
':user-has-approved'
=>
'approvals.userHasApproved'
}
=
icon
(
'spinner spin'
,
class:
'loading-icon'
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment