ocp_registry 0.0.1.alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +25 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +65 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/bin/ocp_registry +28 -0
- data/config/example-mysql.yml +40 -0
- data/config/example-sqlite.yml +33 -0
- data/lib/ocp_registry.rb +29 -0
- data/lib/ocp_registry/api_controller.rb +146 -0
- data/lib/ocp_registry/application_manager.rb +213 -0
- data/lib/ocp_registry/cloud_manager/mock.rb +5 -0
- data/lib/ocp_registry/cloud_manager/mock/mock.rb +191 -0
- data/lib/ocp_registry/cloud_manager/mock/model.rb +22 -0
- data/lib/ocp_registry/cloud_manager/openstack.rb +4 -0
- data/lib/ocp_registry/cloud_manager/openstack/cinder_helper.rb +27 -0
- data/lib/ocp_registry/cloud_manager/openstack/keystone_helper.rb +57 -0
- data/lib/ocp_registry/cloud_manager/openstack/nova_helper.rb +37 -0
- data/lib/ocp_registry/cloud_manager/openstack/openstack.rb +126 -0
- data/lib/ocp_registry/common.rb +54 -0
- data/lib/ocp_registry/config.rb +96 -0
- data/lib/ocp_registry/db/001_db_initialize.rb +16 -0
- data/lib/ocp_registry/error.rb +16 -0
- data/lib/ocp_registry/mail_client.rb +141 -0
- data/lib/ocp_registry/models.rb +7 -0
- data/lib/ocp_registry/models/registry_application.rb +10 -0
- data/lib/ocp_registry/runner.rb +47 -0
- data/lib/ocp_registry/version.rb +3 -0
- data/lib/ocp_registry/yaml_helper.rb +23 -0
- data/mail_template/approve_admin.erb +14 -0
- data/mail_template/approve_user.erb +22 -0
- data/mail_template/refuse_admin.erb +16 -0
- data/mail_template/refuse_user.erb +17 -0
- data/mail_template/request_admin.erb +15 -0
- data/mail_template/request_user.erb +16 -0
- data/ocp_registry.gemspec +34 -0
- data/public/bootstrap/css/bootstrap-responsive.css +1109 -0
- data/public/bootstrap/css/bootstrap-responsive.min.css +9 -0
- data/public/bootstrap/css/bootstrap.css +6167 -0
- data/public/bootstrap/css/bootstrap.min.css +9 -0
- data/public/bootstrap/img/glyphicons-halflings-white.png +0 -0
- data/public/bootstrap/img/glyphicons-halflings.png +0 -0
- data/public/bootstrap/js/bootstrap.js +2280 -0
- data/public/bootstrap/js/bootstrap.min.js +6 -0
- data/public/common.css +104 -0
- data/public/favicon.ico +0 -0
- data/public/images/loading.gif +0 -0
- data/public/jquery-1.10.2.min.js +6 -0
- data/public/jquery-1.10.2.min.map +1 -0
- data/public/jquery.json-2.4.min.js +23 -0
- data/public/noty/.gitignore +8 -0
- data/public/noty/LICENSE.txt +20 -0
- data/public/noty/README.markdown +22 -0
- data/public/noty/demo/allLayouts.html +91 -0
- data/public/noty/demo/allTypes.html +86 -0
- data/public/noty/demo/api.html +103 -0
- data/public/noty/demo/buttons.css +320 -0
- data/public/noty/demo/consumingAlert.html +78 -0
- data/public/noty/demo/customContainer.html +90 -0
- data/public/noty/demo/index.html +66 -0
- data/public/noty/demo/jquery-1.7.2.min.js +4 -0
- data/public/noty/demo/usingMaxVisible.html +104 -0
- data/public/noty/demo/usingWithButtons.html +104 -0
- data/public/noty/demo/usingWithButtons2.html +98 -0
- data/public/noty/demo/usingWithModal.html +87 -0
- data/public/noty/demo/usingWithOldOptions.html +110 -0
- data/public/noty/js/jquery.noty.js +547 -0
- data/public/noty/js/layouts/bottom.js +34 -0
- data/public/noty/js/layouts/bottomCenter.js +41 -0
- data/public/noty/js/layouts/bottomLeft.js +43 -0
- data/public/noty/js/layouts/bottomRight.js +43 -0
- data/public/noty/js/layouts/center.js +56 -0
- data/public/noty/js/layouts/centerLeft.js +61 -0
- data/public/noty/js/layouts/centerRight.js +61 -0
- data/public/noty/js/layouts/inline.js +31 -0
- data/public/noty/js/layouts/top.js +34 -0
- data/public/noty/js/layouts/topCenter.js +41 -0
- data/public/noty/js/layouts/topLeft.js +43 -0
- data/public/noty/js/layouts/topRight.js +43 -0
- data/public/noty/js/promise.js +432 -0
- data/public/noty/js/themes/default.js +156 -0
- data/views/apply.erb +134 -0
- data/views/base.erb +25 -0
- data/views/list.erb +41 -0
- data/views/review.erb +141 -0
- data/views/show.erb +96 -0
- data/views/view.erb +7 -0
- metadata +294 -0
@@ -0,0 +1,156 @@
|
|
1
|
+
;(function($) {
|
2
|
+
|
3
|
+
$.noty.themes.defaultTheme = {
|
4
|
+
name: 'defaultTheme',
|
5
|
+
helpers: {
|
6
|
+
borderFix: function() {
|
7
|
+
if (this.options.dismissQueue) {
|
8
|
+
var selector = this.options.layout.container.selector + ' ' + this.options.layout.parent.selector;
|
9
|
+
switch (this.options.layout.name) {
|
10
|
+
case 'top':
|
11
|
+
$(selector).css({borderRadius: '0px 0px 0px 0px'});
|
12
|
+
$(selector).last().css({borderRadius: '0px 0px 5px 5px'}); break;
|
13
|
+
case 'topCenter': case 'topLeft': case 'topRight':
|
14
|
+
case 'bottomCenter': case 'bottomLeft': case 'bottomRight':
|
15
|
+
case 'center': case 'centerLeft': case 'centerRight': case 'inline':
|
16
|
+
$(selector).css({borderRadius: '0px 0px 0px 0px'});
|
17
|
+
$(selector).first().css({'border-top-left-radius': '5px', 'border-top-right-radius': '5px'});
|
18
|
+
$(selector).last().css({'border-bottom-left-radius': '5px', 'border-bottom-right-radius': '5px'}); break;
|
19
|
+
case 'bottom':
|
20
|
+
$(selector).css({borderRadius: '0px 0px 0px 0px'});
|
21
|
+
$(selector).first().css({borderRadius: '5px 5px 0px 0px'}); break;
|
22
|
+
default: break;
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
26
|
+
},
|
27
|
+
modal: {
|
28
|
+
css: {
|
29
|
+
position: 'fixed',
|
30
|
+
width: '100%',
|
31
|
+
height: '100%',
|
32
|
+
backgroundColor: '#000',
|
33
|
+
zIndex: 10000,
|
34
|
+
opacity: 0.6,
|
35
|
+
display: 'none',
|
36
|
+
left: 0,
|
37
|
+
top: 0
|
38
|
+
}
|
39
|
+
},
|
40
|
+
style: function() {
|
41
|
+
|
42
|
+
this.$bar.css({
|
43
|
+
overflow: 'hidden',
|
44
|
+
background: "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABsAAAAoCAYAAAAPOoFWAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAPZJREFUeNq81tsOgjAMANB2ov7/7ypaN7IlIwi9rGuT8QSc9EIDAsAznxvY4pXPKr05RUE5MEVB+TyWfCEl9LZApYopCmo9C4FKSMtYoI8Bwv79aQJU4l6hXXCZrQbokJEksxHo9KMOgc6w1atHXM8K9DVC7FQnJ0i8iK3QooGgbnyKgMDygBWyYFZoqx4qS27KqLZJjA1D0jK6QJcYEQEiWv9PGkTsbqxQ8oT+ZtZB6AkdsJnQDnMoHXHLGKOgDYuCWmYhEERCI5gaamW0bnHdA3k2ltlIN+2qKRyCND0bhqSYCyTB3CAOc4WusBEIpkeBuPgJMAAX8Hs1NfqHRgAAAABJRU5ErkJggg==') repeat-x scroll left top #fff"
|
45
|
+
});
|
46
|
+
|
47
|
+
this.$message.css({
|
48
|
+
fontSize: '13px',
|
49
|
+
lineHeight: '16px',
|
50
|
+
textAlign: 'center',
|
51
|
+
padding: '8px 10px 9px',
|
52
|
+
width: 'auto',
|
53
|
+
position: 'relative'
|
54
|
+
});
|
55
|
+
|
56
|
+
this.$closeButton.css({
|
57
|
+
position: 'absolute',
|
58
|
+
top: 4, right: 4,
|
59
|
+
width: 10, height: 10,
|
60
|
+
background: "url(data:image/png;base64,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)",
|
61
|
+
display: 'none',
|
62
|
+
cursor: 'pointer'
|
63
|
+
});
|
64
|
+
|
65
|
+
this.$buttons.css({
|
66
|
+
padding: 5,
|
67
|
+
textAlign: 'right',
|
68
|
+
borderTop: '1px solid #ccc',
|
69
|
+
backgroundColor: '#fff'
|
70
|
+
});
|
71
|
+
|
72
|
+
this.$buttons.find('button').css({
|
73
|
+
marginLeft: 5
|
74
|
+
});
|
75
|
+
|
76
|
+
this.$buttons.find('button:first').css({
|
77
|
+
marginLeft: 0
|
78
|
+
});
|
79
|
+
|
80
|
+
this.$bar.bind({
|
81
|
+
mouseenter: function() { $(this).find('.noty_close').stop().fadeTo('normal',1); },
|
82
|
+
mouseleave: function() { $(this).find('.noty_close').stop().fadeTo('normal',0); }
|
83
|
+
});
|
84
|
+
|
85
|
+
switch (this.options.layout.name) {
|
86
|
+
case 'top':
|
87
|
+
this.$bar.css({
|
88
|
+
borderRadius: '0px 0px 5px 5px',
|
89
|
+
borderBottom: '2px solid #eee',
|
90
|
+
borderLeft: '2px solid #eee',
|
91
|
+
borderRight: '2px solid #eee',
|
92
|
+
boxShadow: "0 2px 4px rgba(0, 0, 0, 0.1)"
|
93
|
+
});
|
94
|
+
break;
|
95
|
+
case 'topCenter': case 'center': case 'bottomCenter': case 'inline':
|
96
|
+
this.$bar.css({
|
97
|
+
borderRadius: '5px',
|
98
|
+
border: '1px solid #eee',
|
99
|
+
boxShadow: "0 2px 4px rgba(0, 0, 0, 0.1)"
|
100
|
+
});
|
101
|
+
this.$message.css({fontSize: '13px', textAlign: 'center'});
|
102
|
+
break;
|
103
|
+
case 'topLeft': case 'topRight':
|
104
|
+
case 'bottomLeft': case 'bottomRight':
|
105
|
+
case 'centerLeft': case 'centerRight':
|
106
|
+
this.$bar.css({
|
107
|
+
borderRadius: '5px',
|
108
|
+
border: '1px solid #eee',
|
109
|
+
boxShadow: "0 2px 4px rgba(0, 0, 0, 0.1)"
|
110
|
+
});
|
111
|
+
this.$message.css({fontSize: '13px', textAlign: 'left'});
|
112
|
+
break;
|
113
|
+
case 'bottom':
|
114
|
+
this.$bar.css({
|
115
|
+
borderRadius: '5px 5px 0px 0px',
|
116
|
+
borderTop: '2px solid #eee',
|
117
|
+
borderLeft: '2px solid #eee',
|
118
|
+
borderRight: '2px solid #eee',
|
119
|
+
boxShadow: "0 -2px 4px rgba(0, 0, 0, 0.1)"
|
120
|
+
});
|
121
|
+
break;
|
122
|
+
default:
|
123
|
+
this.$bar.css({
|
124
|
+
border: '2px solid #eee',
|
125
|
+
boxShadow: "0 2px 4px rgba(0, 0, 0, 0.1)"
|
126
|
+
});
|
127
|
+
break;
|
128
|
+
}
|
129
|
+
|
130
|
+
switch (this.options.type) {
|
131
|
+
case 'alert': case 'notification':
|
132
|
+
this.$bar.css({backgroundColor: '#FFF', borderColor: '#CCC', color: '#444'}); break;
|
133
|
+
case 'warning':
|
134
|
+
this.$bar.css({backgroundColor: '#FFEAA8', borderColor: '#FFC237', color: '#826200'});
|
135
|
+
this.$buttons.css({borderTop: '1px solid #FFC237'}); break;
|
136
|
+
case 'error':
|
137
|
+
this.$bar.css({backgroundColor: 'red', borderColor: 'darkred', color: '#FFF'});
|
138
|
+
this.$message.css({fontWeight: 'bold'});
|
139
|
+
this.$buttons.css({borderTop: '1px solid darkred'}); break;
|
140
|
+
case 'information':
|
141
|
+
this.$bar.css({backgroundColor: '#57B7E2', borderColor: '#0B90C4', color: '#FFF'});
|
142
|
+
this.$buttons.css({borderTop: '1px solid #0B90C4'}); break;
|
143
|
+
case 'success':
|
144
|
+
this.$bar.css({backgroundColor: 'lightgreen', borderColor: '#50C24E', color: 'darkgreen'});
|
145
|
+
this.$buttons.css({borderTop: '1px solid #50C24E'});break;
|
146
|
+
default:
|
147
|
+
this.$bar.css({backgroundColor: '#FFF', borderColor: '#CCC', color: '#444'}); break;
|
148
|
+
}
|
149
|
+
},
|
150
|
+
callback: {
|
151
|
+
onShow: function() { $.noty.themes.defaultTheme.helpers.borderFix.apply(this); },
|
152
|
+
onClose: function() { $.noty.themes.defaultTheme.helpers.borderFix.apply(this); }
|
153
|
+
}
|
154
|
+
};
|
155
|
+
|
156
|
+
})(jQuery);
|
data/views/apply.erb
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
|
2
|
+
<div class="bordered optDialog">
|
3
|
+
<legend>Create Project</legend>
|
4
|
+
|
5
|
+
<%=erb :show, :locals => {:data=>data, :readonly=>false} %>
|
6
|
+
|
7
|
+
<div class="optAction" id="optAction">
|
8
|
+
<button id="optSubmit" type="button" class="btn btn-primary toRight"
|
9
|
+
data-loading-text="Loading ..."
|
10
|
+
data-complete-text="Completed!">
|
11
|
+
Submit</button>
|
12
|
+
<img class="loadingIcon toRight" id="optActionLoadingIcon" src="/images/loading.gif" alt="" />
|
13
|
+
<div class="clear"></div>
|
14
|
+
</div>
|
15
|
+
|
16
|
+
</div>
|
17
|
+
|
18
|
+
|
19
|
+
<script type="text/javascript">
|
20
|
+
|
21
|
+
(function(){
|
22
|
+
|
23
|
+
$(document).ready(init);
|
24
|
+
|
25
|
+
function init(){
|
26
|
+
initOptSubmit();
|
27
|
+
}
|
28
|
+
|
29
|
+
function initOptSubmit(){
|
30
|
+
$('#optSubmit').click(function(){
|
31
|
+
$.noty.closeAll();
|
32
|
+
|
33
|
+
//check the data corrections
|
34
|
+
var ret=checkTenantFields();
|
35
|
+
if(!ret.ret){
|
36
|
+
var fieldNamesStr="";
|
37
|
+
$.each(ret.fields, function(i, v){
|
38
|
+
if(i>=ret.fields.length-1){
|
39
|
+
fieldNamesStr+=v;
|
40
|
+
}else{
|
41
|
+
fieldNamesStr+=v+" and ";
|
42
|
+
}
|
43
|
+
});
|
44
|
+
|
45
|
+
noty({text: "Field "+fieldNamesStr+" "+((ret.fields.length>1)?"are":"is")+" invalid.", type: 'error'});
|
46
|
+
return;
|
47
|
+
}
|
48
|
+
|
49
|
+
//do the submission
|
50
|
+
submitBtnToLoading();
|
51
|
+
var data=generateTenantRequest();
|
52
|
+
|
53
|
+
$.post('/v1/applications', data, 'json').done(function(data){
|
54
|
+
data = $.evalJSON(data);
|
55
|
+
if(data.status&&data.status=='error'){
|
56
|
+
//server returned error
|
57
|
+
noty({text: 'Failed to Submit Your Request: '+(data.message?data.message:'Unknown Error'), type:'error'});
|
58
|
+
submitBtnToReady();
|
59
|
+
}else{
|
60
|
+
noty({text: 'Successfully Submitted Your Request! You Can Close This Window Now.', type:'success'});
|
61
|
+
submitBtnToComplete();
|
62
|
+
}
|
63
|
+
}).fail(function(){
|
64
|
+
noty({text: 'Failed to Submit Your Request: Connection Error. You May Retry Later.', type:'error'});
|
65
|
+
submitBtnToReady();
|
66
|
+
});
|
67
|
+
|
68
|
+
});
|
69
|
+
}
|
70
|
+
|
71
|
+
function submitBtnToLoading(){
|
72
|
+
$('#optSubmit').button('loading');
|
73
|
+
$('#optSubmit').attr('disabled', 'true');
|
74
|
+
$('#optActionLoadingIcon').show();
|
75
|
+
}
|
76
|
+
|
77
|
+
function submitBtnToReady(){
|
78
|
+
$('#optSubmit').button('reset');
|
79
|
+
$('#optSubmit').removeAttr('disabled');
|
80
|
+
$('#optActionLoadingIcon').hide();
|
81
|
+
}
|
82
|
+
|
83
|
+
function submitBtnToComplete(){
|
84
|
+
//$('#optSubmit').button('complete'); //BUG here: I don't use this. Because this will cause the button to be enabled. I want it to keep disabled.
|
85
|
+
$('#optSubmit').text("Completed");
|
86
|
+
$('#optSubmit').attr('disabled', 'true');
|
87
|
+
$('#optActionLoadingIcon').hide();
|
88
|
+
}
|
89
|
+
|
90
|
+
function checkTenantFields(){
|
91
|
+
var project=$('#tenantInfo input[name=project]').val();
|
92
|
+
var email=$('#tenantInfo input[name=email]').val();
|
93
|
+
|
94
|
+
var result={ret:true, fields:[]};
|
95
|
+
|
96
|
+
if(!project||project.length<=0){
|
97
|
+
result.ret=false;
|
98
|
+
result.fields.push("project");
|
99
|
+
}
|
100
|
+
if(!email||email.length<=0){
|
101
|
+
result.ret=false;
|
102
|
+
result.fields.push("email");
|
103
|
+
}
|
104
|
+
|
105
|
+
return result;
|
106
|
+
}
|
107
|
+
|
108
|
+
function generateTenantRequest(){
|
109
|
+
var data={
|
110
|
+
project : $('#tenantInfo input[name=project]').val(),
|
111
|
+
description : $('#tenantInfo input[name=description]').val(),
|
112
|
+
email : $('#tenantInfo input[name=email]').val(),
|
113
|
+
settings :
|
114
|
+
{
|
115
|
+
metadata_items : $('#quota input[name=metadata_items]').val(),
|
116
|
+
cores : $('#quota input[name=cores]').val(),
|
117
|
+
instances : $('#quota input[name=instances]').val(),
|
118
|
+
injected_files : $('#quota input[name=injected_files]').val(),
|
119
|
+
injected_file_content_bytes : $('#quota input[name=injected_file_content_bytes]').val(),
|
120
|
+
volumes : $('#quota input[name=volumes]').val(),
|
121
|
+
gigabytes : $('#quota input[name=gigabytes]').val(),
|
122
|
+
ram : $('#quota input[name=ram]').val(),
|
123
|
+
floating_ips : $('#quota input[name=floating_ips]').val(),
|
124
|
+
fixed_ips : $('#quota input[name=floating_ips]').val(),
|
125
|
+
security_groups : $('#quota input[name=security_groups]').val(),
|
126
|
+
security_group_rules : $('#quota input[name=security_group_rules]').val()
|
127
|
+
}
|
128
|
+
};
|
129
|
+
return $.toJSON( data );
|
130
|
+
}
|
131
|
+
|
132
|
+
})();
|
133
|
+
|
134
|
+
</script>
|
data/views/base.erb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title></title>
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6
|
+
<!-- Bootstrap -->
|
7
|
+
<link href="/bootstrap/css/bootstrap.min.css" rel="stylesheet" media="screen">
|
8
|
+
<link rel="stylesheet" type="text/css" href="/common.css">
|
9
|
+
<script src="/jquery-1.10.2.min.js"></script>
|
10
|
+
<script src="/bootstrap/js/bootstrap.min.js"></script>
|
11
|
+
<script type="text/javascript" src="/noty/js/jquery.noty.js"></script>
|
12
|
+
<script type="text/javascript" src="/noty/js/layouts/top.js"></script>
|
13
|
+
<script type="text/javascript" src="/noty/js/layouts/topLeft.js"></script>
|
14
|
+
<script type="text/javascript" src="/noty/js/layouts/topRight.js"></script>
|
15
|
+
<script type="text/javascript" src="/noty/js/layouts/topCenter.js"></script>
|
16
|
+
<script type="text/javascript" src="/noty/js/themes/default.js"></script>
|
17
|
+
<script type="text/javascript" src="/jquery.json-2.4.min.js"></script>
|
18
|
+
</head>
|
19
|
+
<body>
|
20
|
+
<div class="container">
|
21
|
+
<%=yield %>
|
22
|
+
</div>
|
23
|
+
|
24
|
+
</body>
|
25
|
+
</html>
|
data/views/list.erb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
<div class="page-header">
|
2
|
+
<h1>Projects</h1>
|
3
|
+
</div>
|
4
|
+
<div class="table_wrapper">
|
5
|
+
<table class="table table-bordered table-striped datatable">
|
6
|
+
<thead>
|
7
|
+
<tr>
|
8
|
+
<th class="sortable normal_column">Name</th>
|
9
|
+
<th class="sortable normal_column">Description</th>
|
10
|
+
<th class="sortable normal_column">Project ID</th>
|
11
|
+
<th class="sortable normal_column">Status</th>
|
12
|
+
<th class="sortable normal_column">Requestor</th>
|
13
|
+
<th class="normal_column">Action</th>
|
14
|
+
</tr>
|
15
|
+
</thead>
|
16
|
+
<tbody>
|
17
|
+
<% data.each do |app| %>
|
18
|
+
<tr>
|
19
|
+
<td class="sortable normal_column"><%=app[:project]%></td>
|
20
|
+
<td class="sortable normal_column"><%=app[:description]%></td>
|
21
|
+
<td class="sortable normal_column"><%=app[:id]%></td>
|
22
|
+
<td class="status_up sortable normal_column"><%=app[:state]%></td>
|
23
|
+
<td class="sortable normal_column"><%=app[:email]%></td>
|
24
|
+
<td class="normal_column">
|
25
|
+
<% link = "/v1/applications/#{app[:id]}"
|
26
|
+
link += "?review=true" if mark && mark[:review] %>
|
27
|
+
<a href="<%=link%>" class="btn btn-small">View</a>
|
28
|
+
</td>
|
29
|
+
</tr>
|
30
|
+
<% end %>
|
31
|
+
</tbody>
|
32
|
+
<tfoot>
|
33
|
+
|
34
|
+
<tr>
|
35
|
+
<td colspan="6">
|
36
|
+
<span class="table_count">Displaying <%=data.size%> items</span>
|
37
|
+
</td>
|
38
|
+
</tr>
|
39
|
+
</tfoot>
|
40
|
+
</table>
|
41
|
+
</div>
|
data/views/review.erb
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
|
2
|
+
<div class="bordered optDialog">
|
3
|
+
<legend>Review Project Request</legend>
|
4
|
+
|
5
|
+
<%=erb :show, :locals => {:data=>data, :readonly=>true} %>
|
6
|
+
|
7
|
+
<div class="optAction" id="optAction">
|
8
|
+
<button id="optAccept" type="button" class="btn btn-success toRight"
|
9
|
+
data-loading-text="Loading ...">
|
10
|
+
Accept
|
11
|
+
</button>
|
12
|
+
<button id="optReject" type="button" class="btn btn-warning toRight"
|
13
|
+
data-loading-text="Loading ...">
|
14
|
+
Reject
|
15
|
+
</button>
|
16
|
+
<img class="loadingIcon toRight" id="optActionLoadingIcon" src="/images/loading.gif" alt="" />
|
17
|
+
<button id="optBack" type="button" class="btn toRight">Back</button>
|
18
|
+
<div class="clear"></div>
|
19
|
+
</div>
|
20
|
+
|
21
|
+
</div>
|
22
|
+
|
23
|
+
<div id="rejectCommentDialog" class="bordered rejectCommentDialog modal hide" tabindex="-1" role="dialog" aria-labelledby="Rejection Comment" aria-hidden="true">
|
24
|
+
<legend>Comment</legend>
|
25
|
+
|
26
|
+
<textarea name="rejectCommentText" placeholder="Put your comment for rejection here ..."></textarea>
|
27
|
+
|
28
|
+
<div class="rejectCommentAction">
|
29
|
+
<button id="rejectCommentConfirm" type="button" class="btn btn-primary toRight">Confirm</button>
|
30
|
+
<button id="rejectCommentBack" type="button" class="btn toRight">Back</button>
|
31
|
+
<div class="clear"></div>
|
32
|
+
</div>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<script type="text/javascript">
|
36
|
+
|
37
|
+
$(document).ready(init);
|
38
|
+
|
39
|
+
function init(){
|
40
|
+
initOptActions();
|
41
|
+
initRejectCommentDialogActions();
|
42
|
+
}
|
43
|
+
|
44
|
+
function initOptActions(){
|
45
|
+
$('#optBack').hide();
|
46
|
+
$('#optBack').click(function(){
|
47
|
+
window.location='/v1/applications';
|
48
|
+
});
|
49
|
+
|
50
|
+
$('#optAccept').click(function(){
|
51
|
+
$.noty.closeAll();
|
52
|
+
handleActionClick('accept', null);
|
53
|
+
});
|
54
|
+
$('#optReject').click(function(){
|
55
|
+
$.noty.closeAll();
|
56
|
+
$('#rejectCommentDialog').modal();
|
57
|
+
});
|
58
|
+
}
|
59
|
+
|
60
|
+
function initRejectCommentDialogActions(){
|
61
|
+
|
62
|
+
$('#rejectCommentBack').click(function(){
|
63
|
+
$('#rejectCommentDialog').modal('hide');
|
64
|
+
});
|
65
|
+
|
66
|
+
$('#rejectCommentConfirm').click(function(){
|
67
|
+
$('#rejectCommentDialog').modal('hide');
|
68
|
+
|
69
|
+
var data={
|
70
|
+
comments: $('textarea[name=rejectCommentText]').val()
|
71
|
+
};
|
72
|
+
data=$.toJSON( data );
|
73
|
+
|
74
|
+
handleActionClick('reject', data);
|
75
|
+
|
76
|
+
});
|
77
|
+
|
78
|
+
}
|
79
|
+
|
80
|
+
function handleActionClick(which, dataToSend){
|
81
|
+
actionBtnToLoading(which);
|
82
|
+
var url='/v1/applications/'+'<%=data[:id]%>'+'/'+((which=="accept")?"approve":"refuse");
|
83
|
+
$.post(url, dataToSend, 'json').done(function(data){
|
84
|
+
data = $.evalJSON(data);
|
85
|
+
if(data.status&&data.status=='error'){
|
86
|
+
//server returned error
|
87
|
+
noty({text: 'Failed to Submit Your Decision: '+(data.message?data.message:'Unknown Error'), type:'error'});
|
88
|
+
actionBtnToReady();
|
89
|
+
}else{
|
90
|
+
noty({text: 'Successfully Submitted Your Decision!', type:'success'});
|
91
|
+
actionBtnToComplete(which);
|
92
|
+
}
|
93
|
+
}).fail(function(){
|
94
|
+
noty({text: 'Failed to Submit Your Decision: Connection Error. You May Retry Later.', type:'error'});
|
95
|
+
actionBtnToReady();
|
96
|
+
});
|
97
|
+
|
98
|
+
}
|
99
|
+
|
100
|
+
function actionBtnToLoading(which){
|
101
|
+
if(which=="accept"){
|
102
|
+
$('#optAccept').button("loading");
|
103
|
+
}else if(which=="reject"){
|
104
|
+
$('#optReject').button("loading");
|
105
|
+
}else{
|
106
|
+
throw "This statement should never be reached!"
|
107
|
+
}
|
108
|
+
|
109
|
+
$('#optAccept').attr('disabled', 'true');
|
110
|
+
$('#optReject').attr('disabled', 'true');
|
111
|
+
|
112
|
+
$('#optActionLoadingIcon').show();
|
113
|
+
}
|
114
|
+
|
115
|
+
function actionBtnToReady(){
|
116
|
+
$('#optAccept').button('reset');
|
117
|
+
$('#optReject').button('reset');
|
118
|
+
|
119
|
+
$('#optReject').removeAttr('disabled');
|
120
|
+
$('#optAccept').removeAttr('disabled');
|
121
|
+
|
122
|
+
$('#optActionLoadingIcon').hide();
|
123
|
+
}
|
124
|
+
|
125
|
+
function actionBtnToComplete(which){
|
126
|
+
$('#optAccept').attr('disabled', 'true');
|
127
|
+
$('#optReject').attr('disabled', 'true');
|
128
|
+
$('#optActionLoadingIcon').hide();
|
129
|
+
|
130
|
+
if(which=="accept"){
|
131
|
+
$('#optAccept').text("Completed");
|
132
|
+
}else if(which=="reject"){
|
133
|
+
$('#optReject').text("Complete");
|
134
|
+
}else{
|
135
|
+
throw "This statement should never be reached!"
|
136
|
+
}
|
137
|
+
|
138
|
+
$('#optBack').show();
|
139
|
+
}
|
140
|
+
|
141
|
+
</script>
|