kaui 4.0.4 → 4.0.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 44468e809ef2b1ffd8115e0b54664822a212fc2ec26ae6513d8b64135f6de48f
4
- data.tar.gz: 7ceff36da85b32040813f3101246588d5c9cf07a7893297ac1df44d0462b25b2
3
+ metadata.gz: 68c8619a8002b5eccb52c3e514b3eaa09c6360c76fb7655305ef38d8a8bd9389
4
+ data.tar.gz: 2558a2c5362f1547e269bcae07aff1b533854c8dbcead9d81e278f379a62302e
5
5
  SHA512:
6
- metadata.gz: b0949ac7f3c9054757e5b7d5ea33867aba33738d185071917127032ac10293fc845b2da1dec911ca7d02ce0a8500ee7c95309264b3b05936e0eaf59e7e84d5c8
7
- data.tar.gz: 5d6fcb261e749b7cc6d7c97782b3a78cf917acca0369c055515c18f34f514d739e04062755e669f859be2538d09da2a65d3f5fa1b6ab5a4f8c3e10b39f77a308
6
+ metadata.gz: ab1dec602fc6943ce1994f7c080ab659e3b40568855ce480237760da4c983780a9e17b30ab2843925adcb29e85119606b59b6cd0bbb26ffdf708ba1f4c99abdd
7
+ data.tar.gz: fbbf245fd6e028b9d898b4bfe662202222fbd9bc2f0818fc8b582dfb8401ad343a12c8aa86a46044b846866c8f3b76071d7282b2a52cfc77ebe69f4332df4ebb
@@ -14,7 +14,7 @@ module Kaui
14
14
  @max_records = {}
15
15
  %w[account payment invoice].each do |type|
16
16
  model = "Kaui::#{type.capitalize}".constantize
17
- @max_records[type.to_sym] = model.list_or_search(nil, 0, 0, options_for_klient).pagination_max_nb_records || 0
17
+ @max_records[type.to_sym] = model.list_or_search(nil, 0, 0, options_for_klient).pagination_max_nb_records
18
18
  end
19
19
  end
20
20
 
@@ -36,6 +36,15 @@ module Kaui
36
36
  Kaui::Invoice.list_or_search(query_string, 0, MAXIMUM_NUMBER_OF_RECORDS_DOWNLOAD, options_for_klient.merge(params: kb_params))
37
37
  end
38
38
 
39
+ if start_date && end_date
40
+ invoices = invoices.select do |invoice|
41
+ start_date_parsed = Date.parse(start_date)
42
+ end_date_parsed = Date.parse(end_date)
43
+ invoice_date = Date.parse(invoice.invoice_date)
44
+ invoice_date.between?(start_date_parsed, end_date_parsed)
45
+ end
46
+ end
47
+
39
48
  csv_string = CSV.generate(headers: true) do |csv|
40
49
  csv << columns
41
50
 
@@ -24,6 +24,8 @@ module Kaui
24
24
  '/kenui'
25
25
  when /payment-test/
26
26
  '/payment_test'
27
+ when /aviate/
28
+ '/aviate'
27
29
  else
28
30
  "/#{plugin_key}"
29
31
  end
@@ -43,7 +43,7 @@
43
43
  <path d="M2.5 8.3335H17.5" stroke="#A4A7AE" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
44
44
  </svg>
45
45
  </label>
46
- <input type="text" class="form-control center-input" id="startDate" placeholder="All Accounts" name="startDate">
46
+ <input type="text" class="form-control center-input" id="startDate" placeholder="All Account Timelines" name="startDate">
47
47
  <div id="dash" class="dash">–</div>
48
48
  <input type="text" class="form-control right-input" id="endDate" placeholder="" name="endDate">
49
49
  <div id="toggle-wrapper" class="position-absolute" style="width: 100%; height: 100%;" onclick="document.getElementById('single-toggle').click()"></div>
@@ -117,12 +117,10 @@
117
117
  <% end %>
118
118
  </div>
119
119
 
120
- <% if can? :trigger, Kaui::Invoice %>
121
- <div class="info-item">
122
- <b>Next invoice date</b>
123
- <p id='next-invoice-date'>N/A</p>
124
- </div>
125
- <% end %>
120
+ <div class="info-item">
121
+ <b>Next invoice date</b>
122
+ <p id='next-invoice-date'>N/A</p>
123
+ </div>
126
124
  </div>
127
125
 
128
126
  <!-- Right Column -->
@@ -60,23 +60,12 @@
60
60
  <td><%= link_to u.kb_username, admin_allowed_user_path(u.id) %></td>
61
61
  <td><%= u.description %></td>
62
62
  <td class="text-end">
63
-
64
-
65
- <%= render "kaui/components/button/button", {
66
- label: 'Delete',
67
- variant: "outline-secondary d-inline-flex align-items-center gap-1",
68
- type: "button",
69
- html_class: "kaui-button delete-button custom-hover",
70
- html_options: {
71
- data: {
72
- confirm: "Are you sure?",
73
- method: "delete",
74
- turbo: false,
75
- "url": kaui_engine.admin_allowed_user_path(u.id)
76
- }
77
- }
78
- } %>
79
- <%= link_to kaui_engine.edit_admin_allowed_user_path(u.id), :class => '' do %>
63
+ <%= form_tag kaui_engine.admin_allowed_user_path(u.id), method: :delete, class: 'd-inline', onsubmit: "return confirm('Are you sure?');" do %>
64
+ <%= button_tag type: 'submit', class: 'btn btn-outline-secondary d-inline-flex align-items-center gap-1 kaui-button delete-button custom-hover' do %>
65
+ Delete
66
+ <% end %>
67
+ <% end %>
68
+ <%= link_to kaui_engine.edit_admin_allowed_user_path(u.id), class: 'text-decoration-none' do %>
80
69
  <%= render "kaui/components/button/button", {
81
70
  label: "Edit",
82
71
  variant: "outline-secondary d-inline-flex align-items-center gap-1",
@@ -154,6 +143,8 @@
154
143
  $header.find('.sort-' + direction).addClass('active');
155
144
  }
156
145
 
146
+ } catch (e) {
147
+ console.error('Error initializing DataTable:', e);
157
148
  }
158
149
  }, 100);
159
150
  });
@@ -246,6 +246,8 @@ function switch_basic_config() {
246
246
  $(document).ready(function() {
247
247
  switch_basic_config();
248
248
 
249
+ // jQuery UI autocomplete interferes with HTML5 validation
250
+ // So we keep the custom JS validation
249
251
  $('#simple_plan_product_name').autocomplete({
250
252
  source: function(query, process) {
251
253
  process(known_products());
@@ -261,8 +263,72 @@ $(document).ready(function() {
261
263
  $('#simple_plan_product_name').on('mouseleave', function() {
262
264
  recompute_available_base_products_for_ao();
263
265
  });
266
+
267
+ // Custom validation since HTML5 validation is not working
268
+ // (possibly due to jQuery autocomplete or other JavaScript interference)
269
+ $('#catalog_simple form').on('submit', function(e) {
270
+ var isValid = true;
271
+ var pattern = /^[a-zA-Z_][\w\.-]*$/;
272
+
273
+ // Validate Product Name
274
+ var productName = $('#simple_plan_product_name').val().trim();
275
+ var productNameField = $('#simple_plan_product_name');
276
+
277
+ if (productName === '') {
278
+ showError(productNameField, 'Product Name is required');
279
+ isValid = false;
280
+ } else if (!pattern.test(productName)) {
281
+ showError(productNameField, 'Product Name must start with a letter or underscore, and can only contain letters, digits, underscores, hyphens, and periods');
282
+ isValid = false;
283
+ } else {
284
+ clearError(productNameField);
285
+ }
286
+
287
+ // Validate Plan Name
288
+ var planName = $('#simple_plan_plan_id').val().trim();
289
+ var planNameField = $('#simple_plan_plan_id');
290
+
291
+ if (planName === '') {
292
+ showError(planNameField, 'Plan Name is required');
293
+ isValid = false;
294
+ } else if (!pattern.test(planName)) {
295
+ showError(planNameField, 'Plan Name must start with a letter or underscore, and can only contain letters, digits, underscores, hyphens, and periods');
296
+ isValid = false;
297
+ } else {
298
+ clearError(planNameField);
299
+ }
300
+
301
+ if (!isValid) {
302
+ e.preventDefault();
303
+ e.stopPropagation();
304
+ // Scroll to first error
305
+ $('.error-message:first').get(0)?.scrollIntoView({ behavior: 'smooth', block: 'center' });
306
+ return false;
307
+ }
308
+
309
+ return true;
310
+ });
311
+
312
+ // Clear errors on input
313
+ $('#simple_plan_product_name, #simple_plan_plan_id').on('input', function() {
314
+ clearError($(this));
315
+ });
264
316
  });
265
317
 
318
+ function showError(field, message) {
319
+ clearError(field);
320
+ field.addClass('error-field');
321
+ field.css('border-color', '#dc3545');
322
+ var errorDiv = $('<div class="error-message" style="color: #dc3545; font-size: 0.875rem; margin-top: 0.25rem;"></div>').text(message);
323
+ field.parent().append(errorDiv);
324
+ }
325
+
326
+ function clearError(field) {
327
+ field.removeClass('error-field');
328
+ field.css('border-color', '');
329
+ field.parent().find('.error-message').remove();
330
+ }
331
+
266
332
  document.querySelectorAll('.toggle-option').forEach(el => {
267
333
  el.addEventListener('click', () => {
268
334
  document.querySelectorAll('.toggle-option').forEach(opt => opt.classList.remove('active-btn'));
@@ -43,7 +43,7 @@
43
43
  <path d="M2.5 8.3335H17.5" stroke="#A4A7AE" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
44
44
  </svg>
45
45
  </label>
46
- <input type="text" class="form-control center-input" id="startDate" placeholder="All Accounts" name="startDate">
46
+ <input type="text" class="form-control center-input" id="startDate" placeholder="All Logs" name="startDate">
47
47
  <div id="dash" class="dash">–</div>
48
48
  <input type="text" class="form-control right-input" id="endDate" placeholder="" name="endDate">
49
49
  <div id="toggle-wrapper" class="position-absolute" style="width: 100%; height: 100%;" onclick="document.getElementById('single-toggle').click()"></div>
@@ -1,3 +1,4 @@
1
+ <% count_text = count.nil? ? "20k+" : count.to_i %>
1
2
  <div class="col-md-4">
2
3
  <div class="dashboard-card border rounded-4 d-flex flex-column justify-content-between h-100">
3
4
  <div class="d-flex px-4 py-3 align-items-center gap-3">
@@ -6,7 +7,7 @@
6
7
  </div>
7
8
  <div>
8
9
  <h6 class="mb-0 fw-600 text-black-900"><%= title %></h6>
9
- <p class="text-muted fw-normal text-tertiary small mb-0"><%= count %></p>
10
+ <p class="text-muted fw-normal text-tertiary small mb-0"><%= count_text %></p>
10
11
  </div>
11
12
  </div>
12
13
  <div class="w-full dashboard-card-divider"></div>
@@ -91,7 +91,7 @@
91
91
  <path d="M2.5 8.3335H17.5" stroke="#A4A7AE" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
92
92
  </svg>
93
93
  </label>
94
- <input type="text" class="form-control center-input" id="startDate" placeholder="All Accounts" name="startDate">
94
+ <input type="text" class="form-control center-input" id="startDate" placeholder="All Invoices" name="startDate">
95
95
  <div id="dash" class="dash">–</div>
96
96
  <input type="text" class="form-control right-input" id="endDate" placeholder="" name="endDate">
97
97
  <div id="toggle-wrapper" class="position-absolute" style="width: 100%; height: 100%;" onclick="document.getElementById('single-toggle').click()"></div>
@@ -90,7 +90,7 @@
90
90
  <path d="M2.5 8.3335H17.5" stroke="#A4A7AE" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
91
91
  </svg>
92
92
  </label>
93
- <input type="text" class="form-control center-input" id="startDate" placeholder="All Accounts" name="startDate">
93
+ <input type="text" class="form-control center-input" id="startDate" placeholder="All Payments" name="startDate">
94
94
  <div id="dash" class="dash">–</div>
95
95
  <input type="text" class="form-control right-input" id="endDate" placeholder="" name="endDate">
96
96
  <div id="toggle-wrapper" class="position-absolute" style="width: 100%; height: 100%;" onclick="document.getElementById('single-toggle').click()"></div>
data/lib/kaui/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Kaui
4
- VERSION = '4.0.4'
4
+ VERSION = '4.0.5'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kaui
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.4
4
+ version: 4.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kill Bill core team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-12-09 00:00:00.000000000 Z
11
+ date: 2025-12-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack