wakame-vdc-webui 10.12.0 → 11.06.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (152) hide show
  1. data/INSTALL-API.txt +14 -0
  2. data/Rakefile +5 -1
  3. data/app/api/config/environment.rb +9 -0
  4. data/app/controllers/accounts_controller.rb +39 -1
  5. data/app/controllers/application_controller.rb +73 -1
  6. data/app/controllers/instance_specs_controller.rb +11 -0
  7. data/app/controllers/instances_controller.rb +7 -3
  8. data/app/controllers/{images_controller.rb → machine_images_controller.rb} +2 -3
  9. data/app/controllers/sessions_controller.rb +6 -3
  10. data/app/controllers/snapshots_controller.rb +17 -6
  11. data/app/controllers/volumes_controller.rb +6 -2
  12. data/app/helpers/application_helper.rb +9 -5
  13. data/app/helpers/machine_images_helper.rb +2 -0
  14. data/app/models/account.rb +22 -4
  15. data/app/models/base_new.rb +11 -2
  16. data/app/models/dcmgr_resource/base.rb +13 -0
  17. data/app/models/dcmgr_resource/instance_spec.rb +7 -0
  18. data/app/models/dcmgr_resource/volume_snapshot.rb +6 -0
  19. data/app/models/information.rb +1 -1
  20. data/app/models/oauth_consumer.rb +15 -0
  21. data/app/models/oauth_token.rb +10 -0
  22. data/app/models/user.rb +34 -1
  23. data/app/views/accounts/index.html.erb +42 -67
  24. data/app/views/accounts/password.html.erb +35 -0
  25. data/app/views/dialog/attach_volume.html.erb +2 -2
  26. data/app/views/dialog/create_and_edit_security_group.html.erb +61 -28
  27. data/app/views/dialog/create_snapshot.html.erb +11 -4
  28. data/app/views/dialog/create_ssh_keypair.html.erb +2 -2
  29. data/app/views/dialog/create_volume.html.erb +3 -4
  30. data/app/views/dialog/create_volume_from_snapshot.html.erb +1 -1
  31. data/app/views/dialog/delete_security_group.html.erb +1 -1
  32. data/app/views/dialog/delete_snapshot.html.erb +1 -1
  33. data/app/views/dialog/delete_ssh_keypair.html.erb +1 -1
  34. data/app/views/dialog/delete_volume.html.erb +1 -1
  35. data/app/views/dialog/detach_volume.html.erb +1 -1
  36. data/app/views/dialog/launch_instance.html.erb +10 -14
  37. data/app/views/dialog/reboot_instances.html.erb +1 -1
  38. data/app/views/dialog/terminate_instances.html.erb +1 -1
  39. data/app/views/home/index.html.erb +11 -11
  40. data/app/views/host_pools/index.html.erb +87 -92
  41. data/app/views/instances/index.html.erb +50 -52
  42. data/app/views/keypairs/index.html.erb +16 -16
  43. data/app/views/layouts/_header.html.erb +6 -6
  44. data/app/views/layouts/_informationarea.html.erb +5 -5
  45. data/app/views/layouts/_login_header.erb +1 -1
  46. data/app/views/layouts/_sidemenu.html.erb +30 -28
  47. data/app/views/layouts/application.html.erb +19 -3
  48. data/app/views/layouts/login.html.erb +4 -4
  49. data/app/views/{images → machine_images}/index.html.erb +20 -39
  50. data/app/views/security_groups/index.html.erb +20 -23
  51. data/app/views/sessions/new.html.erb +10 -5
  52. data/app/views/snapshots/index.html.erb +28 -26
  53. data/app/views/storage_pools/index.html.erb +17 -22
  54. data/app/views/volumes/index.html.erb +32 -34
  55. data/config/application-cli.rb +33 -0
  56. data/config/{application-api.rb → cli_token.rb} +0 -0
  57. data/config/environment-cli.rb +4 -0
  58. data/config/environments/development.rb +19 -0
  59. data/config/initializers/dcmgr_gui.rb +8 -3
  60. data/config/initializers/sequel.rb +4 -0
  61. data/config/initializers/site.rb +8 -0
  62. data/config/locales/en.yml +307 -1
  63. data/config/locales/ja-JP.yml +4 -0
  64. data/config/locales/ja.yml +309 -0
  65. data/config/routes.rb +16 -9
  66. data/lib/cli/account.rb +264 -0
  67. data/lib/cli/base.rb +74 -0
  68. data/lib/cli/errors.rb +59 -0
  69. data/lib/cli/user.rb +226 -0
  70. data/lib/tasks/dcmgr_api.rake +65 -12
  71. data/lib/tasks/dcmgr_gui.rake +96 -4
  72. data/lib/tasks/dcmgr_oauth.rake +39 -0
  73. data/public/i18n/Messages.properties +0 -0
  74. data/public/images/Chevron.gif +0 -0
  75. data/public/images/ChevronOverlay.png +0 -0
  76. data/public/images/IconHome.gif +0 -0
  77. data/public/images/bg-box-body.gif +0 -0
  78. data/public/images/bg-box-body.png +0 -0
  79. data/public/images/bg-box-bottom.gif +0 -0
  80. data/public/images/bg-box-bottom.png +0 -0
  81. data/public/images/bg-box-top.gif +0 -0
  82. data/public/images/bg-box-top.png +0 -0
  83. data/public/images/cluetip/arrowdown.gif +0 -0
  84. data/public/images/cluetip/arrowleft.gif +0 -0
  85. data/public/images/cluetip/arrowright.gif +0 -0
  86. data/public/images/cluetip/arrowup.gif +0 -0
  87. data/public/images/cluetip/bl.gif +0 -0
  88. data/public/images/cluetip/bl.png +0 -0
  89. data/public/images/cluetip/br.gif +0 -0
  90. data/public/images/cluetip/br.png +0 -0
  91. data/public/images/cluetip/darrowdown.gif +0 -0
  92. data/public/images/cluetip/darrowleft.gif +0 -0
  93. data/public/images/cluetip/darrowright.gif +0 -0
  94. data/public/images/cluetip/darrowup.gif +0 -0
  95. data/public/images/cluetip/itunes.png +0 -0
  96. data/public/images/cluetip/rarrowdown.gif +0 -0
  97. data/public/images/cluetip/rarrowleft.gif +0 -0
  98. data/public/images/cluetip/rarrowright.gif +0 -0
  99. data/public/images/cluetip/rarrowup.gif +0 -0
  100. data/public/images/cluetip/tl.gif +0 -0
  101. data/public/images/cluetip/tl.png +0 -0
  102. data/public/images/cluetip/tr.gif +0 -0
  103. data/public/images/cluetip/tr.png +0 -0
  104. data/public/images/cluetip/wait.gif +0 -0
  105. data/public/images/dialog-error.png +0 -0
  106. data/public/images/dialog-help.png +0 -0
  107. data/public/images/dialog-information.png +0 -0
  108. data/public/images/dialog-warning.png +0 -0
  109. data/public/images/ui-bg_flat_55_fcf0ba_40x100.png +0 -0
  110. data/public/images/ui-bg_glass_10_136d76_1x400.png +0 -0
  111. data/public/images/ui-bg_glass_10_458845_1x400.png +0 -0
  112. data/public/images/ui-bg_highlight-hard_100_f5f3e5_1x100.png +0 -0
  113. data/public/images/ui-bg_highlight-hard_100_fafaf4_1x100.png +0 -0
  114. data/public/images/ui-bg_highlight-soft_50_136d76_1x100.png +0 -0
  115. data/public/images/ui-bg_inset-soft_15_386b3d_1x100.png +0 -0
  116. data/public/images/ui-icons_4c9052_256x240.png +0 -0
  117. data/public/images/ui-icons_847e71_256x240.png +0 -0
  118. data/public/javascripts/dcmgr_gui/account_panel.js +6 -0
  119. data/public/javascripts/dcmgr_gui/application.js +78 -5
  120. data/public/javascripts/dcmgr_gui/core.js +409 -102
  121. data/public/javascripts/dcmgr_gui/dashboard_panel.js +12 -3
  122. data/public/javascripts/dcmgr_gui/host_pool_panel.js +1 -1
  123. data/public/javascripts/dcmgr_gui/image_panel.js +119 -65
  124. data/public/javascripts/dcmgr_gui/instance_panel.js +86 -44
  125. data/public/javascripts/dcmgr_gui/security_group_panel.js +135 -77
  126. data/public/javascripts/dcmgr_gui/snapshot_panel.js +119 -61
  127. data/public/javascripts/dcmgr_gui/sshkeypair_panel.js +71 -47
  128. data/public/javascripts/dcmgr_gui/storage_pool_panel.js +10 -10
  129. data/public/javascripts/dcmgr_gui/volume_panel.js +311 -155
  130. data/public/javascripts/jquery.cluetip.min.js +33 -0
  131. data/public/javascripts/jquery.easing.1.3.js +205 -0
  132. data/public/javascripts/jquery.hoverIntent.js +114 -0
  133. data/public/javascripts/jquery.i18n.properties-min.js +7 -0
  134. data/public/javascripts/jquery.jBreadCrumb.1.1.js +240 -0
  135. data/public/javascripts/sexyalertbox.v1.2.jquery.js +414 -0
  136. data/public/javascripts/ui.selectmenu.js +541 -0
  137. data/public/stylesheets/BreadCrumb.css +109 -0
  138. data/public/stylesheets/common.css +146 -86
  139. data/public/stylesheets/dialog.css +7 -7
  140. data/public/stylesheets/jquery-ui-1.8.4.custom.css +41 -40
  141. data/public/stylesheets/jquery.cluetip.css +179 -0
  142. data/public/stylesheets/sexyalertbox.css +67 -0
  143. data/public/stylesheets/ui.selectmenu.css +24 -0
  144. data/test/functional/{images_controller_test.rb → machine_images_controller_test.rb} +1 -1
  145. data/test/unit/helpers/machine_images_helper_test.rb +4 -0
  146. metadata +350 -221
  147. data/README +0 -256
  148. data/app/api/auth_server.rb +0 -28
  149. data/app/helpers/images_helper.rb +0 -2
  150. data/app/views/information/index.html.erb +0 -25
  151. data/app/views/layouts/_service_health.erb +0 -27
  152. data/test/unit/helpers/images_helper_test.rb +0 -4
@@ -0,0 +1,39 @@
1
+ namespace :oauth do
2
+ desc 'Create oauth consumer'
3
+ task :create_consumer,[:vdc_account_uuid] => :environment do |t,args|
4
+
5
+ split_uuid = args[:vdc_account_uuid].split('-')
6
+
7
+ if args[:vdc_account_uuid].nil? or split_uuid[0] != 'a'
8
+ puts 'Please set the wakame-vdc account uuid.'
9
+ exit(0)
10
+ end
11
+
12
+ account_uuid = split_uuid[1]
13
+ account = Account.find(:uuid => account_uuid)
14
+
15
+ if account.nil?
16
+ puts "Account not found."
17
+ exit(0)
18
+ end
19
+
20
+ oauth_consumer = OauthConsumer.find(:account_id => account.id)
21
+
22
+ if oauth_consumer.nil?
23
+ oauth_token = OauthToken.new
24
+ oauth_token.generate_keys
25
+ oauth_consumer = OauthConsumer.create(
26
+ :key => oauth_token.token,
27
+ :secret => oauth_token.secret,
28
+ :account_id => account.id
29
+ )
30
+ end
31
+ puts "consumer_key=#{oauth_consumer.key}"
32
+ puts "secret_key=#{oauth_consumer.secret}"
33
+ end
34
+
35
+ desc 'Create table'
36
+ task :create_table => :environment do |t,args|
37
+ OauthConsumer.create_table!
38
+ end
39
+ end
File without changes
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,6 @@
1
+ DcmgrGUI.prototype.accountPanel = function(){
2
+ var last_login_at = $('#last_login_at').html();
3
+ last_login_at = DcmgrGUI.date.parseISO8601(last_login_at);
4
+ last_login_at = DcmgrGUI.date.setTimezoneOffset(last_login_at, dcmgrGUI.getConfig('time_zone_utc_offset'));
5
+ $('#last_login_at').html(DcmgrGUI.date.getI18n(last_login_at));
6
+ }
@@ -4,6 +4,11 @@
4
4
  //<![CDATA[
5
5
  jQuery(function($){
6
6
 
7
+ //global
8
+ dcmgrGUI = new DcmgrGUI;
9
+ dcmgrGUI.initialize();
10
+ dcmgrGUI.notification = new DcmgrGUI.Notification;
11
+
7
12
  //サイドメニュー開閉関数
8
13
  var regionpos = 0;
9
14
  $('#regionselect').click(function () {
@@ -83,9 +88,77 @@ jQuery(function($){
83
88
  $(this).parent('form').submit();
84
89
  return false;
85
90
  });
86
-
87
- //global
88
- dcmgrGUI = new DcmgrGUI;
89
- dcmgrGUI.initialize();
91
+
92
+ $('#select_language_locale').bind('change', function(){
93
+ $('#select_language')[0].submit();
94
+ })
95
+
96
+ $(document).ajaxError(function(e, xhr, settings, exception) {
97
+ var message = '';
98
+ if(xhr.status == 0){
99
+ message = 'Please Check Your Network.';
100
+ }else if(e == 'parsererror'){
101
+ message = 'Parsing JSON Request failed.';
102
+ }else if(e == 'timeout'){
103
+ message = 'Request Time out.';
104
+ }else {
105
+ var is_dcmgr = function() {
106
+ if(xhr.getResponseHeader("X-Vdc-Request-Id")) {
107
+ return true;
108
+ } else {
109
+ return false;
110
+ }
111
+ }
112
+
113
+ if(is_dcmgr()) {
114
+ try {
115
+ var r = $.parseJSON(xhr.responseText);
116
+ var code = r.code;
117
+ var body = r.message.replace('Dcmgr::Endpoints::', '');
118
+ } catch(e) {
119
+ var code = xhr.status;
120
+ var body = 'Request faild.'
121
+ dcmgrGUI.logger.push(e.type, xhr);
122
+ }
123
+ } else{
124
+ var code = xhr.status;
125
+ var body = xhr.statusText;
126
+ }
127
+
128
+ message = "<div id='error_box'>"
129
+ + "<div class='error_code'>" + $.i18n.prop('code_error_box') + ': ' + code + '</div>'
130
+ + "<div class='error_body'>" + body + '</div>'
131
+ + '</div>';
132
+ }
133
+
134
+ dcmgrGUI.logger.push(e.type, xhr);
135
+
136
+ if(dcmgrGUI.getConfig('error_popup')) {
137
+ Sexy.error(message);
138
+ if(dcmgrGUI.getConfig('error_popup_once')) {
139
+ dcmgrGUI.setConfig('error_popup', false);
140
+ }
141
+ }
142
+ });
143
+
144
+ //Region selectmenu
145
+ $('#regionmenu').selectmenu({
146
+ width: 208,
147
+ menuWidth: 208,
148
+ style:'dropdown',
149
+ icons: [
150
+ {find: '.script', icon: 'ui-icon-script'},
151
+ {find: '.image', icon: 'ui-icon-image'}
152
+ ],
153
+ select: function(event){
154
+ }
155
+ });
156
+
157
+ $('#regionmenu-button').css('font-size', '13px')
158
+ .css('height', '25px');
159
+
160
+ $('a[id^="ui-selectmenu-item"]').css('font-size', '13px')
161
+ .css('height', '17px')
162
+
90
163
  });
91
- //]]>
164
+ //]]>
@@ -23,6 +23,35 @@ DcmgrGUI.Class = (function() {
23
23
  }
24
24
  })();
25
25
 
26
+ DcmgrGUI.Request = DcmgrGUI.Class.create({
27
+ initialize: function(){
28
+
29
+ },
30
+ get: function(params){
31
+ params['type'] = 'GET';
32
+ return this._request(params);
33
+ },
34
+ put: function(params){
35
+ params['type'] = 'PUT';
36
+ return this._request(params)
37
+ },
38
+ post: function(params){
39
+ params['type'] = 'POST';
40
+ return this._request(params);
41
+ },
42
+ del: function(params){
43
+ params['type'] = 'DELETE';
44
+ return this._request(params);
45
+ },
46
+
47
+ _request: function(params){
48
+ params['async'] = params['async'] || true;
49
+ params['dataType'] = 'json';
50
+ params['cache'] = false;
51
+ return $.ajax(params);
52
+ }
53
+ });
54
+
26
55
  DcmgrGUI.Filter = DcmgrGUI.Class.create({
27
56
  initialize: function(){
28
57
  this.filters = [];
@@ -51,6 +80,67 @@ DcmgrGUI.Converter.fromMBtoGB = function(data){
51
80
  return Math.ceil(data/1024) + 'GB';
52
81
  };
53
82
 
83
+ DcmgrGUI.Converter.unit = function(data, unit_type){
84
+ var unit = '';
85
+ switch(unit_type) {
86
+ case 'megabyte':
87
+ unit = 'MB'
88
+ break;
89
+
90
+ case 'gigabyte':
91
+ unit = 'GB'
92
+ break;
93
+ }
94
+ return data + unit;
95
+ };
96
+
97
+ DcmgrGUI.date = {};
98
+ DcmgrGUI.date.parseISO8601 = function (str) {
99
+ /*
100
+ Reference: http://anentropic.wordpress.com/2009/06/25/javascript-iso8601-parser-and-pretty-dates/
101
+ */
102
+
103
+ // we assume str is a UTC date ending in 'Z'
104
+ var parts = str.split('T'),
105
+ dateParts = parts[0].split('-'),
106
+ timeParts = parts[1].split('Z'),
107
+ timeSubParts = timeParts[0].split(':'),
108
+ timeSecParts = timeSubParts[2].split('.'),
109
+ timeHours = Number(timeSubParts[0]),
110
+ _date = new Date;
111
+
112
+ _date.setUTCFullYear(Number(dateParts[0]));
113
+ _date.setUTCMonth(Number(dateParts[1]));
114
+ _date.setUTCDate(Number(dateParts[2]));
115
+ _date.setUTCHours(Number(timeHours));
116
+ _date.setUTCMinutes(Number(timeSubParts[1]));
117
+ _date.setUTCSeconds(Number(timeSecParts[0]));
118
+ if (timeSecParts[1]) _date.setUTCMilliseconds(Number(timeSecParts[1]));
119
+
120
+ // by using setUTC methods the date has already been converted to local time(?)
121
+ return _date;
122
+ };
123
+
124
+ DcmgrGUI.date.setTimezoneOffset = function(date_str, utc_offset){
125
+ date_str.setUTCSeconds(utc_offset);
126
+ return date_str;
127
+ }
128
+
129
+ DcmgrGUI.date.getI18n = function(date_str){
130
+
131
+ var convert = function(value) {
132
+ return ("0" + value).slice(-2);
133
+ }
134
+
135
+ return $.i18n.prop('display_date', [date_str.getUTCFullYear(),
136
+ convert(date_str.getUTCMonth()),
137
+ convert(date_str.getUTCDate()),
138
+ convert(date_str.getUTCHours()),
139
+ convert(date_str.getUTCMinutes()),
140
+ convert(date_str.getUTCSeconds())
141
+ ]);
142
+ };
143
+
54
144
  DcmgrGUI.Pagenate = DcmgrGUI.Class.create({
55
145
  initialize: function(params) {
56
146
  var self = this;
@@ -66,8 +156,8 @@ DcmgrGUI.Pagenate = DcmgrGUI.Class.create({
66
156
  disabled : true,
67
157
  text : false
68
158
  });
69
-
70
159
  this.next = DcmgrGUI.Util.createUIButton(this.element.find('.next'),{
160
+ disabled : true,
71
161
  text : false
72
162
  });
73
163
 
@@ -78,14 +168,7 @@ DcmgrGUI.Pagenate = DcmgrGUI.Class.create({
78
168
  };
79
169
 
80
170
  self.updatePage.call(this,event);
81
-
82
- if (self.current_page === 1) {
83
- self.prev.button("option", "disabled", true);
84
- self.next.button("option", "disabled", false);
85
- } else {
86
- self.prev.button("option", "disabled", false);
87
- self.next.button("option", "disabled", false);
88
- }
171
+ self.changeArrowButton();
89
172
  });
90
173
 
91
174
  this.next.bind("click",{obj: this},function(event){
@@ -95,35 +178,83 @@ DcmgrGUI.Pagenate = DcmgrGUI.Class.create({
95
178
  };
96
179
 
97
180
  self.updatePage.call(this,event);
98
-
99
- if (self.current_page === self.page_count) {
100
- self.prev.button("option", "disabled", false);
101
- self.next.button("option", "disabled", true);
102
- } else {
103
- self.prev.button("option", "disabled", false);
104
- self.next.button("option", "disabled", false);
105
- }
181
+ self.changeArrowButton();
106
182
  });
107
183
 
108
184
  this.renderPagenate();
185
+
186
+ //create topics
187
+ dcmgrGUI.notification.create_topic('change_pagenate');
188
+ },
189
+ changeArrowButton: function() {
190
+ if (this.current_page === 1){
191
+ this.prev.button("option", "disabled", true);
192
+ this.next.button("option", "disabled", false);
193
+ }else{
194
+ if (this.current_page === this.page_count) {
195
+ this.prev.button("option", "disabled", false);
196
+ this.next.button("option", "disabled", true);
197
+ } else {
198
+ this.prev.button("option", "disabled", false);
199
+ this.next.button("option", "disabled", false);
200
+ }
201
+ }
109
202
  },
110
203
  getPageCount: function(total,row){
111
204
  return Math.ceil(total / row)
112
205
  },
113
206
  changeTotal: function(total){
114
207
  this.total = total;
208
+
209
+ if(this.total > (this.current_page * this.row)) {
210
+ this.next.button("option", "disabled", false);
211
+ }else{
212
+ this.next.button("option", "disabled", true);
213
+ }
214
+
115
215
  this.page_count = this.getPageCount(this.total,this.row)
116
216
  this.renderPagenate();
117
217
  },
218
+ changePage: function() {
219
+ var self = this;
220
+ var current_page = $('#viewPagenate').find("#current_page");
221
+ if(current_page.length != 0) {
222
+ current_page.bind("focus", function(){
223
+ this.select();
224
+ });
225
+
226
+ current_page.bind("keypress", function(event){
227
+ if(event.keyCode == 13) {
228
+ var page = parseInt(current_page.val());
229
+ self.current_page = page;
230
+ self.page = page;
231
+ event.data = {'obj': self};
232
+ self.updatePage.call(this, event);
233
+ self.changeArrowButton();
234
+ }
235
+ });
236
+ }
237
+ },
118
238
  renderPagenate: function(){
119
239
  this.start = this.getStartCount();
120
240
  this.offset = this.getOffsetCount();
121
- var html = this.start + ' to ' + this.offset + ' of ' + this.total;
122
- $("#viewPagenate").html(html+' '+this.view);
241
+ if (this.start !== 0 && this.offset !==0 ) {
242
+ var current_page = '<input type="text" id="current_page" style="width:20px;height:13px" value="'+ this.current_page +'">';
243
+ var page = $.i18n.prop('page_pagenate', [this.page_count])
244
+ var total = $.i18n.prop('total_pagenate', [this.total])
245
+ var html = current_page + ' / ' + page + ' : ' + total;
246
+ html += ' ' + this.view
247
+ } else{
248
+ var html = '';
249
+ }
250
+ $("#viewPagenate").html(html);
251
+ this.changePage()
123
252
  },
124
253
  updatePage: function(event){
125
254
  var self = event.data.obj;
126
- var name = $(this).attr('class').split(' ')[0];
255
+ if($(this).attr('class')) {
256
+ var name = $(this).attr('class').split(' ')[0];
257
+ }
127
258
 
128
259
  if(self.current_page >= 1 && self.current_page < self.page_count) {
129
260
  if(name === 'next'){
@@ -140,6 +271,7 @@ DcmgrGUI.Pagenate = DcmgrGUI.Class.create({
140
271
  }
141
272
  self.renderPagenate();
142
273
  self.element.trigger('dcmgrGUI.updatePagenate');
274
+ dcmgrGUI.notification.publish('change_pagenate');
143
275
  },
144
276
  getOffsetCount: function(){
145
277
  var count = (this.current_page * this.row);
@@ -163,7 +295,7 @@ DcmgrGUI.Pagenate = DcmgrGUI.Class.create({
163
295
  DcmgrGUI.Dialog = DcmgrGUI.Class.create({
164
296
  initialize: function(params) {
165
297
  this.target = $(params['target']);
166
- this.element = $('<div></div>')
298
+ this.element = $('<div></div>');
167
299
  this.path_prefix = '/dialog';
168
300
  this.path = this.path_prefix + params['path'];
169
301
  this.width = params['width'];
@@ -171,6 +303,8 @@ DcmgrGUI.Dialog = DcmgrGUI.Class.create({
171
303
  this.title = params['title'];
172
304
  this.button = params['button'];
173
305
  this.callback = params['callback'] ||null;
306
+
307
+ dcmgrGUI.notification.create_topic('close_dialog');
174
308
  },
175
309
  open: function(params){
176
310
  //multi select action
@@ -185,35 +319,54 @@ DcmgrGUI.Dialog = DcmgrGUI.Class.create({
185
319
  }
186
320
  this.content.dialog('open');
187
321
  },
188
- disabledButton: function(buttonName,disabled){
189
- var widget = this.content
190
- .dialog('widget')
191
- .find(".ui-button-text:contains('"+ buttonName +"')")
192
- .parent();
322
+ getWidgetButton: function(num) {
323
+ var widget = $(this.content.dialog('widget')
324
+ .find(".ui-button-text")[num])
325
+ return widget;
326
+ },
327
+ disabledButton: function(num, disabled){
328
+ var widget = this.getWidgetButton(num);
193
329
  if( widget ) {
194
- widget.button("option", "disabled", disabled);
195
- }
330
+ widget.parent().button("option", "disabled", disabled);
331
+ }
196
332
  },
197
333
  close: function(){
198
334
  this.content.dialog('close');
199
335
  },
336
+ enableDialogButton: function(){
337
+ $(this.target).button({ disabled: false });
338
+ },
339
+ disableDialogButton: function(){
340
+ $(this.target).button({ disabled: true });
341
+ },
342
+ is_disabled: function(){
343
+ return $(this.target).button("option", "disabled");
344
+ },
200
345
  create: function(params){
346
+ //initialize
347
+ this.element = $('<div></div>');
348
+
201
349
  this.content = this.element
202
- .load(this.path,params,this.callback)
203
- .dialog({
204
- title: this.title,
205
- disable: false,
206
- autoOpen: false,
207
- bgiframe: true,
208
- width: this.width,
209
- height: this.height,
210
- modal: true,
211
- resizable: true,
212
- closeOnEscape: true,
213
- closeText: 'hide',
214
- draggable:false,
215
- buttons: this.button
216
- });
350
+ .load(this.path + '?_=' + (new Date()).getTime(),
351
+ params,
352
+ this.callback)
353
+ .dialog({
354
+ title: this.title,
355
+ disable: false,
356
+ autoOpen: false,
357
+ bgiframe: true,
358
+ width: this.width,
359
+ height: this.height,
360
+ modal: true,
361
+ resizable: true,
362
+ closeOnEscape: true,
363
+ closeText: 'hide',
364
+ draggable:false,
365
+ buttons: this.button,
366
+ close: function(event, ui) {
367
+ dcmgrGUI.notification.publish('close_dialog');
368
+ }
369
+ });
217
370
  }
218
371
  });
219
372
 
@@ -224,48 +377,28 @@ DcmgrGUI.ContentBase = DcmgrGUI.Class.create({
224
377
  } else {
225
378
  this.element = $('<div></div>');
226
379
  }
227
-
228
380
  this.template = params.template_id;
229
- this.events = this.events||[];
230
- //prototype.register_event function add to call before initialize function
231
- this.bind_events();
232
381
  this.filter = new DcmgrGUI.Filter();
233
382
  },
234
- update:function(request,async){
235
- this.request = request;
236
- this.async = async;
383
+ update:function(params,async){
237
384
  var self = this;
238
385
 
239
- $("#list_load_mask").mask("Loading...");
386
+ $("#list_load_mask").mask($.i18n.prop('loading_parts'));
240
387
  self.element.trigger('dcmgrGUI.beforeUpdate');
241
- $.ajax({
242
- async: async||true,
243
- url: request.url,
244
- dataType: "json",
245
- data: request.data,
246
- success: function(json,status,xhr){
247
- self.filter.execute(json);
248
- self.element.trigger('dcmgrGUI.contentChange',[{"data":json,"self":self}]);
249
- self.element.trigger('dcmgrGUI.afterUpdate',[{"data":json,"self":self}]);
250
- },
251
- complete: function(xhr, status) {
252
- $("#list_load_mask").unmask();
253
- },
254
- error: function(xhr, status, error){
255
- alert('Dcmgr connection '+status);
256
- }
257
- });
258
- },
259
- register_event:function(name,handler){
260
- this.events = this.events||[]
261
- this.events.push({
262
- "name":name,
263
- "handler":handler
264
- })
265
- },bind_events:function(){
266
- for(var i in this.events){
267
- this.element.bind(this.events[i].name,this.events[i].handler);
268
- }
388
+
389
+ var request = new DcmgrGUI.Request;
390
+ request.get({
391
+ url: params.url,
392
+ data: params.data,
393
+ success: function(json,status,xhr){
394
+ self.filter.execute(json);
395
+ self.element.trigger('dcmgrGUI.contentChange',[{"data":json,"self":self}]);
396
+ self.element.trigger('dcmgrGUI.afterUpdate',[{"data":json,"self":self}]);
397
+ },
398
+ complete: function(xhr, status) {
399
+ $("#list_load_mask").unmask();
400
+ }
401
+ });
269
402
  }
270
403
  });
271
404
 
@@ -322,6 +455,77 @@ DcmgrGUI.Util.createUIButton = function(element,options){
322
455
  });
323
456
  }
324
457
 
458
+ DcmgrGUI.Event = DcmgrGUI.Class.create({
459
+
460
+ initialize: function(){
461
+ this.events = {}
462
+ },
463
+ attach: function(event_name, func){
464
+ if(!this.events[event_name] && typeof func === "function") {
465
+ this.events[event_name] = func;
466
+ }
467
+ },
468
+ detach: function(event_name){
469
+ if(this.events[event_name]) {
470
+ delete this.events[event_name];
471
+ }
472
+ },
473
+ fire: function(event_name){
474
+ if(this.events[event_name]) {
475
+ this.events[event_name]();
476
+ }
477
+ }
478
+ });
479
+
480
+ DcmgrGUI.Notification = DcmgrGUI.Class.create({
481
+
482
+ initialize: function() {
483
+ this.topics = {};
484
+ this.evaluation_list = {};
485
+ this.subscription_id = 1;
486
+ },
487
+ create_topic: function(topic_id) {
488
+ if(!this.topics[topic_id]) {
489
+ this.topics[topic_id] = [];
490
+ }
491
+ },
492
+ subscribe: function(topic_id, target, method_name, options) {
493
+ if( this.topics[topic_id] ) {
494
+ this.topics[topic_id].push({'target': target,
495
+ 'method_name': method_name,
496
+ 'options': options,
497
+ 'subscription_id': this.subscription_id})
498
+ var subscription_id = this.subscription_id;
499
+ this.subscription_id += 1;
500
+ return subscription_id;
501
+ }
502
+ },
503
+ add_evaluation: function(subscription_id, logic) {
504
+ this.evaluation_list[subscription_id] = logic;
505
+ },
506
+ evaluate: function(subscription_id) {
507
+ if(jQuery.isFunction(this.evaluation_list[subscription_id])) {
508
+ return this.evaluation_list[subscription_id]();
509
+ } else{
510
+ return true;
511
+ }
512
+ },
513
+ publish: function(topic_id) {
514
+ if(this.topics[topic_id]) {
515
+ var size = this.topics[topic_id].length;
516
+ for (i=0; i < size; i++) {
517
+ var topic = this.topics[topic_id][i];
518
+ var target = topic['target'];
519
+ var method_name = topic['method_name'];
520
+ if(this.evaluate(topic['subscription_id'])) {
521
+ target[method_name](topic['options']);
522
+ }
523
+ }
524
+ }
525
+ }
526
+
527
+ });
528
+
325
529
  DcmgrGUI.List = DcmgrGUI.Class.create(DcmgrGUI.ContentBase, {
326
530
  initialize: function(params){
327
531
  DcmgrGUI.ContentBase.prototype.initialize(params);
@@ -329,7 +533,24 @@ DcmgrGUI.List = DcmgrGUI.Class.create(DcmgrGUI.ContentBase, {
329
533
  this.detail_template = {};
330
534
  this.maxrow = params.maxrow
331
535
  this.page = params.page
332
-
536
+ this.detail_filter = new DcmgrGUI.Filter();
537
+ this.detail_filter.add(function(data){
538
+
539
+ if(data.item.created_at) {
540
+ data.item.created_at = DcmgrGUI.date.parseISO8601(data.item.created_at);
541
+ data.item.created_at = DcmgrGUI.date.setTimezoneOffset(data.item.created_at, dcmgrGUI.getConfig('time_zone_utc_offset'));
542
+ data.item.created_at = DcmgrGUI.date.getI18n(data.item.created_at);
543
+ }
544
+
545
+ if(data.item.updated_at) {
546
+ data.item.updated_at = DcmgrGUI.date.parseISO8601(data.item.updated_at);
547
+ data.item.updated_at = DcmgrGUI.date.setTimezoneOffset(data.item.updated_at, dcmgrGUI.getConfig('time_zone_utc_offset'));
548
+ data.item.updated_at = DcmgrGUI.date.getI18n(data.item.updated_at);
549
+ }
550
+
551
+ return data;
552
+ });
553
+
333
554
  var self = this;
334
555
 
335
556
  this.element.bind('dcmgrGUI.afterUpdate',function(event){
@@ -365,12 +586,14 @@ DcmgrGUI.List = DcmgrGUI.Class.create(DcmgrGUI.ContentBase, {
365
586
  this.element.bind('dcmgrGUI.updateList',function(event,params){
366
587
  self.update(params.request,true)
367
588
  });
368
-
589
+ dcmgrGUI.notification.create_topic('checked_box');
590
+ dcmgrGUI.notification.create_topic('unchecked_box');
591
+ dcmgrGUI.notification.create_topic('checked_radio');
369
592
  },
370
593
  setDetailTemplate:function(template){
371
594
  this.detail_template = template;
372
595
  },
373
- getCheckedInstanceIds:function(checked_list){
596
+ getCheckedInstanceIds:function(){
374
597
  var ids = []
375
598
  for(var id in this.checked_list){
376
599
  ids.push(id);
@@ -419,6 +642,18 @@ DcmgrGUI.List = DcmgrGUI.Class.create(DcmgrGUI.ContentBase, {
419
642
  return null;
420
643
  }
421
644
  },
645
+ currentMultiChecked:function(){
646
+ var checked_list = this.element.find("[type='checkbox']:checked");
647
+ var ids = [];
648
+
649
+ $.each(checked_list, function(key, item){
650
+ ids.push($(item).val());
651
+ })
652
+
653
+ return {
654
+ 'ids':ids
655
+ }
656
+ },
422
657
  singleCheckList:function(params){
423
658
  var self = this;
424
659
  this.element.find("[type='radio']").each(function(key,value){
@@ -426,19 +661,22 @@ DcmgrGUI.List = DcmgrGUI.Class.create(DcmgrGUI.ContentBase, {
426
661
  var check_id = $(this).val();
427
662
 
428
663
  if($(this).is(':checked')){
664
+
665
+ dcmgrGUI.notification.publish('checked_radio');
666
+
429
667
  var c_detail = new DcmgrGUI.Detail({
430
668
  template_id:params.template_id
431
669
  });
432
-
670
+
433
671
  c_detail.element.bind('dcmgrGUI.contentChange',function(event,params){
434
672
  var data = { item:params.data }
435
-
436
673
  //initialize
437
674
  if(!params.data){
438
675
  data.item = self.getEmptyData();
439
676
  }
440
-
677
+
441
678
  if(data.item){
679
+ self.detail_filter.execute(data);
442
680
  $('#detail').html($( c_detail.template ).tmpl(data));
443
681
  }
444
682
  });
@@ -455,12 +693,15 @@ DcmgrGUI.List = DcmgrGUI.Class.create(DcmgrGUI.ContentBase, {
455
693
  },
456
694
  multiCheckList:function(params){
457
695
  var self = this;
458
- this.element.find("[type='checkbox']").each(function(key,value){
696
+ var checkboxies = this.element.find("[type='checkbox']");
697
+ checkboxies.each(function(key,value){
698
+
459
699
  $(this).click(function(){
460
700
  var check_id = $(this).val();
461
701
 
462
702
  if($(this).is(':checked')){
463
-
703
+ dcmgrGUI.notification.publish('checked_box');
704
+
464
705
  //step1:onclick checkbox and generate detail object
465
706
  self.checked_list[check_id] = {
466
707
  //+1 is to remove table header
@@ -473,7 +714,8 @@ DcmgrGUI.List = DcmgrGUI.Class.create(DcmgrGUI.ContentBase, {
473
714
  }
474
715
 
475
716
  //step2:bind event dcmgrGUI.contentChange
476
- self.checked_list[check_id].c_detail.element.bind('dcmgrGUI.contentChange',function(event,params){
717
+ var detail_element = self.checked_list[check_id].c_detail.element;
718
+ detail_element.bind('dcmgrGUI.contentChange',function(event,params){
477
719
  if(self.checked_list[check_id]){
478
720
 
479
721
  //step4:marge data in template
@@ -484,12 +726,10 @@ DcmgrGUI.List = DcmgrGUI.Class.create(DcmgrGUI.ContentBase, {
484
726
  data.item = self.checked_list[check_id].c_detail.getEmptyData();
485
727
  }
486
728
 
487
- if (self.detail_template.filter) {
488
- self.detail_template.filter.execute(data);
489
- };
490
729
  self.checked_list[check_id].c_detail.filter.execute(data);
491
730
 
492
731
  if(data.item){
732
+ self.detail_filter.execute(data);
493
733
  $( self.checked_list[check_id].c_detail.template )
494
734
  .tmpl(data)
495
735
  .appendTo( $('#detail') );
@@ -503,12 +743,12 @@ DcmgrGUI.List = DcmgrGUI.Class.create(DcmgrGUI.ContentBase, {
503
743
  },true);
504
744
 
505
745
  }else{
746
+ dcmgrGUI.notification.publish('unchecked_box');
506
747
  //remove detail
507
748
  if(self.checked_list[check_id]){
508
- $($('#detail').find('#'+check_id)).remove();
509
- delete self.checked_list[check_id]
510
- }
511
-
749
+ $($('#detail').find('#'+check_id)).remove();
750
+ delete self.checked_list[check_id]
751
+ }
512
752
  }
513
753
  });
514
754
  })
@@ -520,18 +760,19 @@ DcmgrGUI.Detail = DcmgrGUI.Class.create(DcmgrGUI.ContentBase, {
520
760
 
521
761
  DcmgrGUI.Refresh = DcmgrGUI.Class.create({
522
762
  initialize: function(){
523
- this.element = $('.refresh');
763
+ this.target = '.refresh'
764
+ this.element = $(this.target);
524
765
  var self = this;
525
766
  self.element.live('click',function(){
526
767
  self.element.trigger('dcmgrGUI.refresh');
527
768
  })
528
- },
769
+ }
529
770
  });
530
771
 
531
772
  DcmgrGUI.ItemSelector = DcmgrGUI.Class.create({
532
773
 
533
774
  initialize: function(params) {
534
-
775
+ this.element = $(params.target);
535
776
  this.left_select_id = params.left_select_id;
536
777
  this.right_select_id = params.right_select_id;
537
778
  this.data = params.data;
@@ -551,7 +792,7 @@ DcmgrGUI.ItemSelector = DcmgrGUI.Class.create({
551
792
  $(select_id).html('');
552
793
  for(var i = 0;i < selectionsSize ;i++) {
553
794
  if(selectionsArray[i] !== null ){
554
- $(select_id).append(selectionsArray[i]);
795
+ this.element.find(select_id).append(selectionsArray[i]);
555
796
  }
556
797
  }
557
798
  },
@@ -564,7 +805,7 @@ DcmgrGUI.ItemSelector = DcmgrGUI.Class.create({
564
805
  },
565
806
  leftToRight: function() {
566
807
  var self = this;
567
- $(this.left_select_id).find('option:selected').each(function(){
808
+ this.element.find(this.left_select_id).find('option:selected').each(function(){
568
809
  var index = $(this).attr('id');
569
810
  self.leftSelectionsArray[index] = null;
570
811
  self.rightSelectionsArray[index] = this;
@@ -575,7 +816,7 @@ DcmgrGUI.ItemSelector = DcmgrGUI.Class.create({
575
816
  },
576
817
  rightToLeft: function() {
577
818
  var self = this;
578
- $(this.right_select_id).find('option:selected').each(function(){
819
+ this.element.find(this.right_select_id).find('option:selected').each(function(){
579
820
  var index = $(this).attr('id');
580
821
  self.leftSelectionsArray[index] = this;
581
822
  self.rightSelectionsArray[index] = null;
@@ -583,11 +824,77 @@ DcmgrGUI.ItemSelector = DcmgrGUI.Class.create({
583
824
  });
584
825
 
585
826
  this.refreshOptions(this.left_select_id,this.leftSelectionsArray);
827
+ },
828
+ getRightSelectionCount: function(){
829
+ var count = 0;
830
+ $.each(this.rightSelectionsArray,function(key, value){
831
+ if(value != null) {
832
+ count++;
833
+ }
834
+ });
835
+ return count;
836
+ }
837
+
838
+ });
839
+
840
+ DcmgrGUI.ToolTip = DcmgrGUI.Class.create({
841
+ initialize: function(params) {
842
+ this.target = params.target;
843
+ this.element = $(params.element);
844
+ },
845
+ create: function(params){
846
+ this.content = this.element.find(this.target)
847
+ .cluetip(params);
848
+ },
849
+ close: function(){
850
+ this.content.trigger('hideCluetip');
851
+ }
852
+ });
853
+
854
+ DcmgrGUI.Logger = DcmgrGUI.Class.create({
855
+ initialize: function() {
856
+ this.stack = [];
857
+ },
858
+ push: function(type, item) {
859
+ this.stack.push({
860
+ 'type': type,
861
+ 'item': item
862
+ });
863
+ },
864
+ getLog: function(limit, type) {
865
+ var size = this.stack.length;
866
+ var results = [];
867
+ var count = 0;
868
+ var limit = limit || this.stack.length;
869
+ var type = 'ajaxError';
870
+ for(var i=0; i< size; i++) {
871
+ if(this.stack[i].type == type) {
872
+ if(count < limit) {
873
+ results.push(this.stack[i]);
874
+ count +=1;
875
+ } else {
876
+ break;
877
+ }
878
+ }
879
+ }
880
+ return results;
586
881
  }
587
882
  });
588
883
 
589
884
  DcmgrGUI.prototype = {
590
885
  initialize:function(){
591
886
  $.deferred.define();
887
+ this.config = {
888
+ error_popup: true,
889
+ error_popup_once: true
890
+ };
891
+
892
+ this.logger = new DcmgrGUI.Logger();
893
+ },
894
+ getConfig: function(key){
895
+ return this.config[key];
896
+ },
897
+ setConfig: function(key, value) {
898
+ this.config[key] = value;
592
899
  }
593
- }
900
+ }