kaui 4.0.9 → 4.0.11
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/images/kaui/subscription/transfer.svg +3 -0
- data/app/assets/stylesheets/kaui/common.css +78 -0
- data/app/controllers/kaui/admin_allowed_users_controller.rb +17 -2
- data/app/controllers/kaui/admin_tenants_controller.rb +4 -0
- data/app/controllers/kaui/refunds_controller.rb +1 -0
- data/app/controllers/kaui/role_definitions_controller.rb +31 -1
- data/app/models/kaui/bundle.rb +2 -2
- data/app/views/kaui/accounts/_multi_functions_bar.html.erb +2 -2
- data/app/views/kaui/admin_allowed_users/_form.html.erb +18 -2
- data/app/views/kaui/admin_tenants/_add_allowed_user_modal.html.erb +4 -33
- data/app/views/kaui/admin_tenants/_show_catalog_simple.erb +0 -13
- data/app/views/kaui/admin_tenants/_tenant_details.html.erb +12 -3
- data/app/views/kaui/admin_tenants/show.html.erb +1 -1
- data/app/views/kaui/bundles/transfer.html.erb +45 -27
- data/app/views/kaui/components/search_input/_search_input.html.erb +19 -4
- data/app/views/kaui/refunds/_form.html.erb +1 -1
- data/app/views/kaui/subscriptions/_subscriptions_table.html.erb +9 -1
- data/config/locales/en.yml +3 -3
- data/lib/kaui/error_handler.rb +22 -12
- data/lib/kaui/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7328709e0c330b84f3e47b4041cf55aa61bf98c7ac80dbb9b2d199b71c3d1f7a
|
|
4
|
+
data.tar.gz: 27b7f69cdb1e950cd327ac7c31141a76ae6c07e7e063d5ccd6d66c020a4fe612
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e7e3008686fb14493dca39a5adcda76d6032c0a8ba23cbf76971dac4829d59ae275a34779d3450aaf7babead74924a66a968cfc07579e74bcd6669763681a632
|
|
7
|
+
data.tar.gz: 9195fcbb008a972b2a8e4b6dbee1b471662e5f30623910ea5b4abe290957f726b8c620c56c82df742ef43587b08f006a7c9d65825833938f01e98a666e3605fe
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M2.6665 5.3332H13.3332M13.3332 5.3332L10.6665 2.6665M13.3332 5.3332L10.6665 7.9999M13.3332 10.6665H2.6665M2.6665 10.6665L5.3332 7.9999M2.6665 10.6665L5.3332 13.3332" stroke="#A4A7AE" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
|
|
3
|
+
</svg>
|
|
@@ -687,6 +687,84 @@ form[id^="new_tag_definition"] #object_types div .tag-definition-select {
|
|
|
687
687
|
color: #00919d;
|
|
688
688
|
}
|
|
689
689
|
|
|
690
|
+
/* Modern toggle switch */
|
|
691
|
+
.toggle-switch {
|
|
692
|
+
position: relative;
|
|
693
|
+
display: inline-block;
|
|
694
|
+
width: 70px;
|
|
695
|
+
height: 26px;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
.toggle-switch input {
|
|
699
|
+
opacity: 0;
|
|
700
|
+
width: 0;
|
|
701
|
+
height: 0;
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
.toggle-slider {
|
|
705
|
+
position: absolute;
|
|
706
|
+
cursor: pointer;
|
|
707
|
+
top: 0;
|
|
708
|
+
left: 0;
|
|
709
|
+
right: 0;
|
|
710
|
+
bottom: 0;
|
|
711
|
+
background-color: gray;
|
|
712
|
+
transition: .3s;
|
|
713
|
+
border-radius: 26px;
|
|
714
|
+
box-shadow: inset 0 1px 3px rgba(0,0,0,0.2);
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
.toggle-slider:before {
|
|
718
|
+
position: absolute;
|
|
719
|
+
content: "";
|
|
720
|
+
height: 20px;
|
|
721
|
+
width: 20px;
|
|
722
|
+
left: 3px;
|
|
723
|
+
bottom: 3px;
|
|
724
|
+
background-color: white;
|
|
725
|
+
transition: .3s;
|
|
726
|
+
border-radius: 50%;
|
|
727
|
+
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
.toggle-slider:after {
|
|
731
|
+
content: 'OFF';
|
|
732
|
+
color: white;
|
|
733
|
+
display: block;
|
|
734
|
+
position: absolute;
|
|
735
|
+
transform: translate(-50%,-50%);
|
|
736
|
+
top: 50%;
|
|
737
|
+
left: 70%;
|
|
738
|
+
font-size: 10px;
|
|
739
|
+
font-weight: bold;
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
.toggle-switch input:checked + .toggle-slider {
|
|
743
|
+
background-color: #1570ef;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
.toggle-switch input:checked + .toggle-slider:before {
|
|
747
|
+
transform: translateX(24px);
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
.toggle-switch input:checked + .toggle-slider:after {
|
|
751
|
+
content: 'ON';
|
|
752
|
+
left: 30%;
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
.toggle-switch input:disabled + .toggle-slider {
|
|
756
|
+
cursor: not-allowed;
|
|
757
|
+
opacity: 0.8;
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
.toggle-switch input:not(:checked) + .toggle-slider:hover {
|
|
761
|
+
background-color: #1570ef;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
.toggle-switch input:checked:not(:disabled) + .toggle-slider:hover {
|
|
765
|
+
background-color: #1570ef;
|
|
766
|
+
}
|
|
767
|
+
|
|
690
768
|
/* Required for https://github.com/killbill/killbill-admin-ui/issues/262 */
|
|
691
769
|
.ui-autocomplete {
|
|
692
770
|
position: absolute;
|
|
@@ -15,8 +15,16 @@ module Kaui
|
|
|
15
15
|
def new
|
|
16
16
|
@allowed_user = Kaui::AllowedUser.new
|
|
17
17
|
@is_killbill_managed = true
|
|
18
|
-
|
|
19
18
|
@roles = []
|
|
19
|
+
|
|
20
|
+
# Restore form state if returning from role creation
|
|
21
|
+
return unless params[:user_context].present?
|
|
22
|
+
|
|
23
|
+
context = params[:user_context]
|
|
24
|
+
@allowed_user.kb_username = context[:kb_username]
|
|
25
|
+
@allowed_user.description = context[:description]
|
|
26
|
+
@roles = context[:roles].to_s.split(',').reject(&:blank?)
|
|
27
|
+
@external_checked = context[:external] == '1'
|
|
20
28
|
end
|
|
21
29
|
|
|
22
30
|
def create
|
|
@@ -59,7 +67,14 @@ module Kaui
|
|
|
59
67
|
@allowed_user = Kaui::AllowedUser.find(params.require(:id))
|
|
60
68
|
@is_killbill_managed = killbill_managed?(@allowed_user, options_for_klient)
|
|
61
69
|
|
|
62
|
-
|
|
70
|
+
# Use roles from context if returning from role creation, otherwise fetch from KB
|
|
71
|
+
if params[:user_context].present?
|
|
72
|
+
context = params[:user_context]
|
|
73
|
+
@roles = context[:roles].to_s.split(',').reject(&:blank?)
|
|
74
|
+
@allowed_user.description = context[:description] if context[:description].present?
|
|
75
|
+
else
|
|
76
|
+
@roles = roles_for_user(@allowed_user)
|
|
77
|
+
end
|
|
63
78
|
end
|
|
64
79
|
|
|
65
80
|
def update
|
|
@@ -76,6 +76,10 @@ module Kaui
|
|
|
76
76
|
@tenant = safely_find_tenant_by_id(params[:id])
|
|
77
77
|
@allowed_users = @tenant.kaui_allowed_users & retrieve_allowed_users_for_current_user
|
|
78
78
|
|
|
79
|
+
# Get available users that can be added to this tenant
|
|
80
|
+
actual_allowed_users_ids = (@tenant.kaui_allowed_users || []).map(&:id)
|
|
81
|
+
@available_users = retrieve_allowed_users_for_current_user.reject { |au| actual_allowed_users_ids.include? au.id }
|
|
82
|
+
|
|
79
83
|
configure_tenant_if_nil(@tenant)
|
|
80
84
|
|
|
81
85
|
# Fetch clock data for the clock component
|
|
@@ -28,6 +28,7 @@ module Kaui
|
|
|
28
28
|
|
|
29
29
|
item = KillBillClient::Model::InvoiceItem.new
|
|
30
30
|
item.invoice_item_id = ii[0]
|
|
31
|
+
item.description = params.dig(:descriptions, ii[0])
|
|
31
32
|
# If we tried to do a partial item adjustment, we pass the value, if not we don't send any value and let the system
|
|
32
33
|
# decide what is the maximum amount we can have on that item
|
|
33
34
|
item.amount = ii[1].to_f == original_item.amount ? nil : ii[1]
|
|
@@ -4,6 +4,17 @@ module Kaui
|
|
|
4
4
|
class RoleDefinitionsController < Kaui::EngineController
|
|
5
5
|
def new
|
|
6
6
|
@role_definition = Kaui::RoleDefinition.new
|
|
7
|
+
|
|
8
|
+
# Store user form context if coming from user creation/edit
|
|
9
|
+
return unless params[:return_to_user].present?
|
|
10
|
+
|
|
11
|
+
session[:role_return_context] = {
|
|
12
|
+
kb_username: params[:kb_username],
|
|
13
|
+
description: params[:description],
|
|
14
|
+
roles: params[:roles],
|
|
15
|
+
external: params[:external],
|
|
16
|
+
allowed_user_id: params[:allowed_user_id]
|
|
17
|
+
}
|
|
7
18
|
end
|
|
8
19
|
|
|
9
20
|
def create
|
|
@@ -13,7 +24,26 @@ module Kaui
|
|
|
13
24
|
|
|
14
25
|
begin
|
|
15
26
|
@role_definition = @role_definition.create(current_user.kb_username, params[:reason], params[:comment], options_for_klient)
|
|
16
|
-
|
|
27
|
+
|
|
28
|
+
# Check if we need to return to user form with the new role
|
|
29
|
+
return_context = session.delete(:role_return_context)
|
|
30
|
+
if return_context.present?
|
|
31
|
+
# Add the new role to the existing roles
|
|
32
|
+
existing_roles = return_context[:roles].to_s.split(',').reject(&:blank?)
|
|
33
|
+
existing_roles << @role_definition.role unless existing_roles.include?(@role_definition.role)
|
|
34
|
+
return_context[:roles] = existing_roles.join(',')
|
|
35
|
+
|
|
36
|
+
# Redirect back to user form (new or edit)
|
|
37
|
+
if return_context[:allowed_user_id].present? && return_context[:allowed_user_id] != ''
|
|
38
|
+
redirect_to edit_admin_allowed_user_path(return_context[:allowed_user_id], user_context: return_context),
|
|
39
|
+
notice: "Role '#{@role_definition.role}' was successfully created"
|
|
40
|
+
else
|
|
41
|
+
redirect_to new_admin_allowed_user_path(user_context: return_context),
|
|
42
|
+
notice: "Role '#{@role_definition.role}' was successfully created"
|
|
43
|
+
end
|
|
44
|
+
else
|
|
45
|
+
redirect_to admin_allowed_users_path, notice: 'Role was successfully created'
|
|
46
|
+
end
|
|
17
47
|
rescue StandardError => e
|
|
18
48
|
flash.now[:error] = "Error while creating role: #{as_string(e)}"
|
|
19
49
|
render action: :new
|
data/app/models/kaui/bundle.rb
CHANGED
|
@@ -48,14 +48,14 @@ module Kaui
|
|
|
48
48
|
|
|
49
49
|
def self.list_transfer_policy_params
|
|
50
50
|
@policy_params = [
|
|
51
|
-
[I18n.translate('start_of_term'), 'START_OF_TERM'],
|
|
51
|
+
# [I18n.translate('start_of_term'), 'START_OF_TERM'], Temporarily removed as it is not supported by Kill Bill
|
|
52
52
|
[I18n.translate('end_of_term'), 'END_OF_TERM'],
|
|
53
53
|
[I18n.translate('immediate'), 'IMMEDIATE']
|
|
54
54
|
]
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
def self.list_transfer_policy_params_keys
|
|
58
|
-
@policy_params = %w[
|
|
58
|
+
@policy_params = %w[END_OF_TERM IMMEDIATE]
|
|
59
59
|
end
|
|
60
60
|
end
|
|
61
61
|
end
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
|
|
2
2
|
<div class="filter-bar-container">
|
|
3
3
|
<div class="filter-bar">
|
|
4
|
-
<button class="btn btn-default download-button-right" data-toggle="modal" data-target="#
|
|
4
|
+
<button class="btn btn-default download-button-right" data-toggle="modal" data-target="#advancedSearchModal">
|
|
5
5
|
<i class="glyphicon glyphicon-search"></i>
|
|
6
|
-
<strong>
|
|
6
|
+
<strong>Advanced Search</strong>
|
|
7
7
|
</button>
|
|
8
8
|
|
|
9
9
|
<div id="search-labels-container" class="ml-2">
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<div class="col-sm-9">
|
|
6
6
|
<div class="checkbox">
|
|
7
7
|
<label for="external" class="d-flex align-items-center gap-2 control-label">
|
|
8
|
-
<%= check_box_tag :external, '1', false, disabled: !@allowed_user.id.blank?, id: 'external', class: "pt-2" %>
|
|
8
|
+
<%= check_box_tag :external, '1', @external_checked || false, disabled: !@allowed_user.id.blank?, id: 'external', class: "pt-2" %>
|
|
9
9
|
Managed externally (LDAP, Okta, etc.)?
|
|
10
10
|
</label>
|
|
11
11
|
</div>
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
</div>
|
|
39
39
|
<%= hidden_field_tag :roles, @roles.join(','), id: 'roles-hidden' %>
|
|
40
40
|
|
|
41
|
-
<%= link_to
|
|
41
|
+
<%= link_to '#', class: "border-button custom-hover add-role-button", id: "add-role-link", data: { base_url: new_role_definition_path } do %>
|
|
42
42
|
<%= image_tag("kaui/modal/plus.svg", width: 16, height: 16) %>
|
|
43
43
|
<% end %>
|
|
44
44
|
</div>
|
|
@@ -78,6 +78,22 @@
|
|
|
78
78
|
<%= javascript_tag do %>
|
|
79
79
|
$(document).ready(function() {
|
|
80
80
|
|
|
81
|
+
// Handle add role button click - pass current form state
|
|
82
|
+
$('#add-role-link').click(function(e) {
|
|
83
|
+
e.preventDefault();
|
|
84
|
+
var baseUrl = $(this).data('base-url');
|
|
85
|
+
var params = {
|
|
86
|
+
return_to_user: '1',
|
|
87
|
+
kb_username: $('#allowed_user_kb_username').val(),
|
|
88
|
+
description: $('#allowed_user_description').val(),
|
|
89
|
+
roles: $('#roles-hidden').val(),
|
|
90
|
+
external: $('#external').is(':checked') ? '1' : '0',
|
|
91
|
+
allowed_user_id: '<%= @allowed_user.id %>'
|
|
92
|
+
};
|
|
93
|
+
var queryString = $.param(params);
|
|
94
|
+
window.location.href = baseUrl + '?' + queryString;
|
|
95
|
+
});
|
|
96
|
+
|
|
81
97
|
$('#external').change(function() {
|
|
82
98
|
is_killbill_managed();
|
|
83
99
|
});
|
|
@@ -16,10 +16,10 @@
|
|
|
16
16
|
</div>
|
|
17
17
|
<div class="modal-body">
|
|
18
18
|
<%= form_for :allowed_user, :url => add_allowed_user_path, :method => :put, :html => {:class => 'form-horizontal', :id => 'tenantAllowedUserForm'} do |f| %>
|
|
19
|
-
<div class='form-group
|
|
20
|
-
<%= f.label :kb_username, 'User Name', :class => 'col-sm-3
|
|
19
|
+
<div class='form-group row align-items-center p-3'>
|
|
20
|
+
<%= f.label :kb_username, 'User Name', :class => 'col-sm-3 col-form-label text-center' %>
|
|
21
21
|
<div class="col-sm-9">
|
|
22
|
-
<%= f.
|
|
22
|
+
<%= f.select :kb_username, options_for_select(@available_users.map { |u| [u.kb_username, u.kb_username] }), { prompt: 'Select a user' }, { class: 'form-control', required: true } %>
|
|
23
23
|
</div>
|
|
24
24
|
</div>
|
|
25
25
|
<input type="hidden" name="tenant_id" value="<%= @tenant.id %>" />
|
|
@@ -54,38 +54,9 @@
|
|
|
54
54
|
|
|
55
55
|
<%= javascript_tag do %>
|
|
56
56
|
$(document).ready(function() {
|
|
57
|
-
function loadAllowedUser() {
|
|
58
|
-
$.ajax(
|
|
59
|
-
{
|
|
60
|
-
url: Routes.kaui_engine_admin_tenant_allowed_users_path(),
|
|
61
|
-
type: "GET",
|
|
62
|
-
dataType: "json",
|
|
63
|
-
data: {tenant_id: <%= @tenant.id %>},
|
|
64
|
-
success: function(data) {
|
|
65
|
-
var availableAllowedUser = [];
|
|
66
|
-
for (var i=0; i < data.length ; i++) {
|
|
67
|
-
availableAllowedUser.push(data[i].kb_username);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
$( "#allowed_user_kb_username" ).autocomplete({
|
|
71
|
-
source: availableAllowedUser,
|
|
72
|
-
appendTo: "#tenantAllowedUserForm",
|
|
73
|
-
classes: {
|
|
74
|
-
"ui-autocomplete": "autocomplete-allowed-user"
|
|
75
|
-
},
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
|
|
82
57
|
$('#addAllowedUserModal').on('show.bs.modal', function (e) {
|
|
83
58
|
// reset field
|
|
84
|
-
$(
|
|
85
|
-
|
|
59
|
+
$('#allowed_user_kb_username').prop('selectedIndex', 0);
|
|
86
60
|
});
|
|
87
|
-
|
|
88
|
-
loadAllowedUser();
|
|
89
|
-
|
|
90
61
|
});
|
|
91
62
|
<% end %>
|
|
@@ -74,7 +74,6 @@
|
|
|
74
74
|
<th id="currency_select"></th>
|
|
75
75
|
<th><%= I18n.translate('views.catalogs.show.plan_table.trial') %></th>
|
|
76
76
|
<th><%= I18n.translate('views.catalogs.show.plan_table.final_phase_duration') %></th>
|
|
77
|
-
<th></th>
|
|
78
77
|
</tr>
|
|
79
78
|
</thead>
|
|
80
79
|
<tbody id="catalog_detail">
|
|
@@ -117,18 +116,6 @@
|
|
|
117
116
|
<td>
|
|
118
117
|
<span class="phase-duration">{{final_phase_duration}}</span>
|
|
119
118
|
</td>
|
|
120
|
-
|
|
121
|
-
<td>
|
|
122
|
-
<%= link_to "{{new_plan_currency_path}}", class:"text-decoration-none" do %>
|
|
123
|
-
<%= render "kaui/components/button/button", {
|
|
124
|
-
label: "Currency",
|
|
125
|
-
icon: "kaui/setting/plus.svg",
|
|
126
|
-
variant: "outline-secondary d-inline-flex align-items-center",
|
|
127
|
-
type: "button",
|
|
128
|
-
html_class: "currency-button kaui-button",
|
|
129
|
-
} %>
|
|
130
|
-
<% end %>
|
|
131
|
-
</td>
|
|
132
119
|
</tr>
|
|
133
120
|
{{/plans}}
|
|
134
121
|
{{/catalog}}
|
|
@@ -11,11 +11,20 @@
|
|
|
11
11
|
<div class="row tenant-details">
|
|
12
12
|
<div class="col-sm-3">
|
|
13
13
|
<b>Name:</b>
|
|
14
|
-
<p
|
|
14
|
+
<p class="d-flex align-items-center gap-2">
|
|
15
|
+
<%= @tenant.name %>
|
|
15
16
|
<% if session[:kb_tenant_name] == @tenant.name %>
|
|
16
|
-
<
|
|
17
|
+
<label class="toggle-switch">
|
|
18
|
+
<input type="checkbox" checked disabled>
|
|
19
|
+
<span class="toggle-slider"></span>
|
|
20
|
+
</label>
|
|
17
21
|
<% else %>
|
|
18
|
-
<%= link_to
|
|
22
|
+
<%= link_to switch_tenant_path(:kb_tenant_id => @tenant.kb_tenant_id), method: :get, title: "Click to switch to this tenant", style: "text-decoration: none;" do %>
|
|
23
|
+
<label class="toggle-switch" style="cursor: pointer;">
|
|
24
|
+
<input type="checkbox">
|
|
25
|
+
<span class="toggle-slider"></span>
|
|
26
|
+
</label>
|
|
27
|
+
<% end %>
|
|
19
28
|
<% end %>
|
|
20
29
|
</p>
|
|
21
30
|
</div>
|
|
@@ -1,38 +1,56 @@
|
|
|
1
|
-
<div class="register">
|
|
2
|
-
<div class="
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
<div class="register kaui-subscription-new">
|
|
2
|
+
<div class="">
|
|
3
|
+
<div class="mx-auto" style="max-width: 37.5rem;">
|
|
4
|
+
<h5 class="add-account-title border-bottom pb-3 mb-3">
|
|
5
|
+
<span class="icon-container">
|
|
6
|
+
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
7
|
+
<path d="M3.33325 6.6665H16.6666M16.6666 6.6665L13.3333 3.33317M16.6666 6.6665L13.3333 9.99984M16.6666 13.3332H3.33325M3.33325 13.3332L6.66659 9.99984M3.33325 13.3332L6.66659 16.6665" stroke="#414651" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
8
|
+
</svg>
|
|
9
|
+
</span>
|
|
10
|
+
<%= I18n.translate('transfer') %>
|
|
11
|
+
</h5>
|
|
6
12
|
|
|
7
13
|
<%= form_tag do_transfer_bundle_path(@bundle_id), :class => 'form-horizontal', :method => :put do %>
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
</div>
|
|
14
|
+
<div class="form-group d-flex pb-3">
|
|
15
|
+
<%= label_tag :new_account_key, I18n.translate('new_account'), :class => 'col-sm-3 control-label' %>
|
|
16
|
+
<div class="col-sm-9">
|
|
17
|
+
<%= text_field_tag :new_account_key, nil, :class => 'form-control', :placeholder => I18n.translate('new_account_id_or_external_key') %>
|
|
13
18
|
</div>
|
|
19
|
+
</div>
|
|
14
20
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
</div>
|
|
21
|
+
<div class="form-group d-flex pb-3">
|
|
22
|
+
<%= label_tag :billing_policy, I18n.translate('billing_policy'), :class => 'col-sm-3 control-label' %>
|
|
23
|
+
<div class="col-sm-9">
|
|
24
|
+
<%= select_tag :billing_policy, options_for_select(Kaui::Bundle.list_transfer_policy_params, selected: "END_OF_TERM"), :class => 'form-control' %>
|
|
20
25
|
</div>
|
|
26
|
+
</div>
|
|
21
27
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
</div>
|
|
27
|
-
</div>
|
|
28
|
-
<div class="form-group">
|
|
29
|
-
<div class="col-sm-offset-2 col-sm-10">
|
|
30
|
-
<%= submit_tag I18n.translate('change'), :class => 'btn btn-default' %>
|
|
31
|
-
</div>
|
|
28
|
+
<div class="form-group d-flex pb-3 border-bottom mb-3">
|
|
29
|
+
<%= label_tag :comment, I18n.translate('comment'), :class => 'col-sm-3 control-label' %>
|
|
30
|
+
<div class="col-sm-9">
|
|
31
|
+
<%= text_area_tag :comment, nil, :rows => 3, :class => 'form-control' %>
|
|
32
32
|
</div>
|
|
33
|
-
|
|
33
|
+
</div>
|
|
34
34
|
|
|
35
|
+
<div class="form-group d-flex justify-content-end pb-3">
|
|
36
|
+
<%= render "kaui/components/button/button", {
|
|
37
|
+
label: 'Close',
|
|
38
|
+
variant: "outline-secondary d-inline-flex align-items-center gap-1",
|
|
39
|
+
type: "button",
|
|
40
|
+
html_class: "kaui-button custom-hover mx-2",
|
|
41
|
+
html_options: {
|
|
42
|
+
id: "closeButton",
|
|
43
|
+
onclick: "window.history.back();"
|
|
44
|
+
}
|
|
45
|
+
} %>
|
|
46
|
+
<%= render "kaui/components/button/button", {
|
|
47
|
+
label: I18n.translate('transfer'),
|
|
48
|
+
variant: "outline-secondary d-inline-flex align-items-center gap-1",
|
|
49
|
+
type: "submit",
|
|
50
|
+
html_class: "kaui-dropdown custom-hover"
|
|
51
|
+
} %>
|
|
52
|
+
</div>
|
|
53
|
+
<% end %>
|
|
35
54
|
</div>
|
|
36
|
-
|
|
37
55
|
</div>
|
|
38
56
|
</div>
|
|
@@ -33,15 +33,15 @@
|
|
|
33
33
|
<div class="mb-1 fw-semibold text-muted mb-2">Suggested search queries</div>
|
|
34
34
|
<div class="mb-3">
|
|
35
35
|
<div class="inline-block me-2 my-4">
|
|
36
|
-
<span class="me-2 header-tag custom-hover text-black-900 fw-500 align-items-center gap-2 border-secondary px-2 py-2 border-2 rounded-4 ">account:</span>
|
|
36
|
+
<span class="me-2 header-tag custom-hover text-black-900 fw-500 align-items-center gap-2 border-secondary px-2 py-2 border-2 rounded-4 search-suggestion-term" data-term="account:" style="cursor: pointer;">account:</span>
|
|
37
37
|
<span>account: Flavio Ruggiero</span>
|
|
38
38
|
</div>
|
|
39
39
|
<div class="inline-block me-2 my-4">
|
|
40
|
-
<span class="me-2 header-tag custom-hover text-black-900 fw-500 align-items-center gap-2 border-secondary px-2 py-2 border-2 rounded-4 ">invoice:</span>
|
|
40
|
+
<span class="me-2 header-tag custom-hover text-black-900 fw-500 align-items-center gap-2 border-secondary px-2 py-2 border-2 rounded-4 search-suggestion-term" data-term="invoice:" style="cursor: pointer;">invoice:</span>
|
|
41
41
|
<span>invoice: af58a92c-bdc4-...</span>
|
|
42
42
|
</div>
|
|
43
43
|
<div class="inline-block me-2 my-4">
|
|
44
|
-
<span class="me-2 header-tag custom-hover text-black-900 fw-500 align-items-center gap-2 border-secondary px-2 py-2 border-2 rounded-4 ">payment:</span>
|
|
44
|
+
<span class="me-2 header-tag custom-hover text-black-900 fw-500 align-items-center gap-2 border-secondary px-2 py-2 border-2 rounded-4 search-suggestion-term" data-term="payment:" style="cursor: pointer;">payment:</span>
|
|
45
45
|
<span>payment: 3c4c0263-b06f-...</span>
|
|
46
46
|
</div>
|
|
47
47
|
</div>
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
<div class="fw-semibold text-muted mb-2">Other search queries</div>
|
|
50
50
|
<div class="d-flex flex-wrap gap-2">
|
|
51
51
|
<% %w[bundle: custom\ field: subscription: tag:].each do |term| %>
|
|
52
|
-
<span class="badge text-dark border border-secondary rounded-3 px-3 py-2 custom-hover"><%= term %></span>
|
|
52
|
+
<span class="badge text-dark border border-secondary rounded-3 px-3 py-2 custom-hover search-suggestion-term" data-term="<%= term %>" style="cursor: pointer;"><%= term %></span>
|
|
53
53
|
<% end %>
|
|
54
54
|
</div>
|
|
55
55
|
</div>
|
|
@@ -64,12 +64,27 @@
|
|
|
64
64
|
dropdown.classList.remove("d-none");
|
|
65
65
|
});
|
|
66
66
|
|
|
67
|
+
input.addEventListener("focus", () => {
|
|
68
|
+
dropdown.classList.remove("d-none");
|
|
69
|
+
});
|
|
70
|
+
|
|
67
71
|
document.addEventListener("click", (e) => {
|
|
68
72
|
if (!dropdown.contains(e.target) && e.target !== input) {
|
|
69
73
|
dropdown.classList.add("d-none");
|
|
70
74
|
}
|
|
71
75
|
});
|
|
72
76
|
|
|
77
|
+
// Handle clicks on search suggestion terms
|
|
78
|
+
document.querySelectorAll(".search-suggestion-term").forEach((element) => {
|
|
79
|
+
element.addEventListener("click", (e) => {
|
|
80
|
+
e.preventDefault();
|
|
81
|
+
const term = element.getAttribute("data-term");
|
|
82
|
+
input.value = term;
|
|
83
|
+
input.focus();
|
|
84
|
+
// Keep dropdown open so user can continue typing
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
|
|
73
88
|
// Optional: shortcut CMD+K
|
|
74
89
|
document.addEventListener("keydown", (e) => {
|
|
75
90
|
if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") {
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
<div class="col-sm-9 checkbox-label">
|
|
48
48
|
<label for="<%= "cb_adj_#{ii.invoice_item_id}" %>" class="d-flex align-items-center gap-2 mb-1">
|
|
49
49
|
<input type="checkbox" id="<%= "cb_adj_#{ii.invoice_item_id}" %>">
|
|
50
|
-
<%= Kaui.refund_invoice_description.call(index, ii, bundle_result) %>
|
|
50
|
+
<%= text_field_tag "descriptions[#{ii.invoice_item_id}]", Kaui.refund_invoice_description.call(index, ii, bundle_result), id: "desc_#{ii.invoice_item_id}", class: 'form-control' %>
|
|
51
51
|
</label>
|
|
52
52
|
<%= text_field_tag "adjustments[#{ii.invoice_item_id}]", index, id: "tf_adj_#{ii.invoice_item_id}", value: ii.amount, class: 'form-control checkbox-label' %>
|
|
53
53
|
</div>
|
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
</div>
|
|
132
132
|
<% end %>
|
|
133
133
|
|
|
134
|
-
<% if can?(:create, Kaui::Subscription) || can?(:pause_resume, Kaui::Subscription) || can?(:change_plan, Kaui::Subscription) %>
|
|
134
|
+
<% if can?(:create, Kaui::Subscription) || can?(:pause_resume, Kaui::Subscription) || can?(:change_plan, Kaui::Subscription) || can?(:transfer, Kaui::Bundle) %>
|
|
135
135
|
<% menu_items = [] %>
|
|
136
136
|
|
|
137
137
|
<% if can?(:change_plan, Kaui::Subscription) %>
|
|
@@ -173,6 +173,14 @@
|
|
|
173
173
|
} %>
|
|
174
174
|
<% end %>
|
|
175
175
|
|
|
176
|
+
<% if can?(:transfer, Kaui::Bundle) && sub.product_category != 'ADD_ON' %>
|
|
177
|
+
<% menu_items << {
|
|
178
|
+
label: I18n.translate('transfer'),
|
|
179
|
+
path: kaui_engine.transfer_bundle_path(bundle.bundle_id),
|
|
180
|
+
icon: "kaui/subscription/transfer.svg"
|
|
181
|
+
} %>
|
|
182
|
+
<% end %>
|
|
183
|
+
|
|
176
184
|
<%= render partial: "kaui/components/menu_dropdown/menu_dropdown", locals: {
|
|
177
185
|
variant: "btn-light",
|
|
178
186
|
label: "",
|
data/config/locales/en.yml
CHANGED
|
@@ -18,9 +18,9 @@ en:
|
|
|
18
18
|
custom_field_uuid_exist_in_invoice_payment_db: "UUID do exist in INVOICE PAYMENT object database."
|
|
19
19
|
custom_field_uuid_do_not_exist_in_db: "UUID do not exist in object database."
|
|
20
20
|
custom_field_uuid_exist_in_invoice_item_db: "UUID do exist in INVOICE ITEMS object database."
|
|
21
|
-
immediate: "
|
|
22
|
-
start_of_term: "
|
|
23
|
-
end_of_term: "
|
|
21
|
+
immediate: "IMMEDIATE"
|
|
22
|
+
start_of_term: "START_OF_TERM"
|
|
23
|
+
end_of_term: "END_OF_TERM"
|
|
24
24
|
billing_policy: "Billing Policy"
|
|
25
25
|
new_account_id_or_external_key: "New account id or external key"
|
|
26
26
|
object_invalid_dont_exist: "Object type INVALID or object id do not exist."
|
data/lib/kaui/error_handler.rb
CHANGED
|
@@ -7,31 +7,41 @@ module Kaui
|
|
|
7
7
|
|
|
8
8
|
included do
|
|
9
9
|
rescue_from(StandardError) do |error|
|
|
10
|
-
|
|
10
|
+
error_message = "Error: #{as_string(error)}"
|
|
11
11
|
try_to_redirect_to_account_path = !params[:controller].ends_with?('accounts')
|
|
12
|
-
perform_redirect_after_error(redirect: try_to_redirect_to_account_path)
|
|
12
|
+
perform_redirect_after_error(redirect: try_to_redirect_to_account_path, error:, error_message:)
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
rescue_from(ActionController::ParameterMissing) do |parameter_missing_exception|
|
|
16
16
|
log_rescue_error parameter_missing_exception
|
|
17
|
-
|
|
18
|
-
perform_redirect_after_error
|
|
17
|
+
error_message = "Required parameter missing: #{parameter_missing_exception.param}"
|
|
18
|
+
perform_redirect_after_error(error: parameter_missing_exception, error_message:)
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
rescue_from(KillBillClient::API::ResponseError) do |killbill_exception|
|
|
22
|
-
|
|
22
|
+
error_message = "Error while communicating with the Kill Bill server: #{as_string(killbill_exception)}"
|
|
23
23
|
try_to_redirect_to_account_path = !killbill_exception.is_a?(KillBillClient::API::Unauthorized) && !(killbill_exception.is_a?(KillBillClient::API::NotFound) && params[:controller].ends_with?('accounts'))
|
|
24
|
-
perform_redirect_after_error(redirect: try_to_redirect_to_account_path)
|
|
24
|
+
perform_redirect_after_error(redirect: try_to_redirect_to_account_path, error: killbill_exception, error_message:)
|
|
25
25
|
end
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
def perform_redirect_after_error(redirect: true)
|
|
28
|
+
def perform_redirect_after_error(error:, error_message:, redirect: true)
|
|
29
29
|
account_id = nested_hash_value(params.permit!.to_h, :account_id)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
home_path = kaui_engine.home_path
|
|
31
|
+
redirect_path = if redirect && account_id.present?
|
|
32
|
+
kaui_engine.account_path(account_id)
|
|
33
|
+
else
|
|
34
|
+
home_path
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
redirect_path_without_query = redirect_path.to_s.split('?').first
|
|
38
|
+
already_on_redirect_target = request.path == redirect_path_without_query
|
|
39
|
+
already_on_home = params[:controller].to_s.ends_with?('home') && action_name == 'index'
|
|
40
|
+
|
|
41
|
+
raise error if already_on_redirect_target || (redirect_path == home_path && already_on_home)
|
|
42
|
+
|
|
43
|
+
flash[:error] = error_message
|
|
44
|
+
redirect_to redirect_path
|
|
35
45
|
end
|
|
36
46
|
end
|
|
37
47
|
end
|
data/lib/kaui/version.rb
CHANGED
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
|
+
version: 4.0.11
|
|
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: 2026-03-
|
|
11
|
+
date: 2026-03-25 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: actionpack
|
|
@@ -373,6 +373,7 @@ files:
|
|
|
373
373
|
- app/assets/images/kaui/subscription/change.svg
|
|
374
374
|
- app/assets/images/kaui/subscription/date.svg
|
|
375
375
|
- app/assets/images/kaui/subscription/pause.svg
|
|
376
|
+
- app/assets/images/kaui/subscription/transfer.svg
|
|
376
377
|
- app/assets/images/kaui/timeline/authorize.svg
|
|
377
378
|
- app/assets/images/kaui/timeline/capture.svg
|
|
378
379
|
- app/assets/images/kaui/timeline/chargeback.svg
|