kaui 0.16.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/app/assets/javascripts/application.js +1 -1
  4. data/app/assets/javascripts/kaui/kaui.js +78 -1
  5. data/app/assets/stylesheets/bootstrap_and_overrides.css.less +5 -0
  6. data/app/assets/stylesheets/kaui/account.less +20 -0
  7. data/app/assets/stylesheets/kaui/audit.less +38 -0
  8. data/app/assets/stylesheets/kaui/common.less +103 -0
  9. data/app/assets/stylesheets/kaui/datatable.less +19 -0
  10. data/app/assets/stylesheets/kaui/kaui.less +3 -1
  11. data/app/assets/stylesheets/kaui/subscription.less +15 -0
  12. data/app/assets/stylesheets/kaui/tags.less +30 -1
  13. data/app/controllers/kaui/account_custom_fields_controller.rb +24 -0
  14. data/app/controllers/kaui/account_tags_controller.rb +21 -0
  15. data/app/controllers/kaui/accounts_controller.rb +43 -16
  16. data/app/controllers/kaui/admin_tenants_controller.rb +152 -11
  17. data/app/controllers/kaui/audit_logs_controller.rb +93 -0
  18. data/app/controllers/kaui/bundles_controller.rb +15 -3
  19. data/app/controllers/kaui/custom_fields_controller.rb +2 -0
  20. data/app/controllers/kaui/engine_controller_util.rb +14 -0
  21. data/app/controllers/kaui/invoice_items_controller.rb +17 -0
  22. data/app/controllers/kaui/invoices_controller.rb +22 -5
  23. data/app/controllers/kaui/payment_methods_controller.rb +10 -9
  24. data/app/controllers/kaui/subscriptions_controller.rb +54 -7
  25. data/app/controllers/kaui/tag_definitions_controller.rb +1 -0
  26. data/app/helpers/kaui/account_helper.rb +28 -0
  27. data/app/helpers/kaui/object_helper.rb +4 -0
  28. data/app/helpers/kaui/permissions_helper.rb +15 -0
  29. data/app/helpers/kaui/plugin_helper.rb +58 -0
  30. data/app/helpers/kaui/subscription_helper.rb +9 -7
  31. data/app/models/kaui/admin_tenant.rb +20 -6
  32. data/app/models/kaui/catalog.rb +4 -4
  33. data/app/models/kaui/tag.rb +1 -1
  34. data/app/models/kaui/tag_definition.rb +1 -1
  35. data/app/views/kaui/account_custom_fields/index.html.erb +35 -0
  36. data/app/views/kaui/account_tags/index.html.erb +35 -0
  37. data/app/views/kaui/accounts/_account_info.html.erb +5 -0
  38. data/app/views/kaui/accounts/_billing_info.html.erb +1 -1
  39. data/app/views/kaui/accounts/_close_account_modal.html.erb +98 -0
  40. data/app/views/kaui/accounts/index.html.erb +0 -7
  41. data/app/views/kaui/accounts/show.html.erb +4 -0
  42. data/app/views/kaui/admin_tenants/_add_allowed_user_modal.html.erb +64 -0
  43. data/app/views/kaui/admin_tenants/_form_plugin_config.erb +257 -151
  44. data/app/views/kaui/admin_tenants/_show_catalog_simple.erb +133 -48
  45. data/app/views/kaui/admin_tenants/_show_catalog_xml.erb +3 -2
  46. data/app/views/kaui/admin_tenants/show.html.erb +6 -1
  47. data/app/views/kaui/audit_logs/_show_history_modal.html.erb +177 -0
  48. data/app/views/kaui/audit_logs/index.html.erb +52 -0
  49. data/app/views/kaui/bundle_tags/_form_bar.html.erb +4 -2
  50. data/app/views/kaui/bundles/index.html.erb +21 -14
  51. data/app/views/kaui/chargebacks/_form.html.erb +1 -9
  52. data/app/views/kaui/charges/_form.html.erb +2 -10
  53. data/app/views/kaui/credits/_form.html.erb +1 -9
  54. data/app/views/kaui/custom_fields/_form.html.erb +1 -1
  55. data/app/views/kaui/custom_fields/_list_bar.html.erb +1 -1
  56. data/app/views/kaui/invoices/_invoice_table.html.erb +30 -2
  57. data/app/views/kaui/layouts/kaui_account_navbar.html.erb +7 -0
  58. data/app/views/kaui/layouts/kaui_flash.html.erb +13 -2
  59. data/app/views/kaui/payment_methods/_new_creditcard_payment_method.html.erb +11 -11
  60. data/app/views/kaui/payment_methods/_plugin_properties.html.erb +1 -1
  61. data/app/views/kaui/payments/_form.html.erb +1 -9
  62. data/app/views/kaui/refunds/_form.html.erb +4 -6
  63. data/app/views/kaui/subscriptions/_cancel_by_date_modal.html.erb +62 -0
  64. data/app/views/kaui/subscriptions/_form.html.erb +7 -13
  65. data/app/views/kaui/subscriptions/_subscriptions_table.html.erb +50 -11
  66. data/app/views/kaui/subscriptions/new.html.erb +3 -1
  67. data/app/views/kaui/tag_definitions/_form.html.erb +139 -0
  68. data/app/views/kaui/tags/index.html.erb +1 -1
  69. data/app/views/kaui/transactions/_control_plugin_names.html.erb +1 -1
  70. data/config/routes.rb +18 -2
  71. data/db/migrate/20130812155313_devise_create_kaui_users.rb +9 -7
  72. data/db/migrate/20150109214021_create_kaui_tenants.rb +8 -6
  73. data/db/migrate/20150112232813_create_kaui_allowed_users.rb +15 -11
  74. data/lib/kaui/engine.rb +1 -0
  75. data/lib/kaui/version.rb +1 -1
  76. data/test/dummy/config/database.yml +6 -1
  77. data/test/fixtures/SpyCarAdvanced.xml +824 -0
  78. data/test/functional/kaui/account_children_controller_test.rb +1 -1
  79. data/test/functional/kaui/account_custom_fields_controller_test.rb +29 -0
  80. data/test/functional/kaui/account_tags_controller_test.rb +19 -0
  81. data/test/functional/kaui/accounts_controller_test.rb +23 -6
  82. data/test/functional/kaui/admin_controller_test.rb +2 -2
  83. data/test/functional/kaui/admin_tenants_controller_test.rb +76 -5
  84. data/test/functional/kaui/audit_logs_controller_test.rb +71 -0
  85. data/test/functional/kaui/bundles_controller_test.rb +2 -1
  86. data/test/functional/kaui/payments_controller_test.rb +1 -1
  87. data/test/functional/kaui/subscriptions_controller_test.rb +1 -2
  88. data/test/functional/kaui/tag_definitions_controller_test.rb +2 -1
  89. data/test/killbill_test_helper.rb +5 -2
  90. data/test/unit/kaui/admin_tenant_test.rb +100 -0
  91. data/test/unit/kaui/money_helper_test.rb +1 -1
  92. metadata +58 -13
  93. data/app/assets/javascripts/kaui/validation.js +0 -21
  94. data/test/dummy/log/test.log +0 -0
@@ -9,16 +9,32 @@
9
9
 
10
10
  <%= form_tag({:action => :upload_plugin_config}, :method => 'post', :multipart => true, :class => 'form-horizontal') do %>
11
11
  <%= hidden_field_tag(:id, @tenant.id) %>
12
+ <%= hidden_field_tag(:plugin_name) %>
13
+ <%= hidden_field_tag(:plugin_key) %>
14
+ <%= hidden_field_tag(:plugin_type) %>
12
15
 
13
- <div class="form-group">
14
- <%= label_tag :plugin_name, 'Plugin name', :class => 'col-sm-2 control-label' %>
16
+ <input type="hidden" id="plugin_repository" value="<%= plugin_repository.to_json %>" >
17
+
18
+ <div id="plugin" class="form-group">
19
+ <%= label_tag :entered_plugin_name, 'Plugin name', :class => 'col-sm-2 control-label' %>
15
20
  <div class="col-sm-4">
16
- <%= text_field_tag :plugin_name, nil, :class => 'form-control', :plugin_config => @plugin_config, :tenant_plugin_config => @tenant_plugin_config %>
21
+ <select class="form-control" id="select_plugin_name"></select>
22
+ <%= text_field_tag :entered_plugin_name, nil, :class => 'form-control', :plugin_config => @plugin_config, :tenant_plugin_config => @tenant_plugin_config %>
23
+ <div class="text plugin-suggestion text-danger"></div>
17
24
  </div>
25
+ <label class="col-sm-1 toggle-container control-label">
26
+ <label class="switch">
27
+ <input id="toggle_input" type="checkbox">
28
+ <span class="slider round"></span>
29
+ </label>
30
+ </label>
31
+ <label class="col-sm-3 control-label toggle-label text-muted">or toggle plugin name input</label>
18
32
  </div>
33
+
19
34
  <!-- Anchor DIV that gets thrown away when switching plugins -->
20
- <div id="plugin_config_properties" , plugin_name="" , class="col-sm-10">
35
+ <div id="plugin_config_properties" plugin_name="" class="col-sm-10">
21
36
  </div>
37
+
22
38
  <div class="form-group">
23
39
  <div class="col-sm-offset-2 col-sm-10">
24
40
  <%= submit_tag 'Upload', :class => 'btn btn-default' %>
@@ -28,172 +44,262 @@
28
44
  </div>
29
45
  <% end %>
30
46
 
47
+ <script id="plugin_config_properties_template" type="text/template">
48
+ {{#plugin_props_with_values}}
49
+ <div class="form-group">
50
+ <label class="col-sm-2 control-label" for="{{property}}">{{property_label}}</label>
51
+ <div class="col-sm-4">
52
+ {{#is_raw_config}}
53
+ <textarea name="plugin_properties[raw_config]" id="raw_config" rows="10" class="form-control">{{value}}</textarea>
54
+ {{/is_raw_config}}
55
+ {{^is_raw_config}}
56
+ <input type="text" name="plugin_properties[{{property}}]" id="{{property}}" class="form-control" value="{{value}}" />
57
+ {{/is_raw_config}}
58
+ </div>
59
+ </div>
60
+ {{/plugin_props_with_values}}
61
+ </script>
62
+
63
+ <script id="plugin_name_options_template" type="text/template">
64
+ <option></option>
65
+ {{#plugin_repository}}
66
+ {{#start_installed}}<optgroup label="Installed">{{/start_installed}}
67
+ {{#end_installed}}</optgroup>>{{/end_installed}}
68
+ <option value="{{plugin_name}}" data-plugin-type="{{plugin_type}}" >
69
+ {{plugin_key}}
70
+ </option>
71
+ {{/plugin_repository}}
72
+ </script>
73
+
31
74
  <%= javascript_tag do %>
75
+ $(document).ready(function() {
76
+
77
+ $('#entered_plugin_name').toggle();
78
+ $('#toggle_input').on('change', function() {
79
+ $('#select_plugin_name').toggle();
80
+ $('#entered_plugin_name').toggle();
81
+ $('.toggle-label').toggleClass('text-muted');
82
+ $("#plugin_name").val('');
83
+ $("#plugin_key").val('');
84
+ $("#plugin_type").val('');
85
+ $('#entered_plugin_name').val('');
86
+ $('#select_plugin_name').val('');
87
+ $('#plugin_config_properties').attr('plugin_name', '');
88
+ $('#plugin_config_properties').empty();
32
89
 
33
- function get_existing_tenant_plugin_properties(plugin_name) {
34
-
35
- var tenant_plugin_properties = $('#plugin_name').attr('tenant_plugin_config');
36
- var res = {}
37
- if (tenant_plugin_properties != undefined) {
38
- $.each(tenant_plugin_properties.split(';'), function(idx, el) {
39
- var el_parts = el.split('::');
40
- var el_plugin_name = el_parts[0];
41
- var el_props = el_parts[1];
42
- if (el_plugin_name == plugin_name) {
43
- if (el_props.split('=')[0] == 'raw_config') {
44
- res['raw_config'] = el_props.substr(11);
45
- } else {
46
- $.map(el_props.split(','), function(el) {
47
- var parts = el.split('=');
48
- res[parts[0]] = parts[1];
49
- });
50
- }
51
- return false;
90
+ });
91
+
92
+ $('#select_plugin_name').on('click', function(e) {
93
+ if (e.target.localName == 'option') {
94
+ var plugin_name = e.target.value;
95
+ var plugin_key = e.target.text;
96
+ $("#plugin_name").val(plugin_name);
97
+ $("#plugin_key").val(plugin_key);
98
+ $("#plugin_type").val(e.target.dataset['pluginType']);
99
+ $('#plugin_config_properties').attr('plugin_name', '');
100
+
101
+ add_properties_for_plugin(plugin_key, plugin_name);
52
102
  }
53
103
  });
54
- }
55
- return res;
56
- }
57
-
58
- function get_selected_plugin_info() {
59
- var plugin_name = $('#plugin_name').val();
60
- var plugin_config_str = $('#plugin_name').attr('plugin_config');
61
-
62
- var res = {}
63
- /* Deserialize plugin/properties (see AdminTenant model)*/
64
- $.each(plugin_config_str.split(';'), function(idx, el) {
65
- var el_parts = el.split(':');
66
- var el_parts_key = el_parts[0].split('#');
67
- var el_plugin_name = el_parts_key[0];
68
- var el_plugin_type = el_parts_key[1];
69
- var el_plugin_props = el_parts[1];
70
- if (el_plugin_name == plugin_name) {
71
- res['type'] = el_plugin_type;
72
- res['props'] = el_plugin_props == "" ? [] : (el_plugin_type == "" ? ['raw_config'] : el_plugin_props.split(','));
73
- return false;
104
+
105
+ populate_plugin_name_options();
106
+ function populate_plugin_name_options(){
107
+ var plugin_repository = JSON.parse($("#plugin_repository").val());
108
+ for(var idx = 0, size = plugin_repository.length; idx < size; idx++) {
109
+ if (idx == 0 && plugin_repository[idx].installed) {
110
+ plugin_repository[idx]['start_installed'] = true;
111
+ }
112
+
113
+ if (idx > 0 && !plugin_repository[idx].installed && plugin_repository[idx - 1].installed) {
114
+ plugin_repository[idx]['end_installed'] = true;
115
+ break;
116
+ }
117
+ }
118
+
119
+ var template = $("#plugin_name_options_template").html();
120
+ var options_html = Mustache.render( template , { plugin_repository: plugin_repository});
121
+ $("#select_plugin_name").html(options_html);
122
+ }
123
+
124
+ function get_existing_tenant_plugin_properties(entered_plugin_name) {
125
+ var tenant_plugin_properties = $('#entered_plugin_name').attr('tenant_plugin_config');
126
+ var res = {}
127
+ if (tenant_plugin_properties != undefined) {
128
+ $.each(tenant_plugin_properties.split(';'), function(idx, el) {
129
+ var el_parts = el.split('::');
130
+ var el_plugin_name = el_parts[0];
131
+ var el_props = el_parts[1];
132
+ if (el_plugin_name === entered_plugin_name) {
133
+ if (el_props.split('=')[0] == 'raw_config') {
134
+ res['raw_config'] = el_props.substr(11);
135
+ } else {
136
+ $.map(el_props.split('|'), function(el) {
137
+ var parts = el.split('=');
138
+ res[parts[0]] = parts[1];
139
+ });
140
+ }
141
+ return false;
142
+ }
143
+ });
144
+ }
145
+ return res;
146
+ }
147
+
148
+ function get_selected_plugin_info(plugin_index) {
149
+ var plugin_config_str = $('#entered_plugin_name').attr('plugin_config');
150
+ var res = {}
151
+ /* Deserialize plugin/properties (see AdminTenant model)*/
152
+ $.each(plugin_config_str.split(';'), function(idx, el) {
153
+ var el_parts = el.split(':');
154
+ var el_parts_key = el_parts[0].split('#');
155
+ var el_plugin_name = el_parts_key[0];
156
+ var el_plugin_type = el_parts_key[1];
157
+ var el_plugin_props = el_parts[1];
158
+ if (el_plugin_name == plugin_index) {
159
+ res['type'] = el_plugin_type;
160
+ res['props'] = el_plugin_props == "" ? [] : (el_plugin_type == "" ? ['raw_config'] : el_plugin_props.split(','));
161
+ return false;
162
+ }
163
+ });
164
+
165
+ if (res['props'] == undefined) {
166
+ res['type'] = '';
167
+ res['props'] = ['raw_config'];
168
+ }
169
+
170
+ return res;
74
171
  }
75
- });
76
172
 
77
- if (res['props'] == undefined) {
78
- res['type'] = '';
79
- res['props'] = ['raw_config'];
80
- }
173
+ function add_properties_for_plugin(plugin_key, plugin_name) {
174
+ console.log(plugin_key, plugin_name);
175
+ var plugin_info = get_selected_plugin_info(plugin_key);
176
+
177
+ if (isBlank(plugin_name)) {
178
+ $('#plugin_config_properties').empty();
179
+ $('#plugin_config_properties').attr('plugin_name', '');
180
+ return;
181
+ }
182
+
183
+ if ($('#plugin_config_properties').attr('plugin_name') == plugin_name) {
184
+ /* Already set...*/
185
+ return;
186
+ }
81
187
 
82
- return res;
83
- }
188
+ /* Retrieve existing plugin properties for this tenant */
189
+ var existing_props = get_existing_tenant_plugin_properties(plugin_key);
190
+
191
+ var type = plugin_info['type'];
192
+ var props = plugin_info['props']
193
+
194
+ $('#plugin_type').val(type);
195
+ /* Prune the tree to restart from scratch */
196
+ $('#plugin_config_properties').empty();
197
+ $('#plugin_config_properties').append('<label class="col-sm-2 control-label" for="plugin_name">Plugin Properties</label>');
198
+ $('#plugin_config_properties').append('<div id="plugin_config_properties_anchor" class="col-sm-offset-2 col-sm-10">');
199
+
200
+ var merged_props_with_values = existing_props;
201
+ if (props != undefined) {
202
+ $.each(props, function(idx, p) {
203
+ if (merged_props_with_values[p] == undefined) {
204
+ merged_props_with_values[p] = '';
205
+ }
206
+ });
207
+ }
84
208
 
85
- function init_plugin_config_source() {
86
- var plugin_config_str = $('#plugin_name').attr('plugin_config');
87
- var res = []
88
- $.map(plugin_config_str.split(";"), function(el) { res.push(el.split(':')[0].split('#')[0]) });
89
- return res;
90
- }
209
+ add_property_form_entry(merged_props_with_values);
91
210
 
92
- function add_properties_for_plugin(plugin_name, plugin_info) {
211
+ $('#plugin_config_properties').attr('plugin_name', plugin_name);
212
+ }
93
213
 
94
- if (plugin_name == "") {
95
- $('#plugin_config_properties').empty();
96
- return;
97
- }
214
+ function format_label(input) {
215
+ /* Keep latest piece of a system property to keep it short */
216
+ var label_name = input.split('.').pop();
217
+ /* Replace underscore with comma */
218
+ label_name = label_name.replace(/_/g, ',');
219
+ /* Replace uppercase with comma + uppercase */
220
+ label_name = label_name.replace(/([A-Z]+)/g, ",$1");
221
+ /* Split name make sure each word starts with Uppercase */
222
+ var tmp1 = label_name.split(',');
223
+ var label_name_array = [];
224
+ $.map(tmp1, function(el) { label_name_array.push(el.charAt(0).toUpperCase() + el.slice(1)) });
225
+ label_name = label_name_array.join(' ');
226
+ return label_name;
227
+ }
98
228
 
99
- if ($('#plugin_config_properties').attr('plugin_name') == plugin_name) {
100
- /* Already set...*/
101
- return;
102
- }
229
+ function add_property_form_entry(merged_props_with_values) {
230
+ var plugin_props_with_values = [];
103
231
 
104
- var type = plugin_info['type'];
105
- var props = plugin_info['props']
232
+ $.each(merged_props_with_values, function(p, v) {
233
+ plugin_props_with_values.push({ property_label: format_label(p), property: p, value: v, is_raw_config: p == 'raw_config'});
234
+ });
106
235
 
107
- /* Prune the tree to restart from scratch */
108
- $('#plugin_config_properties').empty();
236
+ var template = $("#plugin_config_properties_template").html();
237
+ var plugin_props_with_values_html = Mustache.render( template , { plugin_props_with_values: plugin_props_with_values});
238
+ $("#plugin_config_properties_anchor").html(plugin_props_with_values_html);
239
+ }
109
240
 
110
- $('#plugin_config_properties').append('<input type="hidden" name="plugin_type" id="plugin_type" value="' + type + '" />');
111
- $('#plugin_config_properties').append('<label class="col-sm-2 control-label" for="plugin_name">Plugin Properties</label>');
112
- $('#plugin_config_properties').append('<div id="plugin_config_properties_anchor" class="col-sm-offset-2 col-sm-10">');
241
+ // Free text related functions and handlers
242
+ init_plugin_name_handlers();
243
+ function init_plugin_name_handlers() {
244
+ /* Intercept ENTER and potentially display property form if plugin is know */
245
+ $('#entered_plugin_name').keyup(function (e) {
246
+ e.preventDefault();
247
+ if (e.keyCode === 13) {
248
+ suggest_plugin_name();
249
+ }
250
+ });
113
251
 
114
- /* Retrieve existing plugin properties for this tenant */
115
- var existing_props = get_existing_tenant_plugin_properties(plugin_name);
252
+ /* Intercept mouseleave and potentially display property form if plugin is know */
253
+ $('#entered_plugin_name').on('mouseleave', function() {
254
+ suggest_plugin_name();
255
+ });
256
+ }
116
257
 
117
- var merged_props_with_values = existing_props;
118
- if (props != undefined) {
119
- $.each(props, function(idx, p) {
120
- if (merged_props_with_values[p] == undefined) {
121
- merged_props_with_values[p] = '';
258
+ function suggested_response(response) {
259
+ if (!isBlank(response.suggestion)) {
260
+ $(".plugin-suggestion").html(response.suggestion);
261
+
262
+ $("#suggested").click(function(e) {
263
+ var plugin_name = e.currentTarget.dataset['pluginName'];
264
+ var plugin_key = e.currentTarget.dataset['pluginKey'];
265
+
266
+ $("#entered_plugin_name").val(plugin_name);
267
+ $("#plugin_key").val(plugin_key);
268
+ $("#plugin_type").val(e.currentTarget.dataset['pluginType']);
269
+
270
+ $(".plugin-suggestion").html('');
271
+ add_properties_for_plugin(isBlank(plugin_key) ? plugin_name : plugin_key, plugin_name);
272
+ });
273
+
274
+ } else {
275
+ $(".plugin-suggestion").html('');
122
276
  }
123
- });
124
- }
125
-
126
- $.each(merged_props_with_values, function(p, v) {
127
- add_property_form_entry(format_label(p), p, v);
128
- });
129
-
130
- $('#plugin_config_properties').attr('plugin_name', plugin_name);
131
- }
132
-
133
- function format_label(input) {
134
- /* Keep latest piece of a system property to keep it short */
135
- var label_name = input.split('.').pop();
136
- /* Replace underscore with comma */
137
- label_name = label_name.replace(/_/g, ',');
138
- /* Replace uppercase with comma + uppercase */
139
- label_name = label_name.replace(/([A-Z]+)/g, ",$1");
140
- /* Split name make sure each word starts with Uppercase */
141
- var tmp1 = label_name.split(',');
142
- var label_name_array = [];
143
- $.map(tmp1, function(el) { label_name_array.push(el.charAt(0).toUpperCase() + el.slice(1)) });
144
- label_name = label_name_array.join(' ');
145
- return label_name;
146
- }
147
-
148
- function add_property_form_entry(property_label, property, current_value) {
149
-
150
- var clone = $('#PluginConfig form div').first().clone();
151
- clone.children("label").attr('for', property).text(property_label);
152
- clone.children("div").first().attr("name", property).attr("id", property);
153
- var input = clone.children("div").children("input").first();
154
- input.removeAttr('autocomplete').removeAttr('plugin_config');
155
- if (property == 'raw_config') {
156
- var text_area = $('<textarea name="plugin_properties[raw_config]" id="raw_config" rows="10" class="form-control">');
157
- input.replaceWith(text_area);
158
- text_area.attr("name", "plugin_properties[" + property + "]")
159
- .attr("id", property)
160
- .attr('class', 'form-control')
161
- .val(current_value);
162
-
163
- input.replaceWith('<textarea name="plugin_properties[raw_config]" id="raw_config" rows="10" class="form-control">').text(current_value);
164
- } else {
165
- input.attr("name", "plugin_properties[" + property + "]")
166
- .attr("id", property)
167
- .attr('class', 'form-control')
168
- .val(current_value);
169
- }
170
-
171
- /* Attach clone object */
172
- $('#plugin_config_properties_anchor').append(clone);
173
-
174
- }
175
-
176
-
177
- function init_plugin_name_handlers() {
178
- /* Intercept ENTER and potentially display property form if plugin is know */
179
- $('#plugin_name').keyup(function (e) {
180
- if (e.keyCode === 13) {
181
- add_properties_for_plugin($('#plugin_name').val(), get_selected_plugin_info());
277
+
278
+ var plugin_name = $('#entered_plugin_name').val();
279
+ var plugin_key = $("#plugin_key").val();
280
+ $("#plugin_name").val(plugin_name);
281
+
282
+ add_properties_for_plugin(isBlank(plugin_key) ? plugin_name : plugin_key, plugin_name);
182
283
  }
183
- });
184
284
 
185
- /* Intercept mouseleave and potentially display property form if plugin is know */
186
- $('#plugin_name').on('mouseleave', function() {
187
- add_properties_for_plugin($('#plugin_name').val(), get_selected_plugin_info());
188
- });
285
+ function suggest_plugin_name() {
286
+ var plugin_name = $("#entered_plugin_name").val();
287
+ $("#plugin_key").val(plugin_name);
189
288
 
190
- /* Attach auto-completion source */
191
- $('#plugin_name').autocomplete({
192
- source: init_plugin_config_source()
193
- });
194
- }
289
+ if (isBlank(plugin_name)) {
290
+ return;
291
+ }
292
+
293
+ $.ajax({
294
+ url: '<%= suggest_plugin_name_path() %>',
295
+ type: "GET",
296
+ dataType: "json",
297
+ data: {
298
+ "plugin_name": plugin_name,
299
+ },
300
+ success: suggested_response
301
+ });
302
+ }
195
303
 
196
- $(document).ready(function() {
197
- init_plugin_name_handlers();
198
304
  });
199
- <% end %>
305
+ <% end %>
@@ -19,7 +19,7 @@
19
19
  <b>Catalog Versions:</b>
20
20
  </span>
21
21
  <select id="select_catalog" class="selectpicker show-menu-arrow">
22
- <% @catalogs.each_with_index do |catalog, i| %>
22
+ <% @catalog_versions.reverse_each do |catalog, i| %>
23
23
  <option idx="<%= catalog[:version] %>"><%= catalog[:version_date] %></option>
24
24
  <% end %>
25
25
  </select>
@@ -30,70 +30,155 @@
30
30
  <th>Product</th>
31
31
  <th>Category</th>
32
32
  <th>Billing Period</th>
33
- <% @catalogs.each do |catalog| %>
34
- <th class="catalog_version_<%= catalog[:version] %>">
35
- <select id="select_currencies_<%= catalog[:version] %>" class="selectpicker show-menu-arrow">
36
- <% catalog[:currencies].each_with_index do |currency, i| %>
37
- <option><%= currency %></option>
38
- <% end %>
39
- </select>
40
- </th>
41
- <% end %>
33
+ <th id="currency_select"></th>
42
34
  <th>Trial</th>
43
35
  <th></th>
44
36
  </tr>
45
37
  </thead>
46
- <tbody>
47
- <% @catalogs.each do |catalog| %>
48
- <% catalog[:plans].each do |p| %>
49
- <tr class="catalog_version_<%= catalog[:version] %>">
50
- <td><%= p.plan_id %></td>
51
- <td><%= humanized_product_name(p.product_name) %></td>
52
- <td><%= humanized_product_category(p.product_category) %></td>
53
- <td><%= humanized_billing_period(p.billing_period) %></td>
54
- <td>
55
- <% catalog[:currencies].each do |c| %>
56
- <span class="plan_currency_<%= c %>"><%= p.prices[c] %></span>
57
- <% end %>
58
- </td>
59
- <td><%= p.trial_length != 0 ? "#{p.trial_length} #{humanized_time_unit(p.trial_time_unit)}" : "N/A" %></td>
60
- <td><%= link_to '<i class="fa fa-plus-square"></i>'.html_safe + " currency", kaui_engine.admin_tenant_new_plan_currency_path(:id => @tenant.id, :plan_id => p.plan_id),
61
- :class => 'btn btn-xs' %></td>
62
- </tr>
63
- <% end %>
64
- <% end %>
38
+ <tbody id="catalog_detail">
39
+
65
40
  </tbody>
66
41
  </table>
67
42
  </div>
68
43
 
44
+ <script id="currencies_template" type="text/template">
45
+ {{#catalog}}
46
+ <select id="select_currencies" class="selectpicker show-menu-arrow">
47
+ {{#currencies}}
48
+ <option>{{.}}</option>
49
+ {{/currencies}}
50
+ </select>
51
+ {{/catalog}}
52
+ </script>
53
+
54
+ <script id="selected_catalog_template" type="text/template" >
55
+ {{#catalog}}
56
+ {{#plans}}
57
+ <tr class="selected_catalog">
58
+ <td>{{plan_id}}</td>
59
+ <td>{{#humanized_product_name}}{{product_name}}{{/humanized_product_name}}</td>
60
+ <td>{{#humanized_product_category}}{{product_category}}{{/humanized_product_category}}</td>
61
+ <td>{{#humanized_billing_period}}{{billing_period}}{{/humanized_billing_period}}</td>
62
+ <td>
63
+ {{#currenciesWithPrices}}
64
+ <span class="plan_currency_{{currency}}">{{price}}</span>
65
+ {{/currenciesWithPrices}}
66
+ </td>
67
+ <td>
68
+ {{#trial_length}} {{trial_length}} {{#humanized_time_unit}}{{trial_time_unit}}{{/humanized_time_unit}} {{/trial_length}}
69
+ {{^trial_length}} N/A {{/trial_length}}
70
+ </td>
71
+ <td><a class="btn btn-xs"
72
+ href="{{new_plan_currency_path}}"><i class="fa fa-plus-square"></i> currency</a></td>
73
+ </tr>
74
+ {{/plans}}
75
+ {{/catalog}}
76
+ </script>
69
77
 
70
78
  <%= javascript_tag do %>
79
+ window.onload = function() {
80
+ fetchCatalog('<%= @latest_version %>');
81
+ };
71
82
 
72
- function initBasicConfig() {
73
- displayCatalogVersion();
74
- displayAmountsForCurrency();
75
- }
83
+ function renderCurrencySelect(data) {
84
+ var template = $("#currencies_template").html();
85
+ var currencies_html = Mustache.render(template,data);
86
+ $("#currency_select").html(currencies_html);
87
+ }
76
88
 
77
- function displayCatalogVersion() {
78
- $('[class^="catalog_version_"]').hide();
79
- $("[class^=catalog_version_" + $("#select_catalog option:selected" ).attr("idx") + "]").show();
80
- }
89
+ function renderCatalog(data){
90
+ for (var i = 0; i < data.catalog.length; i++) {
91
+ var current = data.catalog[i];
92
+ for (var j = 0; j < current.plans.length; j++) {
93
+ var plan = current.plans[j];
94
+ plan['currenciesWithPrices'] = [];
95
+ for (var currency in plan['prices']) {
96
+ plan['currenciesWithPrices'].push({currency: currency, price: plan['prices'][currency]});
97
+ }
98
+ plan['new_plan_currency_path'] = Routes.kaui_engine_admin_tenant_new_plan_currency_path(<%= @tenant.id %>, {plan_id: plan['plan_id']});
99
+ plan['humanized_product_name'] = function(){
100
+ return function (input, render) {
101
+ var product_name = render(input);
102
+ return product_name.toLowerCase().replace(/\b\w/g, function(l){ return l.toUpperCase() });
103
+ }
104
+ }
81
105
 
82
- function displayAmountsForCurrency() {
83
- var catalogVersion = $("#select_catalog option:selected" ).attr("idx");
84
- $('[class^="plan_currency_"]').hide();
85
- $("[class^=plan_currency_" + $("#select_currencies_" + catalogVersion + " option:selected" ).text() + "]").show();
86
- }
106
+ plan['humanized_product_category'] = function(){
107
+ return function (input, render) {
108
+ var product_category = render(input);
109
+ if (product_category == 'BASE') {
110
+ return 'Base'
111
+ } else if (product_category == 'ADD_ON') {
112
+ return 'Add-on'
113
+ } else {
114
+ return product_category.toLowerCase().replace(/\b\w/g, function(l){ return l.toUpperCase() });
115
+ }
116
+ }
117
+ }
87
118
 
88
- $(document).ready(function() {
119
+ plan['humanized_billing_period'] = function(){
120
+ return function (input, render) {
121
+ var billing_period = render(input);
122
+ if (billing_period == 'NO_BILLING_PERIOD') {
123
+ return 'No billing period'
124
+ } else {
125
+ return billing_period.toLowerCase().replace(/\b\w/g, function(l){ return l.toUpperCase() });
126
+ }
127
+ }
128
+ }
89
129
 
90
- $("#select_catalog").change(function() {
91
- displayCatalogVersion();
92
- });
130
+ plan['humanized_time_unit'] = function(){
131
+ return function (input, render) {
132
+ var time_unit = render(input);
133
+ return time_unit.toLowerCase().replace(/\b\w/g, function(l){ return l.toUpperCase() });
134
+ }
135
+ }
136
+ }
137
+ }
138
+ var template = $("#selected_catalog_template").html();
139
+ var catalog_html = Mustache.render(template,data);
140
+ $("#catalog_detail").html(catalog_html);
141
+ displayAmountsForCurrency();
142
+ }
93
143
 
94
- $('[id^="select_currencies"]').change(function() {
144
+ function initBasicConfig() {
95
145
  displayAmountsForCurrency();
146
+ }
147
+
148
+ function displayAmountsForCurrency() {
149
+ $('[class^="plan_currency_"]').hide();
150
+ $("[class^=plan_currency_" + $("#select_currencies option:selected" ).text() + "]").show();
151
+ }
152
+
153
+ function fetchCatalog(effectiveDate) {
154
+ if (effectiveDate == '')
155
+ return;
156
+
157
+ $.ajax(
158
+ {
159
+ url: Routes.kaui_engine_catalog_by_effective_date_path(),
160
+ type: "GET",
161
+ dataType: "json",
162
+ data: {
163
+ id: <%= @tenant.id %>,
164
+ effective_date: effectiveDate
165
+ },
166
+ success: function(data) {
167
+ renderCurrencySelect(data);
168
+ renderCatalog(data);
169
+ }
170
+ });
171
+ }
172
+
173
+ $(document).ready(function() {
174
+
175
+ $("#select_catalog").change(function() {
176
+ fetchCatalog(this.value);
177
+ });
178
+
179
+ $('[id^="select_currencies"]').change(function() {
180
+ displayAmountsForCurrency();
181
+ });
96
182
  });
97
- });
98
183
  <% end %>
99
184