Skip to content

Commit 5df1f03

Browse files
committed
Added search bar for Bundle page
1 parent b1c3afb commit 5df1f03

5 files changed

Lines changed: 270 additions & 4 deletions

File tree

app/assets/stylesheets/kaui/subscription.css

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -689,4 +689,79 @@ table tr.expired td {
689689
line-height: 1.25rem;
690690
color: #414651;
691691
margin-bottom: 0.25rem;
692+
}
693+
694+
/* Advance Search modal – Subscription Bundles page */
695+
.subscription-bundl-index .close-button {
696+
background: transparent;
697+
padding: 0;
698+
margin-top: -1.25rem;
699+
}
700+
701+
.subscription-bundl-index .close-button:hover {
702+
background: transparent;
703+
padding: 0;
704+
}
705+
706+
.subscription-bundl-index .border-button {
707+
background: transparent;
708+
display: inline-flex;
709+
justify-content: center;
710+
align-items: center;
711+
border: 0.0625rem solid #D5D7DA;
712+
border-radius: 0.375rem;
713+
width: 2.5rem;
714+
height: 2.5rem;
715+
padding: 0.625rem;
716+
}
717+
718+
.subscription-bundl-index .border-button:hover {
719+
background: transparent;
720+
}
721+
722+
.subscription-bundl-index .button {
723+
background: transparent;
724+
display: inline-flex;
725+
justify-content: center;
726+
align-items: center;
727+
width: 2.5rem;
728+
height: 2.5rem;
729+
padding: 0.625rem;
730+
}
731+
732+
.subscription-bundl-index .button:hover {
733+
background: transparent;
734+
}
735+
736+
.subscription-bundl-index .field-label {
737+
font-weight: 500;
738+
font-size: 0.875rem;
739+
line-height: 1.25rem;
740+
color: #414651;
741+
margin-top: -1.25rem;
742+
min-width: 9.59375rem;
743+
}
744+
745+
.subscription-bundl-index .search-field-label {
746+
margin-top: -1.25rem;
747+
}
748+
749+
.subscription-bundl-index .form-group.row.align-items-center {
750+
display: flex;
751+
align-items: center;
752+
}
753+
754+
.subscription-bundl-index .form-group.row.align-items-center label {
755+
margin-bottom: 0;
756+
}
757+
758+
.subscription-bundl-index .form-group.row.align-items-center .form-control {
759+
margin-right: 0.25rem;
760+
height: 2.5rem;
761+
border-radius: 0.375rem;
762+
}
763+
764+
.subscription-bundl-index .form-group.row.align-items-center.search-field div {
765+
padding: 0;
766+
margin-right: 0.25rem;
692767
}

app/controllers/kaui/bundles_controller.rb

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ class BundlesController < Kaui::EngineController
55
# rubocop:disable Lint/HashCompareByIdentity
66
def index
77
cached_options_for_klient = options_for_klient
8+
@search_query = params[:q].presence
9+
@search_by = params[:search_by] || 'bundle_id'
810
@per_page = (params[:per_page] || 10).to_i
911
@page = (params[:page] || 1).to_i
1012

11-
fetch_bundles = promise { Kaui::Account.paginated_bundles(@account.account_id, (@page - 1) * @per_page, @per_page, 'NONE', cached_options_for_klient) }
1213
fetch_bundle_tags = promise do
1314
all_bundle_tags = @account.all_tags(:BUNDLE, false, 'NONE', cached_options_for_klient)
1415
all_bundle_tags.each_with_object({}) do |entry, hsh|
@@ -36,8 +37,15 @@ def index
3637
fetch_available_tags = promise { Kaui::TagDefinition.all_for_bundle(cached_options_for_klient) }
3738
fetch_available_subscription_tags = promise { Kaui::TagDefinition.all_for_subscription(cached_options_for_klient) }
3839

39-
@bundles = wait(fetch_bundles)
40-
@total_pages = (@bundles.pagination_max_nb_records.to_f / @per_page).ceil
40+
if @search_query.present?
41+
@bundles = search_bundles(@search_query, @search_by, cached_options_for_klient)
42+
@total_pages = 1
43+
@page = 1
44+
else
45+
fetched = Kaui::Account.paginated_bundles(@account.account_id, (@page - 1) * @per_page, @per_page, 'NONE', cached_options_for_klient)
46+
@bundles = fetched
47+
@total_pages = (fetched.pagination_max_nb_records.to_f / @per_page).ceil
48+
end
4149

4250
@tags_per_bundle = wait(fetch_bundle_tags)
4351
@tags_per_subscription = wait(fetch_subscription_tags)
@@ -112,5 +120,38 @@ def do_pause_resume
112120
end
113121
redirect_to kaui_engine.account_bundles_path(@account.account_id), notice: msg
114122
end
123+
124+
private
125+
126+
def search_bundles(query, search_by, options)
127+
case search_by
128+
when 'bundle_id'
129+
bundle = Kaui::Bundle.find_by_id(query, options)
130+
bundle ? [bundle] : []
131+
when 'bundle_external_key'
132+
bundle = Kaui::Bundle.find_by_external_key(query, false, options)
133+
bundle ? [bundle] : []
134+
when 'subscription_id'
135+
subscription = KillBillClient::Model::Subscription.find_by_id(query, 'NONE', options)
136+
if subscription
137+
bundle = Kaui::Bundle.find_by_id(subscription.bundle_id, options)
138+
bundle ? [bundle] : []
139+
else
140+
[]
141+
end
142+
when 'subscription_external_key'
143+
subscription = KillBillClient::Model::Subscription.find_by_external_key(query, 'NONE', options)
144+
if subscription
145+
bundle = Kaui::Bundle.find_by_id(subscription.bundle_id, options)
146+
bundle ? [bundle] : []
147+
else
148+
[]
149+
end
150+
else
151+
[]
152+
end
153+
rescue StandardError
154+
[]
155+
end
115156
end
116157
end

app/models/kaui/bundle.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
module Kaui
44
class Bundle < KillBillClient::Model::Bundle
5+
SEARCH_FIELDS = [
6+
['bundle_id', 'Bundle ID'],
7+
['bundle_external_key', 'Bundle External Key'],
8+
['subscription_id', 'Subscription ID'],
9+
['subscription_external_key', 'Subscription External Key']
10+
].freeze
511
def self.find_by_id_or_key(bundle_id_or_key, options = {})
612
if /[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}/.match?(bundle_id_or_key)
713
bundle = begin
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
<div class="modal fade" id="advanceSearchModal" tabindex="-1" role="dialog" aria-labelledby="advanceSearchModalLabel" aria-hidden="true">
2+
<div class="modal-dialog" role="document">
3+
<div class="modal-content">
4+
<div class="modal-header">
5+
<h5 class="modal-title d-flex align-items-center gap-3" id="advanceSearchModalLabel">
6+
<span class="icon-container">
7+
<%= image_tag("kaui/modal/search.svg", width: 20, height: 20) %>
8+
</span>
9+
Advance Search
10+
</h5>
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+
<% Kaui::Bundle::SEARCH_FIELDS.each do |value, title| %>
23+
<option value="<%= value %>" <%= 'selected' if @search_by == value %>><%= title %></option>
24+
<% end %>
25+
</select>
26+
</div>
27+
<div class="form-group d-flex align-items-center mt-3">
28+
<label for="bundleSearchValue" class="mr-2 field-label" style="width: 30%;">Value</label>
29+
<input type="text" id="bundleSearchValue" class="form-control" placeholder="Enter search value..." value="<%= @search_query %>">
30+
</div>
31+
</form>
32+
</div>
33+
<div class="modal-footer">
34+
<%= render "kaui/components/button/button", {
35+
label: 'Clear Search',
36+
variant: "outline-secondary d-inline-flex align-items-center gap-1",
37+
type: "button",
38+
html_class: "kaui-button custom-hover",
39+
html_options: { id: "clearAdvanceSearch" }
40+
} %>
41+
<%= render "kaui/components/button/button", {
42+
label: 'Apply Search',
43+
variant: "outline-secondary d-inline-flex align-items-center gap-1",
44+
type: "button",
45+
html_class: "kaui-dropdown custom-hover",
46+
html_options: { id: "applyAdvanceSearch" }
47+
} %>
48+
</div>
49+
</div>
50+
</div>
51+
</div>
52+
53+
<%= javascript_tag do %>
54+
$(document).ready(function() {
55+
// Pre-populate modal from current URL params on open
56+
$('#advanceSearchModal').on('show.bs.modal', function() {
57+
var params = new URLSearchParams(window.location.search);
58+
var searchBy = params.get('search_by') || 'bundle_id';
59+
var q = params.get('q') || '';
60+
$('#searchFieldSelect').val(searchBy);
61+
$('#bundleSearchValue').val(q);
62+
});
63+
64+
// Apply search: navigate to same page with query params
65+
$('#applyAdvanceSearch').on('click', function() {
66+
var searchBy = $('#searchFieldSelect').val();
67+
var q = $('#bundleSearchValue').val().trim();
68+
if (!q) return;
69+
70+
var url = new URL(window.location.href);
71+
url.searchParams.set('search_by', searchBy);
72+
url.searchParams.set('q', q);
73+
url.searchParams.delete('page');
74+
window.location.href = url.toString();
75+
});
76+
77+
// Clear search: navigate to same page without query params
78+
$('#clearAdvanceSearch').on('click', function() {
79+
var url = new URL(window.location.href);
80+
url.searchParams.delete('q');
81+
url.searchParams.delete('search_by');
82+
url.searchParams.delete('page');
83+
window.location.href = url.toString();
84+
});
85+
86+
// Handle click on active search label close icon
87+
$(document).on('click', '.bundle-filter-close-icon', function() {
88+
var url = new URL(window.location.href);
89+
url.searchParams.delete('q');
90+
url.searchParams.delete('search_by');
91+
url.searchParams.delete('page');
92+
window.location.href = url.toString();
93+
});
94+
95+
// Show active search label on page load
96+
updateBundleSearchLabels();
97+
98+
function updateBundleSearchLabels() {
99+
var params = new URLSearchParams(window.location.search);
100+
var q = params.get('q');
101+
var searchBy = params.get('search_by');
102+
var container = $('#search-labels-container');
103+
container.empty();
104+
105+
if (q && searchBy) {
106+
var fieldLabel = $('#searchFieldSelect option[value="' + searchBy + '"]').text() || searchBy;
107+
var label = $('<span>', {
108+
class: 'label label-info d-inline-flex align-items-center gap-2'
109+
});
110+
label.append($('<span>', { text: fieldLabel + ': ' + q }));
111+
label.append($('<span>', {
112+
class: 'bundle-filter-close-icon',
113+
style: 'cursor: pointer; margin-left: 5px; display: inline-flex; align-items: center;'
114+
}).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>'));
115+
container.append(label);
116+
}
117+
}
118+
});
119+
<% end %>

app/views/kaui/bundles/index.html.erb

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<div class="kaui-container subscription-bundl-index pb-5">
22
<%= render "kaui/components/breadcrumb/breadcrumb" %>
3+
<%= render :partial => 'bundle_filterbar' %>
34
<div class="d-flex mb-5" style="gap: 4rem;">
45
<%= render :template => 'kaui/layouts/kaui_account_sidebar' %>
56
<div class="subscription-bundle">
@@ -8,7 +9,20 @@
89
<div class="d-flex align-items-center">
910
<h2>Subscription Bundles</h2>
1011
</div>
11-
<span>
12+
<span class="d-flex align-items-center gap-2">
13+
<%= render "kaui/components/button/button", {
14+
label: "Advance Search",
15+
icon: "kaui/search.svg",
16+
variant: "outline-secondary d-inline-flex align-items-center gap-1",
17+
type: "button",
18+
html_class: "kaui-button custom-hover",
19+
html_options: {
20+
data: {
21+
bs_toggle: "modal",
22+
bs_target: "#advanceSearchModal"
23+
}
24+
}
25+
} %>
1226
<% if can? :create, Kaui::Subscription %>
1327
<%= link_to kaui_engine.new_subscription_path(:params => { :account_id => @account.account_id, :product_category => 'BASE' }) do %>
1428
<%= render "kaui/components/button/button", {
@@ -22,6 +36,9 @@
2236
<% end %>
2337
</span>
2438
</div>
39+
<div id="search-labels-container" class="ml-2 mb-2">
40+
<!-- Dynamic search labels will be added here -->
41+
</div>
2542
<div class="subscriptions-scroll">
2643
<% @bundles.each_with_index do |bundle, idx| %>
2744
<div class="row">
@@ -37,6 +54,13 @@
3754
<% end %>
3855

3956

57+
<% if @bundles.empty? %>
58+
<div class="custom-alert custom-alert-info mt-3">
59+
<span>No bundles found<%= @search_query.present? ? " for the given search query." : "." %></span>
60+
</div>
61+
<% end %>
62+
63+
<% unless @search_query.present? %>
4064
<div class="text-right d-flex justify-content-end pagination" style="">
4165
<%= link_to account_bundles_path(page: @page - 1), class: "btn btn-custom #{'disabled' if @page == 1}" do %>
4266
<%= render "kaui/components/button/button", {
@@ -81,6 +105,7 @@
81105
} %>
82106
<% end %>
83107
</div>
108+
<% end %>
84109
</div>
85110
</div>
86111
</div>

0 commit comments

Comments
 (0)