kaui 3.0.1 → 3.0.2

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.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -1
  3. data/app/assets/config/kaui_manifest.js +2 -44
  4. data/app/assets/javascripts/application.js +12 -0
  5. data/app/assets/javascripts/kaui/kaui.js +7 -452
  6. data/app/assets/javascripts/kaui/kaui_override.js +441 -0
  7. data/app/assets/stylesheets/application.css +23 -0
  8. data/app/assets/stylesheets/kaui/account.css +34 -0
  9. data/app/assets/stylesheets/kaui/audit.css +19 -0
  10. data/app/assets/stylesheets/kaui/common.css +550 -0
  11. data/app/assets/stylesheets/kaui/datatable.css +71 -0
  12. data/app/assets/stylesheets/kaui/header.css +129 -0
  13. data/app/assets/stylesheets/kaui/home.css +72 -0
  14. data/app/assets/stylesheets/kaui/invoice.css +37 -0
  15. data/app/assets/stylesheets/kaui/kaui.css +152 -0
  16. data/app/assets/stylesheets/kaui/overdue.css +7 -0
  17. data/app/assets/stylesheets/kaui/payment.css +28 -0
  18. data/app/assets/stylesheets/kaui/subscription.css +15 -0
  19. data/app/assets/stylesheets/kaui/tags.css +137 -0
  20. data/app/assets/stylesheets/kaui/timeline.css +5 -0
  21. data/app/assets/stylesheets/kaui/tooltip.css +16 -0
  22. data/app/controllers/kaui/account_tags_controller.rb +1 -1
  23. data/app/controllers/kaui/admin_allowed_users_controller.rb +1 -1
  24. data/app/controllers/kaui/admin_tenants_controller.rb +3 -3
  25. data/app/controllers/kaui/bundle_tags_controller.rb +1 -1
  26. data/app/controllers/kaui/engine_controller_util.rb +1 -1
  27. data/app/controllers/kaui/home_controller.rb +21 -12
  28. data/app/controllers/kaui/invoice_tags_controller.rb +1 -1
  29. data/app/controllers/kaui/invoices_controller.rb +6 -1
  30. data/app/controllers/kaui/payment_methods_controller.rb +1 -1
  31. data/app/controllers/kaui/subscriptions_controller.rb +9 -8
  32. data/app/controllers/kaui/transactions_controller.rb +1 -1
  33. data/app/helpers/kaui/object_helper.rb +16 -1
  34. data/app/models/kaui/admin_tenant.rb +1 -1
  35. data/app/models/kaui/catalog.rb +2 -2
  36. data/app/models/kaui/invoice_payment.rb +1 -1
  37. data/app/models/kaui/overdue.rb +2 -2
  38. data/app/models/kaui/tag.rb +2 -2
  39. data/app/models/kaui/tag_definition.rb +1 -1
  40. data/app/views/kaui/accounts/_billing_info.html.erb +2 -4
  41. data/app/views/kaui/accounts/_form.html.erb +3 -3
  42. data/app/views/kaui/accounts/index.html.erb +0 -1
  43. data/app/views/kaui/admin_tenants/new_overdue_config.html.erb +5 -5
  44. data/app/views/kaui/home/_advanced_search_modal.html.erb +22 -1
  45. data/app/views/kaui/invoices/show.html.erb +2 -1
  46. data/app/views/kaui/layouts/kaui_header.html.erb +2 -18
  47. data/app/views/kaui/refunds/_form.html.erb +50 -2
  48. data/app/views/kaui/subscriptions/_cancel_by_date_modal.html.erb +1 -1
  49. data/app/views/kaui/subscriptions/_edit_form.html.erb +1 -1
  50. data/app/views/kaui/subscriptions/_form.html.erb +1 -1
  51. data/app/views/kaui/subscriptions/edit_bcd.erb +1 -1
  52. data/app/views/kaui/tag_definitions/_form.html.erb +1 -2
  53. data/config/routes.rb +1 -0
  54. data/lib/kaui/engine.rb +1 -4
  55. data/lib/kaui/version.rb +1 -1
  56. data/lib/kaui.rb +10 -10
  57. metadata +29 -130
  58. data/app/assets/javascripts/jquery.spin.js +0 -76
  59. data/app/assets/javascripts/kaui_application.js +0 -25
  60. data/app/assets/javascripts/spin.js +0 -76
  61. data/app/assets/stylesheets/bootstrap_and_overrides.scss +0 -240
  62. data/app/assets/stylesheets/kaui/account.scss +0 -52
  63. data/app/assets/stylesheets/kaui/audit.scss +0 -42
  64. data/app/assets/stylesheets/kaui/common.scss +0 -765
  65. data/app/assets/stylesheets/kaui/datatable.scss +0 -115
  66. data/app/assets/stylesheets/kaui/header.scss +0 -197
  67. data/app/assets/stylesheets/kaui/home.scss +0 -89
  68. data/app/assets/stylesheets/kaui/invoice.scss +0 -58
  69. data/app/assets/stylesheets/kaui/kaui.scss +0 -265
  70. data/app/assets/stylesheets/kaui/kaui_bootstrap.scss +0 -3
  71. data/app/assets/stylesheets/kaui/overdue.scss +0 -11
  72. data/app/assets/stylesheets/kaui/payment.scss +0 -43
  73. data/app/assets/stylesheets/kaui/subscription.scss +0 -27
  74. data/app/assets/stylesheets/kaui/tags.scss +0 -208
  75. data/app/assets/stylesheets/kaui/timeline.scss +0 -7
  76. data/app/assets/stylesheets/kaui/tooltip.scss +0 -15
  77. data/app/assets/stylesheets/kaui_application.css +0 -12
@@ -0,0 +1,441 @@
1
+ jQuery(document).ready(function ($) {
2
+
3
+ /*
4
+ * Mobile Data Adjustment
5
+ */
6
+
7
+ var running = false;
8
+ $('table.mobile-data').each(function () {
9
+ var count = $(this).find($('table.mobile-data tr')).length - 1;
10
+ $(this).append('<span class="left"><i class="fa fa-arrow-circle-left"></i></span>');
11
+ $(this).append('<span class="right"><i class="fa fa-arrow-circle-right"></i></span>');
12
+ $(this).append('<span class="center"><span class="current">1</span>/' + count + '</span>');
13
+ });
14
+ $('table.mobile-data > span.left').click(function () {
15
+
16
+ if (running === true)
17
+ return;
18
+
19
+ running = true;
20
+
21
+ var table = $(this).parent('table').children('tbody'),
22
+ current = table.find('tr:first-of-type'),
23
+ next = table.find('tr:last-of-type'),
24
+ page = table.children('span.center').children('span.current'),
25
+ number = parseInt(page.html()),
26
+ count = table.find($('table.mobile-data tr')).length - 1;
27
+
28
+ next.insertBefore(current);
29
+ number--;
30
+ if (number <= 0) {
31
+ number = count;
32
+ }
33
+ page.html(number);
34
+
35
+ fixCellHeight(table);
36
+
37
+ running = false;
38
+
39
+ });
40
+ $('table.mobile-data > span.right').click(function () {
41
+
42
+ if (running === true)
43
+ return;
44
+
45
+ running = true;
46
+
47
+ var table = $(this).parent('table').children('tbody'),
48
+ current = table.find('tr:first-of-type'),
49
+ last = table.find('tr:last-of-type'),
50
+ page = table.children('span.center').children('span.current'),
51
+ number = parseInt(page.html()),
52
+ count = table.find($('table.mobile-data tr')).length - 1;
53
+
54
+ current.insertAfter(last);
55
+ number++;
56
+ if (number > count) {
57
+ number = 1;
58
+ }
59
+ page.html(number);
60
+
61
+ fixCellHeight(table);
62
+
63
+ running = false;
64
+
65
+ });
66
+
67
+ function fixCellHeight(table) {
68
+
69
+ table.find('tr:first-of-type').children('th').each(function (i) {
70
+ i++;
71
+ var brother = table.find('tr:nth-of-type(2)').children('td:nth-of-type(' + i + ')');
72
+
73
+ if ($(this).height() > brother.height()) {
74
+ brother.css('height', $(this).outerHeight() + 'px');
75
+ } else {
76
+ $(this).css('height', brother.outerHeight() + 'px');
77
+ }
78
+
79
+ });
80
+
81
+ }
82
+
83
+ if ($(window).width() <= 768) {
84
+ $('table.mobile-data').each(function () {
85
+ fixCellHeight($(this));
86
+ });
87
+ }
88
+
89
+
90
+ /*
91
+ * Toggler activation
92
+ */
93
+ $('.toggler .first-line').click( function(e){
94
+ if (! ($(e.target).is('a') || $(e.target).parent().is('a'))) {
95
+ e.preventDefault();
96
+ $(this).parent('.toggler').toggleClass('toggled');
97
+ }
98
+ });
99
+
100
+ /*
101
+ * Toggle between combobox (US only) and text when entering the state.
102
+ */
103
+ $('#account_country').on('change', function(e){
104
+ toggle_state_input_type($('#account_country').val());
105
+ });
106
+
107
+ function toggle_state_input_type(state){
108
+ if (state == 'US'){
109
+ $('.text-state').hide().attr('name','hide');
110
+ $('.select-state').show().attr('name','account[state]');
111
+ }else{
112
+ $('.select-state').hide().attr('name','hide');
113
+ $('.text-state').show().attr('name','account[state]');
114
+ }
115
+ }
116
+
117
+ toggle_state_input_type($('#account_country').val());
118
+
119
+ /*
120
+ * Calculate first name length
121
+ */
122
+
123
+ $('#account_name').on('keyup', function(e){
124
+ set_first_name_length($(this).val());
125
+ });
126
+
127
+ $('#account_name').on('change', function(e){
128
+ if ($('#account_first_name_length').empty() ){
129
+ set_first_name_length($(this).val());
130
+ }
131
+ });
132
+
133
+ function set_first_name_length(name){
134
+ var name_in_parts = name.trim().split(' ');
135
+
136
+ if (name_in_parts.length > 1){
137
+ $('#account_first_name_length').val(name_in_parts[0].length);
138
+ }else{
139
+ $('#account_first_name_length').val('');
140
+ }
141
+ }
142
+
143
+
144
+ /*
145
+ * Custom Fields Errors
146
+ */
147
+
148
+
149
+ $('#custom_field_object_type').change(function(){
150
+
151
+ ajaxCloseAlert();
152
+
153
+ var uuid = document.getElementById("custom_field_object_id").value;
154
+ var my_url = '/custom_fields/check_object_exist';
155
+ obj_type = document.getElementById("custom_field_object_type").value;
156
+
157
+ if (uuid){
158
+ $.ajax({
159
+ url: my_url,
160
+ type: "GET",
161
+ dataType: "json",
162
+ data: {
163
+ uuid: uuid,
164
+ object_type: obj_type
165
+ },
166
+ success: function(data) {
167
+ if (data.status == 431) {
168
+ var msg = data["message"];
169
+ ajaxErrorAlert(msg);
170
+
171
+ }
172
+ }
173
+ });
174
+ }else{
175
+ var msg = 'Object ID cannot be empty';
176
+ ajaxErrorAlert(msg);
177
+ }
178
+
179
+
180
+
181
+
182
+
183
+
184
+ });
185
+
186
+ $('#custom_field_object_id').on('keyup', function(e) {
187
+
188
+ ajaxCloseAlert();
189
+
190
+ var uuid = $(this).val();
191
+ var my_url = '/custom_fields/check_object_exist';
192
+ obj_type = document.getElementById("custom_field_object_type").value;
193
+
194
+ $.ajax({
195
+ url: my_url,
196
+ type: "GET",
197
+ dataType: "json",
198
+ data: {
199
+ uuid: $(this).val(),
200
+ object_type: obj_type
201
+ },
202
+ success: function(data) {
203
+ if (data.status == 431) {
204
+ var msg = data["message"];
205
+ ajaxErrorAlert(msg);
206
+ }
207
+ }
208
+ });
209
+
210
+
211
+ });
212
+
213
+
214
+ /*
215
+ * Validate external key
216
+ */
217
+ const VALIDATE_EXTERNAL_KEY = {
218
+ account: { url: Routes.kaui_engine_accounts_validate_external_key_path(), invalid_msg_class_name: '.account_external_key_invalid_msg' },
219
+ payment_method: {url: Routes.kaui_engine_payment_methods_validate_external_key_path(), invalid_msg_class_name: '.payment_method_external_key_invalid_msg'},
220
+ bundle: {url: Routes.kaui_engine_subscriptions_validate_bundle_external_key_path(), invalid_msg_class_name: '.subscription_bundle_external_key_invalid_msg'},
221
+ subscription: {url: Routes.kaui_engine_subscriptions_validate_external_key_path(), invalid_msg_class_name: '.subscription_external_key_invalid_msg'}
222
+ }
223
+
224
+ validate_external_key($('#account_external_key').val(),'account');
225
+ $('#account_external_key').on('change', function(e){
226
+ validate_external_key($(this).val(),'account');
227
+ });
228
+
229
+ validate_external_key($('#payment_method_external_key').val(),'payment_method');
230
+ $('#payment_method_external_key').on('change', function(e){
231
+ validate_external_key($(this).val(),'payment_method');
232
+ });
233
+
234
+ validate_external_key($('#bundle_external_key').val(),'bundle');
235
+ $('#bundle_external_key').on('change', function(e){
236
+ validate_external_key($(this).val(),'bundle');
237
+ });
238
+
239
+ validate_external_key($('#subscription_external_key').val(),'subscription');
240
+ $('#subscription_external_key').on('change', function(e){
241
+ validate_external_key($(this).val(),'subscription');
242
+ });
243
+
244
+ function validate_external_key(external_key, key_for){
245
+ if (external_key == undefined || external_key == null || external_key.trim().length == 0){
246
+ $(VALIDATE_EXTERNAL_KEY[key_for].invalid_msg_class_name).hide();
247
+ }else {
248
+ $.ajax(
249
+ {
250
+ url: VALIDATE_EXTERNAL_KEY[key_for].url,
251
+ type: "GET",
252
+ dataType: "json",
253
+ data: {external_key: external_key},
254
+ success: function (data) {
255
+ if (data.is_found) {
256
+ $(VALIDATE_EXTERNAL_KEY[key_for].invalid_msg_class_name).show();
257
+ } else {
258
+ $(VALIDATE_EXTERNAL_KEY[key_for].invalid_msg_class_name).hide();
259
+ }
260
+ }
261
+ });
262
+ }
263
+ }
264
+
265
+ // Restrict numeric input for a text field
266
+ // Using "constraint validation API" to restrict input
267
+ $("input[type=number]").keydown(function(event) {
268
+ $(this).data('oldData', $(this).val());
269
+ }).keyup(function(event) {
270
+ if (event.currentTarget.validity.badInput) {
271
+ $(this).val($(this).data('oldData'));
272
+ }
273
+ });
274
+
275
+ // this will register a global ajax error for all jquery ajax requests (not including DataTable)
276
+ $( document ).ajaxError(function( event, jqxhr, settings, thrownError ) {
277
+ if (jqxhr.status == 0) {
278
+ return;
279
+ }
280
+
281
+ var message = 'Request error: ' + getMessageFromResponse(jqxhr);
282
+
283
+ if (jqxhr.status == 200) {
284
+ message = thrownError.message == undefined ? thrownError : thrownError.message;
285
+ }
286
+ ajaxErrorAlert(message);
287
+ });
288
+
289
+ function getMessageFromResponse(jqxhr) {
290
+ if (isBlank(jqxhr.responseJSON)) {
291
+ return jqxhr.responseText;
292
+ }
293
+
294
+ if (!isBlank(jqxhr.responseJSON.error)) {
295
+ return jqxhr.responseJSON.error;
296
+ }
297
+
298
+ return jqxhr.responseText;
299
+ }
300
+
301
+ // this will prevent DataTable to show an alert message box when an error occurs
302
+ // $.fn.DataTable.ext.errMode = 'none';
303
+ // this will try to register a DataTable error event to all tables, and if an error occurs will display the error on screen
304
+ $( document ).find(".table").on('error.dt', function ( e, settings, techNote, message ) {
305
+ ajaxErrorAlert('An error has been reported by DataTables: ' + message);
306
+ });
307
+
308
+ setObjectIdPopover();
309
+ });
310
+
311
+
312
+ // global function used to show an error message that occurs on a Ajax call, if timeout is passed the box will disappear when the time is up.
313
+ function ajaxErrorAlert(message, timeout) {
314
+ ajaxAlert("ajaxErrorAlert", message, timeout);
315
+ }
316
+
317
+ // global function used to show an information message.
318
+ function ajaxInfoAlert(message, timeout) {
319
+ ajaxAlert("ajaxInfoAlert", message, timeout);
320
+ }
321
+
322
+ // if timeout is passed the box will disappear when the time is up.
323
+ function ajaxAlert(alert_element_id, message, timeout) {
324
+ // do not show ajax alert if there is already an server alert
325
+ var serverAlertStatus = $(".server-alert").css("display");
326
+ if (serverAlertStatus != undefined && serverAlertStatus != "none") {
327
+ return;
328
+ }
329
+
330
+ var messageBox = $("#" + alert_element_id);
331
+ messageBox.find("#" + alert_element_id + "Message").text(message);
332
+ messageBox.show();
333
+ messageBox.find("button").click(function(){
334
+ ajaxCloseAlert(messageBox);
335
+ });
336
+
337
+ //if timeout is passed the box will disappear when the time is up
338
+ if (!isBlank(timeout)) {
339
+ setTimeout(function(){ ajaxCloseAlert()}, timeout);
340
+ }
341
+ }
342
+
343
+ function ajaxCloseAlert(messageBox) {
344
+ var messageBox = messageBox || $(".ajaxAlert");
345
+ messageBox.find(".ajaxAlertMessage").text('');
346
+ messageBox.hide();
347
+ }
348
+
349
+ // global helper function to validate if a variable is null or empty or undefined
350
+ function isNullOrUndefined(value) {
351
+ if (value == undefined || value == null) {
352
+ return true;
353
+ }
354
+ return false;
355
+ }
356
+
357
+ function isBlank(value) {
358
+ if (isNullOrUndefined(value)) {
359
+ return true;
360
+ }
361
+
362
+ if (jQuery.type(value) === "string" && value.trim().length == 0) {
363
+ return true;
364
+ } else if (jQuery.type(value) === "array" && value.length == 0) {
365
+ return true;
366
+ } else if (jQuery.type(value) === "object" && jQuery.isEmptyObject(value)) {
367
+ return true;
368
+ } else {
369
+ return false;
370
+ }
371
+ }
372
+
373
+ // this function set popover for all tags that have class object-id-popover
374
+ // attributes:
375
+ // data-id = content of the popover,object id; required
376
+ // title = title of the popover; not required
377
+ // id = (must be {{id}}-popover) used to close popover when the copy image is clicked; if present; if not present a timeout of 5s will apply; not required
378
+ function setObjectIdPopover(){
379
+ $(".object-id-popover").each(function(idx, e){
380
+ $(this).popover('destroy');
381
+ $(this).off("shown.bs.popover");
382
+ $(this).data("index", idx);
383
+
384
+ $(this).popover({
385
+ html: true,
386
+ content: function() {
387
+ var template = '<div class="{{id}}-content" >' +
388
+ '{{id}}&emsp;<i id="{{id}}-copy" class="fa fa-clipboard copy-icon" aria-hidden="true"></i> ' +
389
+ '</div>';
390
+
391
+ var popover_html = Mustache.render( template , { id: $(this).data("id") });
392
+ return popover_html;
393
+ },
394
+ container: 'body',
395
+ trigger: 'hover',
396
+ delay: { "show": 100, "hide": 4000 }
397
+ });
398
+
399
+ $(this).on("show.bs.popover", function(e) {
400
+ var currentPopoverIndex = $(this).data('index');
401
+ $(".object-id-popover").each(function(idx, e){
402
+ var index = $(this).data('index');
403
+
404
+ if (currentPopoverIndex != index) {
405
+ $(this).popover('hide');
406
+ }
407
+ });
408
+ });
409
+
410
+ $(this).on("shown.bs.popover", function(e) {
411
+ var objectId = $(this).data('id');
412
+ var copyIdImg = $("#" + objectId + "-copy");
413
+
414
+ copyIdImg.data("popover",$(this).attr("id"));
415
+ copyIdImg.click(function(e){
416
+ var id = ($(this).attr("id")).replace('-copy','');
417
+ navigator.clipboard.writeText(id);
418
+ ajaxInfoAlert("Id [" + id + "] was copied into the clipboard!", 4000);
419
+
420
+ if (!isBlank(popover)) {
421
+ popover.popover('hide');
422
+ }
423
+
424
+ });
425
+
426
+ });
427
+
428
+ });
429
+
430
+ // close all object id popover on modal show
431
+ $(".modal").on('show.bs.modal',function(e){
432
+ $(".object-id-popover").each(function(idx, e) {
433
+ $(this).popover('destroy');
434
+ });
435
+ });
436
+
437
+ // check if object id must be restored
438
+ $(".modal").on('hide.bs.modal',function(e){
439
+ setObjectIdPopover();
440
+ });
441
+ }
@@ -0,0 +1,23 @@
1
+ /*
2
+ * This is a manifest file that'll automatically include all the stylesheets available in this directory
3
+ * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
4
+ * the top of the compiled file, but it's generally better to create a new file per style scope.
5
+ *= require_self
6
+ *= require jquery-ui/autocomplete
7
+ *= require bootstrap-datepicker3
8
+ *= require kaui/account.css
9
+ *= require kaui/audit.css
10
+ *= require kaui/common.css
11
+ *= require kaui/datatable.css
12
+ *= require kaui/header.css
13
+ *= require kaui/home.css
14
+ *= require kaui/invoice.css
15
+ *= require kaui/overdue.css
16
+ *= require kaui/payment.css
17
+ *= require kaui/subscription.css
18
+ *= require kaui/tags.css
19
+ *= require kaui/timeline.css
20
+ *= require kaui/tooltip.css
21
+ *= require kaui/kaui.css
22
+ *= require assets/common
23
+ */
@@ -0,0 +1,34 @@
1
+ h1 span.account-child-label {
2
+ float: right; }
3
+
4
+ .account-child-label {
5
+ color: white !important; }
6
+
7
+ .naked {
8
+ background-color: transparent;
9
+ color: #00919d;
10
+ padding: 0;
11
+ font-size: inherit; }
12
+
13
+ .naked:hover {
14
+ background-color: transparent;
15
+ color: #2a6496; }
16
+
17
+ .title-nav-area .container p {
18
+ padding-left: 20px;
19
+ padding-right: 20px; }
20
+ .title-nav-area .container a {
21
+ max-width: 125px;
22
+ min-width: 90px;
23
+ padding: 12px 12px;
24
+ text-align: center; }
25
+ .title-nav-area .container span.label-danger {
26
+ margin: 8px; }
27
+
28
+ .form-force-inline {
29
+ display: inline; }
30
+
31
+ .form-right {
32
+ float: right; }
33
+
34
+ /*# sourceMappingURL=account.css.map */
@@ -0,0 +1,19 @@
1
+ #showHistoryModal #templatesPlaceHolder {
2
+ display: flex; }
3
+ #showHistoryModal #templatesPlaceHolder .panel {
4
+ margin-left: 5px; }
5
+ #showHistoryModal #templatesPlaceHolder .panel .panel-heading {
6
+ white-space: nowrap; }
7
+ #showHistoryModal #templatesPlaceHolder .list-group-item {
8
+ padding: 5px;
9
+ min-height: 32px;
10
+ overflow-x: hidden;
11
+ white-space: nowrap; }
12
+ #showHistoryModal #templatesPlaceHolder #templateFieldsPlaceHolder .list-group-item span {
13
+ text-transform: capitalize;
14
+ font-weight: bold; }
15
+ #showHistoryModal #templatesPlaceHolder #templatePlaceHolder {
16
+ display: flex;
17
+ overflow-x: auto; }
18
+
19
+ /*# sourceMappingURL=audit.css.map */