kaui 4.0.14 → 4.0.16
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 +4 -4
- data/app/assets/javascripts/kaui/multi_functions_bar_utils.js +55 -13
- data/app/assets/stylesheets/kaui/account.css +170 -2
- data/app/assets/stylesheets/kaui/common.css +243 -0
- data/app/assets/stylesheets/kaui/invoice.css +148 -2
- data/app/assets/stylesheets/kaui/payment.css +148 -2
- data/app/assets/stylesheets/kaui/queues.css +176 -88
- data/app/assets/stylesheets/kaui/tenants.css +2 -1
- data/app/controllers/kaui/admin_tenants_controller.rb +25 -0
- data/app/controllers/kaui/engine_controller.rb +2 -1
- data/app/controllers/kaui/engine_controller_util.rb +26 -2
- data/app/controllers/kaui/invoices_controller.rb +3 -3
- data/app/controllers/kaui/payments_controller.rb +3 -3
- data/app/views/kaui/accounts/_account_filterbar.html.erb +10 -212
- data/app/views/kaui/accounts/index.html.erb +9 -2
- data/app/views/kaui/admin_tenants/_show_overdue.erb +11 -0
- data/app/views/kaui/bundles/_bundle_filterbar.html.erb +56 -39
- data/app/views/kaui/invoices/_invoice_filterbar.html.erb +15 -226
- data/app/views/kaui/invoices/index.html.erb +3 -3
- data/app/views/kaui/payments/_payment_filterbar.html.erb +15 -212
- data/app/views/kaui/queues/index.html.erb +212 -191
- data/app/views/kaui/shared/_advanced_search_filterbar.html.erb +253 -0
- data/config/locales/en.yml +32 -0
- data/config/routes.rb +2 -1
- data/lib/kaui/error_handler.rb +2 -1
- data/lib/kaui/version.rb +1 -1
- metadata +3 -2
|
@@ -63,6 +63,7 @@ module Kaui
|
|
|
63
63
|
|
|
64
64
|
@overdue = flash[:overdue_deleted] ? nil : wait(fetch_overdue)
|
|
65
65
|
@overdue_xml = flash[:overdue_deleted] ? nil : wait(fetch_overdue_xml)
|
|
66
|
+
@overdue_config_exists = @overdue_xml.present? || (@overdue&.overdue_states.present? && !@overdue.has_states)
|
|
66
67
|
@tenant_plugin_config = begin
|
|
67
68
|
wait(fetch_tenant_plugin_config)
|
|
68
69
|
rescue StandardError
|
|
@@ -288,13 +289,19 @@ module Kaui
|
|
|
288
289
|
options = tenant_options_for_client
|
|
289
290
|
options[:api_key] = @tenant.api_key
|
|
290
291
|
options[:api_secret] = @tenant.api_secret
|
|
292
|
+
@overdue_config_exists = false
|
|
291
293
|
begin
|
|
292
294
|
@overdue = Kaui::Overdue.get_overdue_json(options)
|
|
293
295
|
@overdue_corrupted = false
|
|
296
|
+
@overdue_config_exists = @overdue.overdue_states.present? && !@overdue.has_states
|
|
297
|
+
rescue KillBillClient::API::NotFound
|
|
298
|
+
@overdue = KillBillClient::Model::Overdue.new.tap { |o| o.overdue_states = [] }
|
|
299
|
+
@overdue_corrupted = false
|
|
294
300
|
rescue StandardError => e
|
|
295
301
|
Rails.logger.warn("Failed to load overdue configuration for tenant #{@tenant.id}: #{e.class}: #{e.message}")
|
|
296
302
|
@overdue = KillBillClient::Model::Overdue.new.tap { |o| o.overdue_states = [] }
|
|
297
303
|
@overdue_corrupted = true
|
|
304
|
+
@overdue_config_exists = true
|
|
298
305
|
flash.now[:warning] = 'The existing overdue configuration is corrupted and cannot be loaded. Use the XML upload below to replace it with a valid configuration.'
|
|
299
306
|
end
|
|
300
307
|
end
|
|
@@ -342,6 +349,24 @@ module Kaui
|
|
|
342
349
|
redirect_to admin_tenant_path(current_tenant.id, active_tab: 'OverdueShow'), notice: I18n.t('flashes.notices.overdue_uploaded_successfully')
|
|
343
350
|
end
|
|
344
351
|
|
|
352
|
+
def delete_overdue_config
|
|
353
|
+
current_tenant = safely_find_tenant_by_id(params[:id])
|
|
354
|
+
|
|
355
|
+
options = tenant_options_for_client
|
|
356
|
+
options[:api_key] = current_tenant.api_key
|
|
357
|
+
options[:api_secret] = current_tenant.api_secret
|
|
358
|
+
|
|
359
|
+
begin
|
|
360
|
+
Kaui::AdminTenant.delete_tenant_user_key_value('OVERDUE_CONFIG', options[:username], nil, comment, options)
|
|
361
|
+
rescue StandardError => e
|
|
362
|
+
flash[:error] = "Failed to delete overdue config: #{as_string(e)}"
|
|
363
|
+
redirect_to admin_tenant_new_overdue_config_path(id: current_tenant.id) and return
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
flash[:overdue_deleted] = true
|
|
367
|
+
redirect_to admin_tenant_path(current_tenant.id, active_tab: 'OverdueShow'), notice: I18n.t('flashes.notices.overdue_deleted_successfully')
|
|
368
|
+
end
|
|
369
|
+
|
|
345
370
|
def upload_invoice_template
|
|
346
371
|
current_tenant = safely_find_tenant_by_id(params[:id])
|
|
347
372
|
|
|
@@ -38,7 +38,8 @@ class Kaui::EngineController < ApplicationController
|
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
def populate_account_details
|
|
41
|
-
|
|
41
|
+
account_id = scalar_account_id_param
|
|
42
|
+
@account ||= account_id.present? ? Kaui::Account.find_by_id(account_id, false, false, options_for_klient) : Kaui::Account.new
|
|
42
43
|
end
|
|
43
44
|
|
|
44
45
|
def retrieve_tenants_for_current_user
|
|
@@ -37,8 +37,8 @@ module Kaui
|
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
def paginate(searcher, data_extractor, formatter, table_default_columns = [])
|
|
40
|
-
search_key = (params[:search] || {})[:value].presence
|
|
41
|
-
advance_search_query = params[:advance_search_query].presence
|
|
40
|
+
search_key = normalize_search_key((params[:search] || {})[:value]).presence
|
|
41
|
+
advance_search_query = normalize_search_key(params[:advance_search_query]).presence
|
|
42
42
|
|
|
43
43
|
search_key = advance_search_query if advance_search_query
|
|
44
44
|
search_key = handle_balance_search(search_key) if search_key.present?
|
|
@@ -84,6 +84,30 @@ module Kaui
|
|
|
84
84
|
end
|
|
85
85
|
end
|
|
86
86
|
|
|
87
|
+
def advanced_search_query?(search_key)
|
|
88
|
+
search_key.to_s.include?('_q')
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def scalar_account_id_param
|
|
92
|
+
path_account_id = request.path_parameters[:account_id].presence
|
|
93
|
+
return path_account_id if path_account_id.present?
|
|
94
|
+
|
|
95
|
+
account_id = params[:account_id]
|
|
96
|
+
account_id if account_id.is_a?(String) || account_id.is_a?(Numeric)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def normalize_search_key(search_key)
|
|
100
|
+
return if search_key.blank?
|
|
101
|
+
|
|
102
|
+
if search_key.respond_to?(:to_unsafe_h)
|
|
103
|
+
search_key.to_unsafe_h.to_query
|
|
104
|
+
elsif search_key.is_a?(Hash)
|
|
105
|
+
search_key.to_query
|
|
106
|
+
else
|
|
107
|
+
search_key
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
87
111
|
def promise(&)
|
|
88
112
|
# Evaluation starts immediately
|
|
89
113
|
::Concurrent::Promises.future do
|
|
@@ -4,7 +4,7 @@ require 'csv'
|
|
|
4
4
|
module Kaui
|
|
5
5
|
class InvoicesController < Kaui::EngineController
|
|
6
6
|
def index
|
|
7
|
-
@search_query =
|
|
7
|
+
@search_query = scalar_account_id_param
|
|
8
8
|
@advance_search_query = params[:q] || request.query_string
|
|
9
9
|
@ordering = params[:ordering] || 'desc'
|
|
10
10
|
@offset = params[:offset] || 0
|
|
@@ -15,7 +15,7 @@ module Kaui
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def download
|
|
18
|
-
account_id =
|
|
18
|
+
account_id = scalar_account_id_param
|
|
19
19
|
start_date = params[:startDate]
|
|
20
20
|
end_date = params[:endDate]
|
|
21
21
|
all_fields_checked = params[:allFieldsChecked] == 'true'
|
|
@@ -60,7 +60,7 @@ module Kaui
|
|
|
60
60
|
|
|
61
61
|
searcher = lambda do |search_key, offset, limit|
|
|
62
62
|
account = begin
|
|
63
|
-
Kaui::Account.find_by_id_or_key(search_key, false, false, cached_options_for_klient)
|
|
63
|
+
Kaui::Account.find_by_id_or_key(search_key, false, false, cached_options_for_klient) unless advanced_search_query?(search_key)
|
|
64
64
|
rescue StandardError
|
|
65
65
|
nil
|
|
66
66
|
end
|
|
@@ -5,7 +5,7 @@ require 'csv'
|
|
|
5
5
|
module Kaui
|
|
6
6
|
class PaymentsController < Kaui::EngineController
|
|
7
7
|
def index
|
|
8
|
-
@search_query = params[:q] ||
|
|
8
|
+
@search_query = params[:q] || scalar_account_id_param
|
|
9
9
|
@advance_search_query = params[:q] || request.query_string
|
|
10
10
|
@ordering = params[:ordering] || (@search_query.blank? ? 'desc' : 'asc')
|
|
11
11
|
@offset = params[:offset] || 0
|
|
@@ -16,7 +16,7 @@ module Kaui
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def download
|
|
19
|
-
account_id =
|
|
19
|
+
account_id = scalar_account_id_param
|
|
20
20
|
start_date = params[:startDate]
|
|
21
21
|
end_date = params[:endDate]
|
|
22
22
|
all_fields_checked = params[:allFieldsChecked] == 'true'
|
|
@@ -104,7 +104,7 @@ module Kaui
|
|
|
104
104
|
payments = Kaui::Payment.list_or_search(payment_state, offset, limit, options_for_klient)
|
|
105
105
|
else
|
|
106
106
|
account = begin
|
|
107
|
-
Kaui::Account.find_by_id_or_key(search_key, false, false, options_for_klient)
|
|
107
|
+
Kaui::Account.find_by_id_or_key(search_key, false, false, options_for_klient) unless advanced_search_query?(search_key)
|
|
108
108
|
rescue StandardError
|
|
109
109
|
nil
|
|
110
110
|
end
|
|
@@ -1,212 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
<button type="button" class="close close-button custom-hover" data-bs-dismiss="modal" aria-label="Close">
|
|
12
|
-
<span aria-hidden="true">
|
|
13
|
-
<%= image_tag("kaui/modal/close.svg", width: 20, height: 20) %>
|
|
14
|
-
</span>
|
|
15
|
-
</button>
|
|
16
|
-
</div>
|
|
17
|
-
<div class="modal-body">
|
|
18
|
-
<form id="advanceSearchForm">
|
|
19
|
-
<div class="form-group d-flex align-items-center">
|
|
20
|
-
<label for="searchFieldSelect" class="mr-2 field-label" style="width: 30%;">Search Field</label>
|
|
21
|
-
<select id="searchFieldSelect" class="form-control mr-2">
|
|
22
|
-
<% @search_fields.each do |value, title| %>
|
|
23
|
-
<option value="<%= value %>"><%= title %></option>
|
|
24
|
-
<% end %>
|
|
25
|
-
</select>
|
|
26
|
-
<button type="button" class="border-button custom-hover" id="addSearchField">
|
|
27
|
-
<%= image_tag("kaui/modal/plus.svg", width: 16, height: 16) %>
|
|
28
|
-
</button>
|
|
29
|
-
</div>
|
|
30
|
-
<div id="search-fields-container">
|
|
31
|
-
</div>
|
|
32
|
-
<div id="save-search-container" style="display: none;">
|
|
33
|
-
<hr class="mt-4 mb-3">
|
|
34
|
-
<div class="form-group d-flex align-items-center mb-0">
|
|
35
|
-
<label for="savedSearchName" class="mr-2 field-label" style="width: 30%;">Save As Name</label>
|
|
36
|
-
<input type="text" id="savedSearchName" class="form-control flex-grow-1" placeholder="Enter a name for this search...">
|
|
37
|
-
</div>
|
|
38
|
-
</div>
|
|
39
|
-
</form>
|
|
40
|
-
</div>
|
|
41
|
-
<div class="modal-footer">
|
|
42
|
-
<%= render "kaui/components/button/button", {
|
|
43
|
-
label: 'Save Search As...',
|
|
44
|
-
variant: "outline-secondary d-inline-flex align-items-center gap-1",
|
|
45
|
-
type: "button",
|
|
46
|
-
html_class: "kaui-button custom-hover",
|
|
47
|
-
html_options: {
|
|
48
|
-
id: "saveAdvanceSearch"
|
|
49
|
-
}
|
|
50
|
-
} %>
|
|
51
|
-
<%= render "kaui/components/button/button", {
|
|
52
|
-
label: 'Clear Search',
|
|
53
|
-
variant: "outline-secondary d-inline-flex align-items-center gap-1",
|
|
54
|
-
type: "button",
|
|
55
|
-
html_class: "kaui-button custom-hover",
|
|
56
|
-
html_options: {
|
|
57
|
-
id: "clearAdvanceSearch"
|
|
58
|
-
}
|
|
59
|
-
} %>
|
|
60
|
-
<%= render "kaui/components/button/button", {
|
|
61
|
-
label: 'Apply Search',
|
|
62
|
-
variant: "outline-secondary d-inline-flex align-items-center gap-1",
|
|
63
|
-
type: "button",
|
|
64
|
-
html_class: "kaui-dropdown custom-hover",
|
|
65
|
-
html_options: {
|
|
66
|
-
id: "applyAdvanceSearch"
|
|
67
|
-
}
|
|
68
|
-
} %>
|
|
69
|
-
</div>
|
|
70
|
-
</div>
|
|
71
|
-
</div>
|
|
72
|
-
</div>
|
|
73
|
-
|
|
74
|
-
<template id="search-field-template" class="kaui-accounts-index-filterbar">
|
|
75
|
-
<div class="form-group row align-items-center justify-content-between search-field">
|
|
76
|
-
<label class="col-sm-3 col-form-label search-field-label"></label>
|
|
77
|
-
<div class="col-sm-4">
|
|
78
|
-
<select class="form-control search-field-filter">
|
|
79
|
-
<option value="eq">Equals</option>
|
|
80
|
-
<option value="neq">Not Equals</option>
|
|
81
|
-
<option value="gt">Greater Than</option>
|
|
82
|
-
<option value="gte">Greater Than Or Equal</option>
|
|
83
|
-
<option value="lt">Less Than</option>
|
|
84
|
-
<option value="lte">Less Than Or Equal</option>
|
|
85
|
-
<option value="like">Like</option>
|
|
86
|
-
</select>
|
|
87
|
-
</div>
|
|
88
|
-
<div class="col-sm-4">
|
|
89
|
-
<input type="text" class="form-control search-field-value">
|
|
90
|
-
</div>
|
|
91
|
-
<button type="button" class="button custom-hover" id="remove-search-field">
|
|
92
|
-
<%= image_tag("kaui/modal/red-close.svg", width: 16, height: 16) %>
|
|
93
|
-
</button>
|
|
94
|
-
</div>
|
|
95
|
-
</template>
|
|
96
|
-
|
|
97
|
-
<%= javascript_tag do %>
|
|
98
|
-
$(document).ready(function() {
|
|
99
|
-
|
|
100
|
-
populateSearchLabelsFromUrl();
|
|
101
|
-
var dateFields = ['Created date', 'Updated date', 'Reference time'];
|
|
102
|
-
// Handle the "Add" button click to add new search fields
|
|
103
|
-
$('#addSearchField').on('click', function() {
|
|
104
|
-
var selectedField = $('#searchFieldSelect option:selected').text();
|
|
105
|
-
var template = document.getElementById('search-field-template').content.cloneNode(true);
|
|
106
|
-
|
|
107
|
-
// Set the label and input names based on the selected field
|
|
108
|
-
template.querySelector('.search-field-label').textContent = selectedField.replace(/([A-Z])/g, ' $1').trim();
|
|
109
|
-
template.querySelector('.search-field-filter').name = selectedField + 'Filter';
|
|
110
|
-
|
|
111
|
-
// Check if the field should use a date input
|
|
112
|
-
if (dateFields.includes(selectedField)) {
|
|
113
|
-
template.querySelector('.search-field-value').type = 'date';
|
|
114
|
-
} else {
|
|
115
|
-
template.querySelector('.search-field-value').type = 'text';
|
|
116
|
-
}
|
|
117
|
-
template.querySelector('.search-field-value').name = selectedField;
|
|
118
|
-
|
|
119
|
-
// Append the new search field to the container
|
|
120
|
-
document.getElementById('search-fields-container').appendChild(template);
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
// Handle the "Apply Search" button click inside the modal
|
|
124
|
-
$('#applyAdvanceSearch').on('click', function() {
|
|
125
|
-
var searchFields = $('.search-field');
|
|
126
|
-
var searchLabelsContainer = $('#search-labels-container');
|
|
127
|
-
searchLabelsContainer.empty();
|
|
128
|
-
|
|
129
|
-
// Validate that at least one search field has a value
|
|
130
|
-
var hasValue = false;
|
|
131
|
-
searchFields.each(function() {
|
|
132
|
-
var value = $(this).find('.search-field-value').val().trim();
|
|
133
|
-
if (value !== '') {
|
|
134
|
-
hasValue = true;
|
|
135
|
-
return false; // Break the loop
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
// If no search field has a value, show an alert and prevent search
|
|
140
|
-
if (!hasValue) {
|
|
141
|
-
alert('Please enter a value for at least one search field.');
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
var table = $('#accounts-table').DataTable();
|
|
146
|
-
table.off('preXhr.dt.filter');
|
|
147
|
-
table.on('preXhr.dt.filter', function(e, settings, data) {
|
|
148
|
-
data.search.value = searchQuery('');
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
// Update the DataTables ajax URL with the new search parameters
|
|
152
|
-
var searchParams = searchQuery('');
|
|
153
|
-
var ajaxUrl = "<%= accounts_pagination_path(:ordering => @ordering, :format => :json) %>";
|
|
154
|
-
if (searchParams) {
|
|
155
|
-
ajaxUrl += (ajaxUrl.includes('?') ? '&' : '?') + searchParams;
|
|
156
|
-
}
|
|
157
|
-
table.ajax.url(ajaxUrl).load();
|
|
158
|
-
|
|
159
|
-
// Update the URL with the search parameters
|
|
160
|
-
if (searchParams) {
|
|
161
|
-
searchParams = searchParams.replace(/account_id/g, 'ac_id');
|
|
162
|
-
var newUrl = window.location.protocol + "//" + window.location.host + window.location.pathname + '?' + searchParams;
|
|
163
|
-
window.history.pushState({ path: newUrl }, '', newUrl);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
searchFields.each(function() {
|
|
167
|
-
var filter = $(this).find('.search-field-filter option:selected').text().trim();
|
|
168
|
-
var value = $(this).find('.search-field-value').val().trim();
|
|
169
|
-
var columnName = $(this).find('.search-field-filter').attr('name').replace('Filter', '').trim();
|
|
170
|
-
|
|
171
|
-
// Create and append the search label
|
|
172
|
-
if (value !== '') {
|
|
173
|
-
var label = $('<span>', {
|
|
174
|
-
class: 'label label-info d-inline-flex align-items-center gap-2',
|
|
175
|
-
'data-field': columnName,
|
|
176
|
-
'data-filter': filter,
|
|
177
|
-
'data-value': value
|
|
178
|
-
});
|
|
179
|
-
var labelText = $('<span>', { text: columnName + ' [' + filter + '] ' + value });
|
|
180
|
-
var closeIcon = $('<span>', {
|
|
181
|
-
class: 'filter-close-icon',
|
|
182
|
-
style: 'cursor: pointer; margin-left: 5px; display: inline-flex; align-items: center;'
|
|
183
|
-
}).html('<svg width="12" height="12" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M15.8337 4.1665L4.16699 15.8332M4.16699 4.1665L15.8337 15.8332" stroke="#A4A7AE" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>');
|
|
184
|
-
label.append(labelText).append(closeIcon);
|
|
185
|
-
searchLabelsContainer.append(label);
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
$('#advanceSearchModal').modal('hide');
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
// Populate the modal with the current filters when it is shown
|
|
193
|
-
$('#advanceSearchModal').on('show.bs.modal', function() {
|
|
194
|
-
showAdvanceSearchModal();
|
|
195
|
-
$('#search-fields-container .search-field').each(function() {
|
|
196
|
-
var input = $(this).find('.search-field-value');
|
|
197
|
-
if (dateFields.includes(input.attr('name'))) {
|
|
198
|
-
input.attr('type', 'date');
|
|
199
|
-
}
|
|
200
|
-
});
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
$('#clearAdvanceSearch').on('click', function() {
|
|
204
|
-
clearAdvanceSearch();
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
// Handle the remove icon click event to remove search fields
|
|
208
|
-
$('#search-fields-container').on('click', '#remove-search-field', function() {
|
|
209
|
-
$(this).closest('.search-field').remove();
|
|
210
|
-
});
|
|
211
|
-
});
|
|
212
|
-
<% end %>
|
|
1
|
+
<%= render "kaui/shared/advanced_search_filterbar", {
|
|
2
|
+
modal_class: "kaui-accounts-index-filterbar",
|
|
3
|
+
search_fields: @search_fields,
|
|
4
|
+
date_fields: ['Created date', 'Updated date', 'Reference time'],
|
|
5
|
+
number_fields: [],
|
|
6
|
+
table_selector: '#accounts-table',
|
|
7
|
+
pagination_path: accounts_pagination_path(:ordering => @ordering, :format => :json),
|
|
8
|
+
search_query: '',
|
|
9
|
+
balance_notice: false
|
|
10
|
+
} %>
|
|
@@ -103,7 +103,13 @@ $(document).ready(function() {
|
|
|
103
103
|
"serverSide": true,
|
|
104
104
|
"search": {"search": "<%= @search_query %>"},
|
|
105
105
|
"ajax": {
|
|
106
|
-
|
|
106
|
+
type: "POST",
|
|
107
|
+
url: "<%= accounts_pagination_path(:ordering => @ordering, :format => :json) %>",
|
|
108
|
+
headers: {"X-CSRF-Token": $("meta[name='csrf-token']").attr("content")},
|
|
109
|
+
data: function(d) {
|
|
110
|
+
d.advance_search_query = "<%= j(@advance_search_query.to_s) %>";
|
|
111
|
+
return d;
|
|
112
|
+
},
|
|
107
113
|
dataSrc: function(json) {
|
|
108
114
|
var colOrder = table.colReorder.order();
|
|
109
115
|
var reorderedData = json.data.map(function(row) {
|
|
@@ -127,9 +133,10 @@ $(document).ready(function() {
|
|
|
127
133
|
// DataTable request with the correct filters.
|
|
128
134
|
if (window.location.search.includes('_q=1') && '<%= j(@advance_search_query.to_s.strip) %>' === '') {
|
|
129
135
|
var urlSearch = window.location.search.substring(1).replace(/ac_id/g, 'account_id');
|
|
130
|
-
var ajaxUrl = "<%= accounts_pagination_path(:ordering => @ordering, :format => :json) %>"
|
|
136
|
+
var ajaxUrl = "<%= accounts_pagination_path(:ordering => @ordering, :format => :json) %>";
|
|
131
137
|
table.on('preXhr.dt.filter', function(e, settings, data) {
|
|
132
138
|
data.search.value = urlSearch;
|
|
139
|
+
data.advance_search_query = urlSearch;
|
|
133
140
|
});
|
|
134
141
|
table.ajax.url(ajaxUrl).load();
|
|
135
142
|
}
|
|
@@ -6,6 +6,17 @@
|
|
|
6
6
|
<h2>Existing Overdue Config</h2>
|
|
7
7
|
</div>
|
|
8
8
|
<span>
|
|
9
|
+
<% if @overdue_config_exists && can?(:config_upload, Kaui::AdminTenant) %>
|
|
10
|
+
<% overdue_delete_confirmation = t('admin_tenants.delete_overdue_config_confirmation') %>
|
|
11
|
+
<%= link_to kaui_engine.admin_tenant_delete_overdue_config_path(id: @tenant.id), method: :delete, data: { confirm: overdue_delete_confirmation }, class: "text-decoration-none" do %>
|
|
12
|
+
<%= render "kaui/components/button/button", {
|
|
13
|
+
label: "Delete",
|
|
14
|
+
variant: "outline-secondary d-inline-flex align-items-center gap-1",
|
|
15
|
+
type: "button",
|
|
16
|
+
html_class: "kaui-button dots-menu custom-hover",
|
|
17
|
+
} %>
|
|
18
|
+
<% end %>
|
|
19
|
+
<% end %>
|
|
9
20
|
<%= link_to "javascript:void(0);", onclick: "submit_overdue_xml();", class:"text-decoration-none" do %>
|
|
10
21
|
<%= render "kaui/components/button/button", {
|
|
11
22
|
label: "XML View",
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
<div class="modal fade" id="advanceSearchModal" tabindex="-1" role="dialog" aria-labelledby="advanceSearchModalLabel" aria-hidden="true"
|
|
1
|
+
<div class="modal fade kaui-advanced-search-modal" id="advanceSearchModal" tabindex="-1" role="dialog" aria-labelledby="advanceSearchModalLabel" aria-hidden="true"
|
|
2
|
+
data-save-search-label="<%= t('advanced_search.actions.save_search_as') %>"
|
|
3
|
+
data-save-label="<%= t('advanced_search.actions.save') %>"
|
|
4
|
+
data-empty-value-message="<%= t('advanced_search.validation.empty_value') %>"
|
|
5
|
+
data-missing-field-message="<%= t('advanced_search.validation.missing_field') %>">
|
|
2
6
|
<div class="modal-dialog" role="document">
|
|
3
7
|
<div class="modal-content">
|
|
4
8
|
<div class="modal-header">
|
|
@@ -6,9 +10,9 @@
|
|
|
6
10
|
<span class="icon-container">
|
|
7
11
|
<%= image_tag("kaui/modal/search.svg", width: 20, height: 20) %>
|
|
8
12
|
</span>
|
|
9
|
-
|
|
13
|
+
<%= t('advanced_search.title') %>
|
|
10
14
|
</h5>
|
|
11
|
-
<button type="button" class="close close-button custom-hover" data-bs-dismiss="modal" aria-label="
|
|
15
|
+
<button type="button" class="close close-button custom-hover" data-bs-dismiss="modal" aria-label="<%= t('advanced_search.actions.close') %>">
|
|
12
16
|
<span aria-hidden="true">
|
|
13
17
|
<%= image_tag("kaui/modal/close.svg", width: 20, height: 20) %>
|
|
14
18
|
</span>
|
|
@@ -16,49 +20,54 @@
|
|
|
16
20
|
</div>
|
|
17
21
|
<div class="modal-body">
|
|
18
22
|
<form id="advanceSearchForm">
|
|
19
|
-
<div class="
|
|
20
|
-
<
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
<div class="advanced-search-builder">
|
|
24
|
+
<div class="advanced-search-group">
|
|
25
|
+
<div class="advanced-search-query-row">
|
|
26
|
+
<select id="searchFieldSelect" class="form-control" aria-label="<%= t('advanced_search.search_field') %>">
|
|
27
|
+
<option value=""><%= t('advanced_search.select_placeholder') %></option>
|
|
28
|
+
<% Kaui::Bundle::SEARCH_FIELDS.each do |value, title| %>
|
|
29
|
+
<option value="<%= value %>" <%= 'selected' if @search_query.present? && @search_by == value %>><%= title %></option>
|
|
30
|
+
<% end %>
|
|
31
|
+
</select>
|
|
32
|
+
<input type="text" id="bundleSearchValue" class="form-control" aria-label="<%= t('advanced_search.search_value') %>" placeholder="<%= t('advanced_search.value_placeholder') %>" value="<%= @search_query %>">
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
30
35
|
</div>
|
|
31
36
|
<div id="save-search-container" style="display: none;">
|
|
32
37
|
<hr class="mt-4 mb-3">
|
|
33
38
|
<div class="form-group d-flex align-items-center mb-0">
|
|
34
|
-
<label for="savedSearchName" class="mr-2 field-label" style="width: 30%;"
|
|
35
|
-
<input type="text" id="savedSearchName" class="form-control flex-grow-1" placeholder="
|
|
39
|
+
<label for="savedSearchName" class="mr-2 field-label" style="width: 30%;"><%= t('advanced_search.save_as_name') %></label>
|
|
40
|
+
<input type="text" id="savedSearchName" class="form-control flex-grow-1" placeholder="<%= t('advanced_search.save_name_placeholder') %>">
|
|
36
41
|
</div>
|
|
37
42
|
</div>
|
|
38
43
|
</form>
|
|
39
44
|
</div>
|
|
40
45
|
<div class="modal-footer">
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
46
|
+
<div class="advanced-search-footer-left">
|
|
47
|
+
<%= render "kaui/components/button/button", {
|
|
48
|
+
label: t('advanced_search.actions.save_search_as'),
|
|
49
|
+
variant: "advanced-search-button advanced-search-button-secondary d-inline-flex align-items-center gap-1",
|
|
50
|
+
type: "button",
|
|
51
|
+
html_class: "custom-hover",
|
|
52
|
+
html_options: { id: "saveAdvanceSearch" }
|
|
53
|
+
} %>
|
|
54
|
+
</div>
|
|
55
|
+
<div class="advanced-search-footer-right">
|
|
56
|
+
<%= render "kaui/components/button/button", {
|
|
57
|
+
label: t('advanced_search.actions.clear_search'),
|
|
58
|
+
variant: "advanced-search-button advanced-search-button-ghost d-inline-flex align-items-center gap-1",
|
|
59
|
+
type: "button",
|
|
60
|
+
html_class: "custom-hover",
|
|
61
|
+
html_options: { id: "clearAdvanceSearch" }
|
|
62
|
+
} %>
|
|
63
|
+
<%= render "kaui/components/button/button", {
|
|
64
|
+
label: t('advanced_search.actions.apply_search'),
|
|
65
|
+
variant: "advanced-search-button advanced-search-button-primary d-inline-flex align-items-center gap-1",
|
|
66
|
+
type: "button",
|
|
67
|
+
html_class: "custom-hover",
|
|
68
|
+
html_options: { id: "applyAdvanceSearch" }
|
|
69
|
+
} %>
|
|
70
|
+
</div>
|
|
62
71
|
</div>
|
|
63
72
|
</div>
|
|
64
73
|
</div>
|
|
@@ -69,7 +78,7 @@ $(document).ready(function() {
|
|
|
69
78
|
// Pre-populate modal from current URL params on open
|
|
70
79
|
$('#advanceSearchModal').on('show.bs.modal', function() {
|
|
71
80
|
var params = new URLSearchParams(window.location.search);
|
|
72
|
-
var searchBy = params.get('search_by') || '
|
|
81
|
+
var searchBy = params.get('search_by') || '';
|
|
73
82
|
var q = params.get('q') || '';
|
|
74
83
|
$('#searchFieldSelect').val(searchBy);
|
|
75
84
|
$('#bundleSearchValue').val(q);
|
|
@@ -79,7 +88,15 @@ $(document).ready(function() {
|
|
|
79
88
|
$('#applyAdvanceSearch').on('click', function() {
|
|
80
89
|
var searchBy = $('#searchFieldSelect').val();
|
|
81
90
|
var q = $('#bundleSearchValue').val().trim();
|
|
82
|
-
if (!
|
|
91
|
+
if (!searchBy) {
|
|
92
|
+
alert($('#advanceSearchModal').data('missing-field-message'));
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (!q) {
|
|
97
|
+
alert($('#advanceSearchModal').data('empty-value-message'));
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
83
100
|
|
|
84
101
|
var url = new URL(window.location.href);
|
|
85
102
|
url.searchParams.set('search_by', searchBy);
|