kaui 3.0.1 → 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
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 */