kaui 2.0.0 → 2.1.0
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 +5 -5
- data/README.md +5 -29
- data/app/assets/javascripts/kaui/kaui.js +1 -1
- data/app/assets/stylesheets/kaui/account.less +9 -1
- data/app/assets/stylesheets/kaui/common.less +46 -3
- data/app/controllers/kaui/accounts_controller.rb +11 -15
- data/app/controllers/kaui/admin_tenants_controller.rb +77 -106
- data/app/controllers/kaui/audit_logs_controller.rb +3 -3
- data/app/controllers/kaui/bundles_controller.rb +4 -0
- data/app/controllers/kaui/engine_controller_util.rb +25 -17
- data/app/controllers/kaui/invoice_tags_controller.rb +28 -0
- data/app/controllers/kaui/invoices_controller.rb +65 -14
- data/app/controllers/kaui/payment_methods_controller.rb +14 -3
- data/app/controllers/kaui/sessions_controller.rb +6 -0
- data/app/controllers/kaui/subscriptions_controller.rb +13 -4
- data/app/helpers/kaui/account_helper.rb +10 -2
- data/app/helpers/kaui/payment_method_helper.rb +5 -3
- data/app/helpers/kaui/plugin_helper.rb +10 -49
- data/app/helpers/kaui/subscription_helper.rb +26 -9
- data/app/helpers/kaui/uuid_helper.rb +1 -0
- data/app/models/kaui/admin_tenant.rb +8 -84
- data/app/models/kaui/catalog.rb +28 -2
- data/app/models/kaui/tag.rb +1 -1
- data/app/views/kaui/account_emails/_form.html.erb +1 -1
- data/app/views/kaui/accounts/_billing_info.html.erb +4 -0
- data/app/views/kaui/accounts/_form.html.erb +1 -1
- data/app/views/kaui/accounts/_payment_methods.html.erb +3 -0
- data/app/views/kaui/accounts/index.html.erb +7 -4
- data/app/views/kaui/admin_tenants/_form_plugin_config.erb +59 -241
- data/app/views/kaui/admin_tenants/_show_catalog_simple.erb +2 -2
- data/app/views/kaui/admin_tenants/new_catalog.html.erb +16 -15
- data/app/views/kaui/bundles/_bundle_details.html.erb +12 -0
- data/app/views/kaui/bundles/index.html.erb +3 -14
- data/app/views/kaui/chargebacks/_form.html.erb +1 -1
- data/app/views/kaui/charges/_form.html.erb +1 -1
- data/app/views/kaui/invoice_tags/_form.html.erb +33 -0
- data/app/views/kaui/invoice_tags/_form_bar.html.erb +21 -0
- data/app/views/kaui/invoice_tags/edit.html.erb +10 -0
- data/app/views/kaui/invoices/_invoice_table.html.erb +30 -9
- data/app/views/kaui/invoices/index.html.erb +6 -4
- data/app/views/kaui/invoices/show.html.erb +11 -2
- data/app/views/kaui/layouts/kaui_flash.html.erb +8 -1
- data/app/views/kaui/payments/_form.html.erb +1 -1
- data/app/views/kaui/payments/_payment_table.html.erb +2 -2
- data/app/views/kaui/payments/index.html.erb +3 -1
- data/app/views/kaui/subscriptions/_edit_form.html.erb +1 -1
- data/app/views/kaui/subscriptions/_form.html.erb +1 -1
- data/app/views/kaui/subscriptions/_subscriptions_table.html.erb +3 -3
- data/config/routes.rb +6 -1
- data/lib/kaui.rb +55 -0
- data/lib/kaui/version.rb +1 -1
- data/test/dummy/config/database.yml +2 -2
- data/test/dummy/config/initializers/cookies_serializer.rb +1 -1
- data/test/dummy/config/initializers/money.rb +2 -0
- data/test/functional/kaui/account_emails_controller_test.rb +2 -2
- data/test/functional/kaui/account_tags_controller_test.rb +1 -1
- data/test/functional/kaui/accounts_controller_test.rb +4 -4
- data/test/functional/kaui/admin_tenants_controller_test.rb +3 -23
- data/test/functional/kaui/bundle_tags_controller_test.rb +1 -1
- data/test/functional/kaui/bundles_controller_test.rb +3 -3
- data/test/functional/kaui/chargebacks_controller_test.rb +2 -2
- data/test/functional/kaui/charges_controller_test.rb +2 -2
- data/test/functional/kaui/credits_controller_test.rb +5 -5
- data/test/functional/kaui/home_controller_test.rb +5 -5
- data/test/functional/kaui/invoice_items_controller_test.rb +3 -3
- data/test/functional/kaui/invoices_controller_test.rb +2 -2
- data/test/functional/kaui/refunds_controller_test.rb +2 -2
- data/test/functional/kaui/subscriptions_controller_test.rb +6 -6
- data/test/killbill_test_helper.rb +8 -6
- data/test/unit/helpers/kaui/payment_method_helper_test.rb +17 -0
- data/test/unit/kaui/account_test.rb +2 -2
- data/test/unit/kaui/admin_tenant_test.rb +10 -47
- data/test/unit/kaui/invoice_item_test.rb +1 -1
- data/test/unit/kaui/invoice_payment_test.rb +7 -7
- data/test/unit/kaui/invoice_test.rb +4 -4
- data/test/unit/kaui/payment_test.rb +7 -7
- metadata +110 -86
@@ -10,25 +10,39 @@ module Kaui
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def humanized_product_category(product_category)
|
13
|
-
if product_category == 'BASE'
|
13
|
+
if product_category.to_s == 'BASE'
|
14
14
|
'Base'
|
15
|
-
elsif product_category == 'ADD_ON'
|
15
|
+
elsif product_category.to_s == 'ADD_ON'
|
16
16
|
'Add-on'
|
17
17
|
else
|
18
|
-
product_category.downcase.capitalize
|
18
|
+
product_category.to_s.downcase.capitalize
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
def humanized_subscription_product_name(sub)
|
23
|
-
if !sub.present?
|
22
|
+
def humanized_subscription_product_name(sub, catalog = nil)
|
23
|
+
if !sub.present? || !sub.product_name.present?
|
24
24
|
nil
|
25
25
|
else
|
26
|
-
|
26
|
+
product = catalog.nil? ? nil : catalog.products.find { |p| p.name == sub.product_name }
|
27
|
+
humanized_product_name(!product.nil? && !product.pretty_name.blank? ? product.pretty_name : sub.product_name)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def humanized_subscription_pretty_plan_name(sub, catalog = nil)
|
32
|
+
if !sub.present? || !sub.product_name.present?
|
33
|
+
nil
|
34
|
+
else
|
35
|
+
product = catalog.nil? ? nil : catalog.products.find { |p| p.name == sub.product_name }
|
36
|
+
return nil if product.nil?
|
37
|
+
|
38
|
+
plan = product.plans.find { |p| p.name == sub.plan_name }
|
39
|
+
plan.nil? || plan.pretty_name.blank? ? nil : plan.pretty_name
|
27
40
|
end
|
28
41
|
end
|
29
42
|
|
30
43
|
def humanized_product_name(product_name)
|
31
|
-
|
44
|
+
# Don't change the casing to avoid confusions (could lead to different products with different casing)
|
45
|
+
product_name
|
32
46
|
end
|
33
47
|
|
34
48
|
def humanized_subscription_billing_period(sub)
|
@@ -55,8 +69,11 @@ module Kaui
|
|
55
69
|
end
|
56
70
|
end
|
57
71
|
|
58
|
-
def
|
59
|
-
|
72
|
+
def humanized_subscription_plan_or_product_name(sub, catalog = nil)
|
73
|
+
pretty_plan_name = humanized_subscription_pretty_plan_name(sub, catalog)
|
74
|
+
return pretty_plan_name unless pretty_plan_name.nil?
|
75
|
+
|
76
|
+
humanized_product_name = humanized_subscription_product_name(sub, catalog)
|
60
77
|
humanized_billing_period = humanized_subscription_billing_period(sub)
|
61
78
|
humanized_price_list = humanized_subscription_price_list(sub, false)
|
62
79
|
|
@@ -26,81 +26,21 @@ class Kaui::AdminTenant < KillBillClient::Model::Tenant
|
|
26
26
|
KillBillClient::Model::Tenant.upload_tenant_plugin_config(plugin_name, plugin_config, user, reason, comment, options)
|
27
27
|
end
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
require 'yaml'
|
32
|
-
|
33
|
-
source = URI.parse('https://raw.githubusercontent.com/killbill/killbill-cloud/master/kpm/lib/kpm/plugins_directory.yml').read
|
34
|
-
YAML.load(source)
|
35
|
-
rescue
|
36
|
-
# Ignore gracefully
|
37
|
-
{}
|
38
|
-
end
|
39
|
-
|
40
|
-
def get_oss_plugin_info(plugin_directory)
|
41
|
-
# Serialize the plugin state for the view:
|
42
|
-
# plugin_name#plugin_type:prop1,prop2,prop3;plugin_name#plugin_type:prop1,prop2,prop3;...
|
43
|
-
#
|
44
|
-
plugin_config = plugin_directory.inject({}) do |hsh, (k,v)|
|
45
|
-
hsh["#{k}##{v[:type]}"] = v[:require] || []
|
46
|
-
hsh
|
47
|
-
end
|
48
|
-
plugin_config.map { |e,v| "#{e}:#{v.join(",")}" }.join(";")
|
49
|
-
end
|
50
|
-
|
51
|
-
def get_tenant_plugin_config(plugin_directory, options)
|
52
|
-
require 'yaml'
|
53
|
-
|
29
|
+
# Return a map of plugin_name => config
|
30
|
+
def get_tenant_plugin_config(options)
|
54
31
|
raw_tenant_config = KillBillClient::Model::Tenant::search_tenant_config("PLUGIN_CONFIG_", options)
|
55
32
|
|
56
33
|
tenant_config = raw_tenant_config.inject({}) do |hsh, e|
|
57
34
|
# Strip prefix '/PLUGIN_CONFIG_'
|
58
|
-
|
59
|
-
|
60
|
-
#
|
61
|
-
|
62
|
-
|
63
|
-
# hack:: rewrite key, to allow the ui to find the right configuration inputs
|
64
|
-
plugin_key = rewrite_plugin_key(plugin_key) unless plugin_key.nil?
|
65
|
-
# If such key exists, lookup in plugin directory to see if is an official plugin
|
66
|
-
is_an_official_plugin = !plugin_key.nil? && !plugin_directory[plugin_key.to_sym].blank?
|
67
|
-
# Deserialize config based on string possible format, if exist in the official repository
|
68
|
-
if is_an_official_plugin && is_yaml?(e.values[0])
|
69
|
-
yml = YAML.load(e.values[0])
|
70
|
-
# Hash of properties
|
71
|
-
# is plugin key part of the yaml?
|
72
|
-
if yml[plugin_key.to_sym].blank?
|
73
|
-
# if not set it as raw
|
74
|
-
hsh[plugin_key] = {:raw_config => e.values[0]}
|
75
|
-
else
|
76
|
-
hsh[plugin_key] = yml[plugin_key.to_sym]
|
77
|
-
end
|
78
|
-
hsh[plugin_key][:_raw] = e.values[0]
|
79
|
-
elsif is_an_official_plugin && is_kv?(e.values[0])
|
80
|
-
# Construct hash of properties based on java properties (k1=v1\nk2=v2\n...)
|
81
|
-
hsh[plugin_key] = e.values[0].split("\n").inject({}) do |h, p0|
|
82
|
-
k, v = p0.split('=');
|
83
|
-
h[k] = v;
|
84
|
-
h
|
85
|
-
end
|
86
|
-
hsh[plugin_key][:_raw] = e.values[0]
|
87
|
-
else
|
88
|
-
# Construct simple hash with one property :raw_config
|
89
|
-
hsh[killbill_key] = {:raw_config => e.values[0], :_raw => e.values[0]}
|
90
|
-
end
|
35
|
+
plugin_name = e.key.gsub!(/PLUGIN_CONFIG_/, '')
|
36
|
+
|
37
|
+
# Construct simple hash with one property (first value)
|
38
|
+
hsh[plugin_name] = e.values[0]
|
39
|
+
|
91
40
|
hsh
|
92
41
|
end
|
93
42
|
|
94
|
-
|
95
|
-
# plugin_key1::key1=value1|key2=value2|..;plugin_key2::...
|
96
|
-
tenant_config.map do |plugin_key, props|
|
97
|
-
serialized_props = props.inject("") do |s, (k, v)|
|
98
|
-
e="#{k.to_s}=#{v.to_s}";
|
99
|
-
s == "" ? s="#{e}" : s="#{s}|#{e}";
|
100
|
-
s
|
101
|
-
end
|
102
|
-
"#{plugin_key}::#{serialized_props}"
|
103
|
-
end.join(";")
|
43
|
+
tenant_config
|
104
44
|
end
|
105
45
|
|
106
46
|
def format_plugin_config(plugin_key, plugin_type, props)
|
@@ -142,22 +82,6 @@ class Kaui::AdminTenant < KillBillClient::Model::Tenant
|
|
142
82
|
props
|
143
83
|
end
|
144
84
|
|
145
|
-
# hack when the plugin name after killbill is not the same as the plugin key, this mainly affects ruby plugin configuration,
|
146
|
-
# as it use the key to retrieve the configuration.
|
147
|
-
def rewrite_plugin_key(plugin_key)
|
148
|
-
if plugin_key.start_with?('paypal')
|
149
|
-
'paypal_express'
|
150
|
-
elsif plugin_key.start_with?('firstdata')
|
151
|
-
'firstdata_e4'
|
152
|
-
elsif plugin_key.start_with?('bridge')
|
153
|
-
'payment_bridge'
|
154
|
-
elsif plugin_key.start_with?('payu-latam')
|
155
|
-
'payu_latam'
|
156
|
-
else
|
157
|
-
"#{plugin_key}"
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
85
|
# checks if string could be parse as yaml
|
162
86
|
def is_yaml?(candidate_string)
|
163
87
|
is_yaml = false
|
data/app/models/kaui/catalog.rb
CHANGED
@@ -4,9 +4,35 @@ class Kaui::Catalog < KillBillClient::Model::Catalog
|
|
4
4
|
|
5
5
|
class << self
|
6
6
|
|
7
|
-
def
|
7
|
+
def get_account_catalog_json(account_id, requested_date = nil, options = {})
|
8
|
+
params = {}
|
9
|
+
params[:accountId] = account_id
|
10
|
+
params[:requestedDate] = requested_date if requested_date
|
11
|
+
|
12
|
+
get KillBillClient::Model::Catalog::KILLBILL_API_CATALOG_PREFIX,
|
13
|
+
params,
|
14
|
+
{
|
15
|
+
:head => {'Accept' => "application/json"},
|
16
|
+
:content_type => "application/json",
|
17
|
+
|
18
|
+
}.merge(options)
|
19
|
+
end
|
8
20
|
|
9
|
-
|
21
|
+
def get_tenant_catalog_json(requested_date = nil, options = {})
|
22
|
+
super
|
23
|
+
rescue ::KillBillClient::API::InternalServerError => e
|
24
|
+
if !e.response.nil? && !e.response.body.nil?
|
25
|
+
error_message = JSON.parse(e.response.body) rescue nil
|
26
|
+
raise e if error_message.nil? || error_message['message'].nil?
|
27
|
+
|
28
|
+
# Hack for lack of proper Kill Bill messaging (see https://github.com/killbill/killbill-admin-ui/issues/265)
|
29
|
+
return [] if error_message['message'].starts_with?('No existing versions')
|
30
|
+
end
|
31
|
+
raise e
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_catalog_json(latest, requested_date, options)
|
35
|
+
catalogs = get_tenant_catalog_json(requested_date, options)
|
10
36
|
return catalogs.length > 0 ? catalogs[catalogs.length - 1] : nil if latest
|
11
37
|
|
12
38
|
# Order by latest
|
data/app/models/kaui/tag.rb
CHANGED
@@ -9,7 +9,7 @@ class Kaui::Tag < KillBillClient::Model::Tag
|
|
9
9
|
end
|
10
10
|
|
11
11
|
class << self
|
12
|
-
[:account, :bundle, :subscription].each do |model|
|
12
|
+
[:account, :bundle, :subscription, :invoice].each do |model|
|
13
13
|
define_method "all_for_#{model.to_s}" do |model_id, included_deleted, audit, options|
|
14
14
|
instance = Kaui.const_get(model.to_s.camelize).new("#{model.to_s}_id".to_sym => model_id)
|
15
15
|
instance.tags(included_deleted, audit, options)
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<div class='form-group'>
|
3
3
|
<%= f.label :email, 'Email', :class => 'col-sm-2 control-label' %>
|
4
4
|
<div class="col-sm-10">
|
5
|
-
<%= f.
|
5
|
+
<%= f.email_field :email, :class => 'form-control', :required => true %>
|
6
6
|
</div>
|
7
7
|
</div>
|
8
8
|
<div class="form-group">
|
@@ -25,6 +25,10 @@
|
|
25
25
|
<%= link_to '<i class="fa fa-plus-square"></i> Create charge'.html_safe,
|
26
26
|
kaui_engine.new_account_charge_path(@account.account_id, :currency => @account.currency) %>
|
27
27
|
<% end %>
|
28
|
+
<% if deposit_plugin_available? %>
|
29
|
+
<%= link_to '<i class="fa fa-plus-square"></i> Create deposit'.html_safe,
|
30
|
+
deposit_engine.collection_index_path(:account_id => @account.account_id, :currency => @account.currency) %>
|
31
|
+
<% end %>
|
28
32
|
</div>
|
29
33
|
</div>
|
30
34
|
</div>
|
@@ -38,7 +38,7 @@
|
|
38
38
|
<div class="form-group">
|
39
39
|
<%= f.label :email, 'Email', :class => 'col-sm-3 control-label' %>
|
40
40
|
<div class="col-sm-9">
|
41
|
-
<%= f.
|
41
|
+
<%= f.email_field :email, :class => 'form-control' %>
|
42
42
|
</div>
|
43
43
|
</div>
|
44
44
|
<% unless @account.persisted? %>
|
@@ -7,6 +7,9 @@
|
|
7
7
|
<%= link_to '<i class="fa fa-plus-square"></i>'.html_safe,
|
8
8
|
kaui_engine.new_payment_method_path(:account_id => @account.account_id),
|
9
9
|
:class => 'btn btn-xs' %>
|
10
|
+
<%= form_tag kaui_engine.refresh_payment_methods_path(params.to_h), :method => :post, :class => 'form-force-inline form-right' do %>
|
11
|
+
<%= button_tag '<i class="fa fa-refresh"></i>'.html_safe, :class => 'btn btn-xs' %>
|
12
|
+
<% end %>
|
10
13
|
<% end %>
|
11
14
|
</h1>
|
12
15
|
|
@@ -13,8 +13,9 @@
|
|
13
13
|
<tr>
|
14
14
|
<th></th>
|
15
15
|
<th>ID</th>
|
16
|
-
|
17
|
-
|
16
|
+
<% Kaui.account_search_columns.call()[0].each do |title| %>
|
17
|
+
<th><%= title %></th>
|
18
|
+
<% end %>
|
18
19
|
</tr>
|
19
20
|
</thead>
|
20
21
|
<tbody>
|
@@ -39,8 +40,10 @@ $(document).ready(function() {
|
|
39
40
|
},
|
40
41
|
"pageLength": <%= @limit %>,
|
41
42
|
"displayStart": <%= @offset %>,
|
42
|
-
<%
|
43
|
-
|
43
|
+
<% if @search_query.blank? %>
|
44
|
+
"ordering": false,
|
45
|
+
<% elsif !@ordering.blank? %>
|
46
|
+
"order": [[ 1, "<%= @ordering %>" ]],
|
44
47
|
<% end %>
|
45
48
|
"processing": true,
|
46
49
|
"serverSide": true,
|
@@ -17,9 +17,10 @@
|
|
17
17
|
|
18
18
|
<div id="plugin" class="form-group">
|
19
19
|
<%= label_tag :entered_plugin_name, 'Plugin name', :class => 'col-sm-2 control-label' %>
|
20
|
+
|
20
21
|
<div class="col-sm-4">
|
21
22
|
<select class="form-control" id="select_plugin_name"></select>
|
22
|
-
<%= text_field_tag :entered_plugin_name, nil, :
|
23
|
+
<%= text_field_tag :entered_plugin_name, nil, :placeholder => 'as defined in the plugin Activator file', :class => 'form-control', :tenant_plugin_config => @tenant_plugin_config.to_json %>
|
23
24
|
<div class="text plugin-suggestion text-danger"></div>
|
24
25
|
</div>
|
25
26
|
<div class="col-sm-1 spinner"><i class="fa fa-cog fa-2x fa-spin"></i></div>
|
@@ -29,7 +30,7 @@
|
|
29
30
|
<span class="slider round"></span>
|
30
31
|
</label>
|
31
32
|
</label>
|
32
|
-
<label class="col-sm-3 control-label toggle-label text-muted">
|
33
|
+
<label class="col-sm-3 control-label toggle-label text-muted">manual entry</label>
|
33
34
|
</div>
|
34
35
|
|
35
36
|
<div id="plugin_config_properties_header" class="form-group">
|
@@ -41,8 +42,11 @@
|
|
41
42
|
</label>
|
42
43
|
</label>
|
43
44
|
</div>
|
44
|
-
|
45
|
-
|
45
|
+
<div class="form-group">
|
46
|
+
<%= label_tag :configuration, 'Configuration', :class => 'col-sm-2 control-label' %>
|
47
|
+
<div class="col-sm-6">
|
48
|
+
<textarea name="plugin_properties[raw_config]" id="raw_config" rows="20" class="form-control"></textarea>
|
49
|
+
</div>
|
46
50
|
</div>
|
47
51
|
|
48
52
|
<div class="form-group">
|
@@ -54,23 +58,6 @@
|
|
54
58
|
</div>
|
55
59
|
<% end %>
|
56
60
|
|
57
|
-
<script id="plugin_config_properties_template" type="text/template">
|
58
|
-
<input type="hidden" id="plugin_key_values" value="{{data_json}}" />
|
59
|
-
{{#plugin_props_with_values}}
|
60
|
-
<div class="form-group">
|
61
|
-
<label class="col-sm-offset-1 col-sm-2 control-label" for="{{property}}">{{property_label}}</label>
|
62
|
-
<div class="col-sm-6">
|
63
|
-
{{#is_raw_config}}
|
64
|
-
<textarea name="plugin_properties[raw_config]" id="raw_config" rows="10" class="form-control">{{value}}</textarea>
|
65
|
-
{{/is_raw_config}}
|
66
|
-
{{^is_raw_config}}
|
67
|
-
<input type="text" name="plugin_properties[{{property}}]" id="{{property}}" class="form-control" value="{{value}}" />
|
68
|
-
{{/is_raw_config}}
|
69
|
-
</div>
|
70
|
-
</div>
|
71
|
-
{{/plugin_props_with_values}}
|
72
|
-
</script>
|
73
|
-
|
74
61
|
<script id="plugin_name_options_template" type="text/template">
|
75
62
|
<option></option>
|
76
63
|
{{#plugin_repository}}
|
@@ -101,48 +88,54 @@
|
|
101
88
|
$('#plugin_config_properties').empty();
|
102
89
|
$('#plugin_config_properties_header').hide();
|
103
90
|
$(".plugin-suggestion").html('');
|
91
|
+
$("#raw_config").val('');
|
104
92
|
});
|
105
93
|
|
106
|
-
|
107
|
-
|
108
|
-
|
94
|
+
/* Intercept TAB and potentially display known properties */
|
95
|
+
$('#entered_plugin_name').keydown(function (e) {
|
96
|
+
if (e.keyCode === 9) {
|
97
|
+
$("#plugin_name").val($('#entered_plugin_name').val());
|
98
|
+
$("#plugin_key").val('');
|
99
|
+
render_plugin_key_values();
|
109
100
|
}
|
101
|
+
});
|
102
|
+
/* Intercept mouseleave and potentially display known properties */
|
103
|
+
$('#entered_plugin_name').on('mouseleave', function() {
|
104
|
+
$("#plugin_name").val($('#entered_plugin_name').val());
|
105
|
+
$("#plugin_key").val('');
|
106
|
+
render_plugin_key_values();
|
107
|
+
});
|
110
108
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
var plugin_name = $('#entered_plugin_name').val();
|
117
|
-
var plugin_key = $("#plugin_key").val();
|
118
|
-
var existing_props = get_tenant_plugin_properties(plugin_key, plugin_name);
|
119
|
-
raw[0].value = existing_props['_raw'];
|
120
|
-
|
121
|
-
render_plugin_key_values(raw, plugin_key_values);
|
122
|
-
} else {
|
123
|
-
render_plugin_key_values(plugin_key_values, plugin_key_values);
|
124
|
-
}
|
109
|
+
$("#toggle_raw").on('change', function(e) {
|
110
|
+
$("#plugin_name").val($('#entered_plugin_name').val());
|
111
|
+
$("#plugin_key").val('');
|
112
|
+
render_plugin_key_values();
|
125
113
|
});
|
126
114
|
|
127
115
|
$('#select_plugin_name').on('change', function(e) {
|
116
|
+
// User has selected a plugin from the dropdown
|
128
117
|
var selectedOption = e.target.selectedOptions;
|
129
118
|
|
130
119
|
if (selectedOption.length > 0) {
|
131
120
|
var plugin_name = selectedOption[0].value;
|
132
121
|
var plugin_key = selectedOption[0].text;
|
122
|
+
|
133
123
|
$("#plugin_name").val(plugin_name);
|
134
124
|
$("#plugin_key").val(plugin_key);
|
135
|
-
$("#plugin_type").val(selectedOption[0].dataset['pluginType']);
|
125
|
+
$("#plugin_type").val(selectedOption[0].dataset['pluginType']); // java or ruby
|
136
126
|
$('#plugin_config_properties').attr('plugin_name', '');
|
137
127
|
$('#plugin_config_properties_header').hide();
|
138
128
|
$("#toggle_raw").prop('checked', false);
|
139
|
-
|
129
|
+
|
130
|
+
render_plugin_key_values();
|
140
131
|
}
|
141
132
|
});
|
142
133
|
|
143
134
|
populate_plugin_name_options();
|
144
135
|
function populate_plugin_name_options(){
|
145
|
-
var
|
136
|
+
var all_plugins = JSON.parse($("#plugin_repository").val());
|
137
|
+
// We only list installed plugins as to not confuse the user
|
138
|
+
var plugin_repository = all_plugins.filter(plugin => plugin.installed);
|
146
139
|
for (var idx = 0, size = plugin_repository.length; idx < size; idx++) {
|
147
140
|
if (idx == 0 && plugin_repository[idx].installed) {
|
148
141
|
plugin_repository[idx]['start_installed'] = true;
|
@@ -163,225 +156,50 @@
|
|
163
156
|
}
|
164
157
|
|
165
158
|
var template = $("#plugin_name_options_template").html();
|
166
|
-
var options_html = Mustache.render( template , { plugin_repository: plugin_repository});
|
159
|
+
var options_html = Mustache.render( template , { plugin_repository: plugin_repository });
|
167
160
|
$("#select_plugin_name").html(options_html);
|
168
161
|
}
|
169
162
|
|
170
163
|
function get_existing_tenant_plugin_properties(entered_plugin_name) {
|
171
164
|
var tenant_plugin_properties = $('#entered_plugin_name').attr('tenant_plugin_config');
|
172
|
-
var res =
|
173
|
-
|
174
|
-
$.each(tenant_plugin_properties.split(';'), function(idx, el) {
|
175
|
-
var el_parts = el.split('::');
|
176
|
-
var el_plugin_name = el_parts[0];
|
177
|
-
var el_props = el_parts[1];
|
178
|
-
if (el_plugin_name === entered_plugin_name) {
|
179
|
-
if (el_props.split('=')[0] == 'raw_config') {
|
180
|
-
res['raw_config'] = el_props.replace("raw_config=", "");
|
181
|
-
} else {
|
182
|
-
$.map(el_props.split('|'), function(el) {
|
183
|
-
var parts = el.split('=');
|
184
|
-
res[parts[0]] = parts.slice(1).join('=');
|
185
|
-
});
|
186
|
-
}
|
187
|
-
return false;
|
188
|
-
}
|
189
|
-
});
|
190
|
-
}
|
191
|
-
return res;
|
192
|
-
}
|
193
|
-
|
194
|
-
function get_selected_plugin_info(plugin_key) {
|
195
|
-
var plugin_config_str = $('#entered_plugin_name').attr('plugin_config');
|
196
|
-
var res = {}
|
197
|
-
/* Deserialize plugin/properties (see AdminTenant model)*/
|
198
|
-
$.each(plugin_config_str.split(';'), function(idx, el) {
|
199
|
-
var el_parts = el.split(':');
|
200
|
-
var el_parts_key = el_parts[0].split('#');
|
201
|
-
var el_plugin_name = el_parts_key[0];
|
202
|
-
var el_plugin_type = el_parts_key[1];
|
203
|
-
var el_plugin_props = el_parts[1];
|
204
|
-
if (el_plugin_name == plugin_key) {
|
205
|
-
res['type'] = el_plugin_type;
|
206
|
-
res['props'] = el_plugin_props == "" ? [] : (el_plugin_type == "" ? ['raw_config'] : el_plugin_props.split(','));
|
207
|
-
return false;
|
208
|
-
}
|
209
|
-
});
|
210
|
-
|
211
|
-
if (isBlank(res['props'])) {
|
212
|
-
res['type'] = '';
|
213
|
-
res['props'] = ['raw_config'];
|
214
|
-
}
|
215
|
-
|
216
|
-
return res;
|
165
|
+
var res = JSON.parse(tenant_plugin_properties);
|
166
|
+
return res[entered_plugin_name];
|
217
167
|
}
|
218
168
|
|
219
169
|
function get_tenant_plugin_properties(plugin_key, plugin_name) {
|
220
170
|
/* Retrieve existing plugin properties for this tenant */
|
221
171
|
var existing_props = get_existing_tenant_plugin_properties(plugin_key);
|
222
172
|
|
223
|
-
//
|
224
|
-
if (isBlank(existing_props)) {
|
173
|
+
// Try by plugin name for proprietary plugins
|
174
|
+
if (isBlank(existing_props) && !isBlank(plugin_name)) {
|
225
175
|
existing_props = get_existing_tenant_plugin_properties(plugin_name);
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
if (isBlank(plugin_name)) {
|
235
|
-
$('#plugin_config_properties').empty();
|
236
|
-
$('#plugin_config_properties').attr('plugin_name', '');
|
237
|
-
return;
|
238
|
-
}
|
239
|
-
|
240
|
-
if ($('#plugin_config_properties').attr('plugin_name') == plugin_name) {
|
241
|
-
/* Already set...*/
|
242
|
-
return;
|
243
|
-
}
|
244
|
-
|
245
|
-
var existing_props = get_tenant_plugin_properties(plugin_key, plugin_name);
|
246
|
-
|
247
|
-
var type = plugin_info['type'];
|
248
|
-
var props = plugin_info['props']
|
249
|
-
|
250
|
-
if (isBlank(type)) {
|
251
|
-
$(".switch-half-container").hide();
|
252
|
-
} else {
|
253
|
-
$(".switch-half-container").show();
|
254
|
-
}
|
255
|
-
|
256
|
-
$('#plugin_type').val(type);
|
257
|
-
/* Prune the tree to restart from scratch */
|
258
|
-
$('#plugin_config_properties_header').show();
|
259
|
-
$('#plugin_config_properties').empty();
|
260
|
-
$('#plugin_config_properties').append('<div id="plugin_config_properties_anchor" class="col-sm-12"></div>');
|
261
|
-
|
262
|
-
var merged_props_with_values = existing_props;
|
263
|
-
if (props != undefined) {
|
264
|
-
$.each(props, function(idx, p) {
|
265
|
-
if (merged_props_with_values[p] == undefined) {
|
266
|
-
merged_props_with_values[p] = '';
|
176
|
+
if (isBlank(existing_props)) {
|
177
|
+
// For proprietary plugins, the killbill- prefix likely doesn't exist (see Kaui::PluginHelper discussion)
|
178
|
+
plugin_name = plugin_name.replace('killbill-', '');
|
179
|
+
existing_props = get_existing_tenant_plugin_properties(plugin_name);
|
180
|
+
if (isBlank(existing_props)) {
|
181
|
+
// For proprietary plugins, our docs suggest acme:foo as the format for the plugin key, and often the plugin name becomes acme-foo
|
182
|
+
plugin_name = plugin_name.replace(':', '-');
|
183
|
+
existing_props = get_existing_tenant_plugin_properties(plugin_name);
|
267
184
|
}
|
268
|
-
});
|
269
|
-
}
|
270
|
-
|
271
|
-
add_property_form_entry(merged_props_with_values);
|
272
|
-
|
273
|
-
$('#plugin_config_properties').attr('plugin_name', plugin_name);
|
274
|
-
}
|
275
|
-
|
276
|
-
function format_label(input) {
|
277
|
-
/* Keep latest piece of a system property to keep it short */
|
278
|
-
var label_name = input.split('.').pop();
|
279
|
-
/* Replace underscore with comma */
|
280
|
-
label_name = label_name.replace(/_/g, ',');
|
281
|
-
/* Replace uppercase with comma + uppercase */
|
282
|
-
label_name = label_name.replace(/([A-Z]+)/g, ",$1");
|
283
|
-
/* Split name make sure each word starts with Uppercase */
|
284
|
-
var tmp1 = label_name.split(',');
|
285
|
-
var label_name_array = [];
|
286
|
-
$.map(tmp1, function(el) { label_name_array.push(el.charAt(0).toUpperCase() + el.slice(1)) });
|
287
|
-
label_name = label_name_array.join(' ');
|
288
|
-
return label_name;
|
289
|
-
}
|
290
|
-
|
291
|
-
function add_property_form_entry(merged_props_with_values) {
|
292
|
-
var plugin_props_with_values = [];
|
293
|
-
|
294
|
-
$.each(merged_props_with_values, function(p, v) {
|
295
|
-
if (p != '_raw') {
|
296
|
-
plugin_props_with_values.push({ property_label: format_label(p), property: p, value: v, is_raw_config: p == 'raw_config'});
|
297
|
-
}
|
298
|
-
});
|
299
|
-
|
300
|
-
render_plugin_key_values(plugin_props_with_values, plugin_props_with_values);
|
301
|
-
}
|
302
|
-
|
303
|
-
function render_plugin_key_values(plugin_props_with_values, original) {
|
304
|
-
var template = $("#plugin_config_properties_template").html();
|
305
|
-
var plugin_props_with_values_html = Mustache.render( template ,{ plugin_props_with_values: plugin_props_with_values,
|
306
|
-
data_json: JSON.stringify(original)});
|
307
|
-
$("#plugin_config_properties_anchor").html(plugin_props_with_values_html);
|
308
|
-
}
|
309
|
-
|
310
|
-
// Free text related functions and handlers
|
311
|
-
init_plugin_name_handlers();
|
312
|
-
function init_plugin_name_handlers() {
|
313
|
-
/* Intercept ENTER and potentially display property form if plugin is know */
|
314
|
-
$('#entered_plugin_name').keyup(function (e) {
|
315
|
-
e.preventDefault();
|
316
|
-
if (e.keyCode === 13) {
|
317
|
-
suggest_plugin_name();
|
318
185
|
}
|
319
|
-
});
|
320
|
-
|
321
|
-
/* Intercept mouseleave and potentially display property form if plugin is know */
|
322
|
-
$('#entered_plugin_name').on('mouseleave', function() {
|
323
|
-
suggest_plugin_name();
|
324
|
-
});
|
325
|
-
}
|
326
|
-
|
327
|
-
function suggested_response(response) {
|
328
|
-
$(".spinner").hide();
|
329
|
-
if (!isBlank(response.suggestion)) {
|
330
|
-
$(".plugin-suggestion").html(response.suggestion);
|
331
|
-
|
332
|
-
$("#suggested").click(function(e) {
|
333
|
-
var plugin_name = e.currentTarget.dataset['pluginName'];
|
334
|
-
var plugin_key = e.currentTarget.dataset['pluginKey'];
|
335
|
-
|
336
|
-
$("#entered_plugin_name").val(plugin_name);
|
337
|
-
$("#plugin_key").val(plugin_key);
|
338
|
-
$("#plugin_type").val(e.currentTarget.dataset['pluginType']);
|
339
|
-
$("#entered_plugin_name").data("last", plugin_name);
|
340
|
-
|
341
|
-
$(".plugin-suggestion").html('');
|
342
|
-
add_properties_for_plugin(isBlank(plugin_key) ? plugin_name : plugin_key, plugin_name);
|
343
|
-
});
|
344
|
-
|
345
|
-
} else {
|
346
|
-
$(".plugin-suggestion").html('');
|
347
186
|
}
|
348
187
|
|
349
|
-
|
350
|
-
var plugin_key = $("#plugin_key").val();
|
351
|
-
$("#plugin_name").val(plugin_name);
|
352
|
-
|
353
|
-
add_properties_for_plugin(isBlank(plugin_key) ? plugin_name : plugin_key, plugin_name);
|
188
|
+
return existing_props;
|
354
189
|
}
|
355
190
|
|
356
|
-
function
|
357
|
-
var plugin_name =
|
358
|
-
var
|
359
|
-
$(
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
// no change
|
366
|
-
if ( plugin_name == last_plugin_name) {
|
367
|
-
return;
|
191
|
+
function render_plugin_key_values() {
|
192
|
+
var plugin_name = "";
|
193
|
+
var plugin_key = "";
|
194
|
+
if (isBlank($('#entered_plugin_name').val())) {
|
195
|
+
plugin_name = $("#plugin_name").val();
|
196
|
+
plugin_key = $("#plugin_key").val();
|
197
|
+
} else {
|
198
|
+
plugin_name = $("#entered_plugin_name").val();
|
368
199
|
}
|
369
200
|
|
370
|
-
|
371
|
-
$(
|
372
|
-
$(".plugin-suggestion").html('');
|
373
|
-
$("#entered_plugin_name").data("last", plugin_name);
|
374
|
-
$(".spinner").show();
|
375
|
-
$.ajax({
|
376
|
-
url: '<%= suggest_plugin_name_path() %>',
|
377
|
-
type: "GET",
|
378
|
-
dataType: "json",
|
379
|
-
data: {
|
380
|
-
"plugin_name": plugin_name,
|
381
|
-
},
|
382
|
-
success: suggested_response
|
383
|
-
});
|
201
|
+
var existing_props = get_tenant_plugin_properties(plugin_key, plugin_name);
|
202
|
+
$("#raw_config").val(existing_props);
|
384
203
|
}
|
385
|
-
|
386
204
|
});
|
387
|
-
<% end %>
|
205
|
+
<% end %>
|