kaui 3.0.9 → 4.0.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.
Files changed (259) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/kaui/account/authorize.svg +4 -0
  3. data/app/assets/images/kaui/account/credit.svg +4 -0
  4. data/app/assets/images/kaui/account/down-arrow.svg +3 -0
  5. data/app/assets/images/kaui/account/edit.svg +4 -0
  6. data/app/assets/images/kaui/account/pay-all.svg +5 -0
  7. data/app/assets/images/kaui/account/plus.svg +3 -0
  8. data/app/assets/images/kaui/account/purchase.svg +5 -0
  9. data/app/assets/images/kaui/account/refresh.svg +5 -0
  10. data/app/assets/images/kaui/arrow.svg +3 -0
  11. data/app/assets/images/kaui/card.svg +5 -0
  12. data/app/assets/images/kaui/copy.svg +12 -0
  13. data/app/assets/images/kaui/dashboard/aviate.svg +6 -0
  14. data/app/assets/images/kaui/dashboard/custom-field.svg +5 -0
  15. data/app/assets/images/kaui/dashboard/kaui-doc-img.png +0 -0
  16. data/app/assets/images/kaui/dashboard/plugins.svg +7 -0
  17. data/app/assets/images/kaui/dashboard/tags.svg +4 -0
  18. data/app/assets/images/kaui/dashboard/users.svg +6 -0
  19. data/app/assets/images/kaui/delete.svg +6 -0
  20. data/app/assets/images/kaui/dots.svg +5 -0
  21. data/app/assets/images/kaui/download-csv.svg +5 -0
  22. data/app/assets/images/kaui/download.svg +4 -0
  23. data/app/assets/images/kaui/eye-off.svg +9 -0
  24. data/app/assets/images/kaui/eye.svg +7 -0
  25. data/app/assets/images/kaui/file-upload.svg +34 -0
  26. data/app/assets/images/kaui/generate.svg +5 -0
  27. data/app/assets/images/kaui/header/account.svg +4 -0
  28. data/app/assets/images/kaui/header/cog_icon.svg +4 -0
  29. data/app/assets/images/kaui/header/invoice.svg +5 -0
  30. data/app/assets/images/kaui/header/payment.svg +5 -0
  31. data/app/assets/images/kaui/header/search_icon.svg +4 -0
  32. data/app/assets/images/kaui/header/subscription.svg +6 -0
  33. data/app/assets/images/kaui/logout.svg +4 -0
  34. data/app/assets/images/kaui/modal/close.svg +3 -0
  35. data/app/assets/images/kaui/modal/plus.svg +3 -0
  36. data/app/assets/images/kaui/modal/red-close.svg +10 -0
  37. data/app/assets/images/kaui/modal/search.svg +4 -0
  38. data/app/assets/images/kaui/payment/payment.svg +4 -0
  39. data/app/assets/images/kaui/payment/refund.svg +4 -0
  40. data/app/assets/images/kaui/plus.svg +3 -0
  41. data/app/assets/images/kaui/search.svg +4 -0
  42. data/app/assets/images/kaui/setting/account.svg +10 -0
  43. data/app/assets/images/kaui/setting/analytics.svg +7 -0
  44. data/app/assets/images/kaui/setting/custom-field.svg +5 -0
  45. data/app/assets/images/kaui/setting/e-notifications.svg +6 -0
  46. data/app/assets/images/kaui/setting/plugins.svg +7 -0
  47. data/app/assets/images/kaui/setting/plus.svg +3 -0
  48. data/app/assets/images/kaui/setting/reset.svg +4 -0
  49. data/app/assets/images/kaui/setting/tag-definitions.svg +5 -0
  50. data/app/assets/images/kaui/setting/tags.svg +4 -0
  51. data/app/assets/images/kaui/setting/tenants.svg +6 -0
  52. data/app/assets/images/kaui/setting/users.svg +6 -0
  53. data/app/assets/images/kaui/setting.svg +4 -0
  54. data/app/assets/images/kaui/sidebar/account.svg +4 -0
  55. data/app/assets/images/kaui/sidebar/audit.svg +5 -0
  56. data/app/assets/images/kaui/sidebar/custom-fields.svg +5 -0
  57. data/app/assets/images/kaui/sidebar/invoices.svg +5 -0
  58. data/app/assets/images/kaui/sidebar/payments.svg +5 -0
  59. data/app/assets/images/kaui/sidebar/queues.svg +5 -0
  60. data/app/assets/images/kaui/sidebar/subscriptions.svg +6 -0
  61. data/app/assets/images/kaui/sidebar/tags.svg +5 -0
  62. data/app/assets/images/kaui/sidebar/timeline.svg +5 -0
  63. data/app/assets/images/kaui/sign_in_background.svg +57 -0
  64. data/app/assets/images/kaui/sort-down.svg +3 -0
  65. data/app/assets/images/kaui/sort-up.svg +3 -0
  66. data/app/assets/images/kaui/subscription/add-on.svg +7 -0
  67. data/app/assets/images/kaui/subscription/cancel.svg +6 -0
  68. data/app/assets/images/kaui/subscription/change.svg +6 -0
  69. data/app/assets/images/kaui/subscription/date.svg +6 -0
  70. data/app/assets/images/kaui/subscription/pause.svg +4 -0
  71. data/app/assets/images/kaui/timeline/authorize.svg +5 -0
  72. data/app/assets/images/kaui/timeline/capture.svg +5 -0
  73. data/app/assets/images/kaui/timeline/chargeback.svg +3 -0
  74. data/app/assets/images/kaui/timeline/credit.svg +6 -0
  75. data/app/assets/images/kaui/timeline/invoice.svg +5 -0
  76. data/app/assets/images/kaui/timeline/purchase.svg +5 -0
  77. data/app/assets/images/kaui/timeline/refund.svg +4 -0
  78. data/app/assets/images/kaui/timeline/void.svg +4 -0
  79. data/app/assets/images/kaui/view-doc.svg +6 -0
  80. data/app/assets/images/kaui/warning.png +0 -0
  81. data/app/assets/javascripts/application.js +2 -2
  82. data/app/assets/javascripts/kaui/kaui_override.js +232 -0
  83. data/app/assets/javascripts/kaui/multi_functions_bar_utils.js +125 -24
  84. data/app/assets/stylesheets/application.css +13 -1
  85. data/app/assets/stylesheets/kaui/account.css +2028 -14
  86. data/app/assets/stylesheets/kaui/account_timeline.css +183 -0
  87. data/app/assets/stylesheets/kaui/admin_allowed_users.css +260 -0
  88. data/app/assets/stylesheets/kaui/audit.css +26 -16
  89. data/app/assets/stylesheets/kaui/audit_logs.css +443 -0
  90. data/app/assets/stylesheets/kaui/auth_pages.css +72 -0
  91. data/app/assets/stylesheets/kaui/breadcrumb.css +38 -0
  92. data/app/assets/stylesheets/kaui/chargebacks.css +118 -0
  93. data/app/assets/stylesheets/kaui/clock.css +103 -0
  94. data/app/assets/stylesheets/kaui/common.css +1744 -401
  95. data/app/assets/stylesheets/kaui/custom_fields.css +546 -0
  96. data/app/assets/stylesheets/kaui/dashboard.css +26 -0
  97. data/app/assets/stylesheets/kaui/datatable.css +114 -56
  98. data/app/assets/stylesheets/kaui/header.css +221 -114
  99. data/app/assets/stylesheets/kaui/home.css +89 -62
  100. data/app/assets/stylesheets/kaui/invoice.css +1061 -27
  101. data/app/assets/stylesheets/kaui/kaui.css +217 -145
  102. data/app/assets/stylesheets/kaui/overdue.css +5 -3
  103. data/app/assets/stylesheets/kaui/payment.css +1102 -13
  104. data/app/assets/stylesheets/kaui/queues.css +269 -0
  105. data/app/assets/stylesheets/kaui/refunds.css +185 -0
  106. data/app/assets/stylesheets/kaui/role_definitions.css +111 -0
  107. data/app/assets/stylesheets/kaui/sidebar.css +122 -0
  108. data/app/assets/stylesheets/kaui/subscription.css +677 -0
  109. data/app/assets/stylesheets/kaui/tag_definitions.css +524 -0
  110. data/app/assets/stylesheets/kaui/tags.css +592 -121
  111. data/app/assets/stylesheets/kaui/tenants.css +1478 -0
  112. data/app/assets/stylesheets/kaui/tooltip.css +9 -5
  113. data/app/assets/stylesheets/kaui/wallets.css +121 -0
  114. data/app/controllers/kaui/accounts_controller.rb +3 -2
  115. data/app/controllers/kaui/admin_tenants_controller.rb +33 -0
  116. data/app/controllers/kaui/custom_fields_controller.rb +1 -1
  117. data/app/controllers/kaui/engine_controller.rb +1 -2
  118. data/app/controllers/kaui/engine_controller_util.rb +5 -7
  119. data/app/controllers/kaui/home_controller.rb +24 -17
  120. data/app/controllers/kaui/invoices_controller.rb +4 -15
  121. data/app/controllers/kaui/payments_controller.rb +1 -1
  122. data/app/controllers/kaui/sessions_controller.rb +1 -0
  123. data/app/controllers/kaui/tag_definitions_controller.rb +1 -0
  124. data/app/helpers/kaui/account_helper.rb +13 -0
  125. data/app/helpers/kaui/plugin_helper.rb +27 -0
  126. data/app/views/kaui/account_custom_fields/index.html.erb +95 -29
  127. data/app/views/kaui/account_emails/_account_emails_table.html.erb +13 -3
  128. data/app/views/kaui/account_emails/_form.html.erb +23 -6
  129. data/app/views/kaui/account_emails/new.html.erb +12 -6
  130. data/app/views/kaui/account_tags/_form_bar.html.erb +10 -1
  131. data/app/views/kaui/account_tags/index.html.erb +103 -24
  132. data/app/views/kaui/account_timelines/_multi_functions_bar.html.erb +302 -69
  133. data/app/views/kaui/account_timelines/show.html.erb +360 -254
  134. data/app/views/kaui/accounts/_account_details.html.erb +165 -0
  135. data/app/views/kaui/accounts/_account_filterbar.html.erb +70 -80
  136. data/app/views/kaui/accounts/_add_parent.html.erb +26 -0
  137. data/app/views/kaui/accounts/_billing_details.html.erb +196 -0
  138. data/app/views/kaui/accounts/_close_account_modal.html.erb +62 -40
  139. data/app/views/kaui/accounts/_form_account.html.erb +157 -0
  140. data/app/views/kaui/accounts/_functions_bar.html.erb +606 -0
  141. data/app/views/kaui/accounts/_link_parent_modal.html.erb +1 -1
  142. data/app/views/kaui/accounts/_link_parent_to_modal.html.erb +62 -0
  143. data/app/views/kaui/accounts/_multi_functions_bar.html.erb +67 -28
  144. data/app/views/kaui/accounts/_payment_gateways.html.erb +43 -0
  145. data/app/views/kaui/accounts/_personal_details.html.erb +67 -0
  146. data/app/views/kaui/accounts/edit.html.erb +15 -9
  147. data/app/views/kaui/accounts/index.html.erb +77 -27
  148. data/app/views/kaui/accounts/new.html.erb +14 -8
  149. data/app/views/kaui/accounts/show.html.erb +17 -11
  150. data/app/views/kaui/admin/index.html.erb +44 -19
  151. data/app/views/kaui/admin_allowed_users/_form.html.erb +123 -31
  152. data/app/views/kaui/admin_allowed_users/edit.html.erb +15 -9
  153. data/app/views/kaui/admin_allowed_users/index.html.erb +150 -30
  154. data/app/views/kaui/admin_allowed_users/new.html.erb +14 -8
  155. data/app/views/kaui/admin_allowed_users/show.html.erb +137 -32
  156. data/app/views/kaui/admin_tenants/_add_allowed_user_modal.html.erb +42 -15
  157. data/app/views/kaui/admin_tenants/_clock.html.erb +72 -0
  158. data/app/views/kaui/admin_tenants/_form.html.erb +32 -20
  159. data/app/views/kaui/admin_tenants/_form_catalog_translation.erb +21 -8
  160. data/app/views/kaui/admin_tenants/_form_invoice_template.erb +25 -9
  161. data/app/views/kaui/admin_tenants/_form_invoice_translation.erb +36 -20
  162. data/app/views/kaui/admin_tenants/_form_plugin_config.erb +16 -20
  163. data/app/views/kaui/admin_tenants/_show_catalog.erb +13 -6
  164. data/app/views/kaui/admin_tenants/_show_catalog_simple.erb +95 -46
  165. data/app/views/kaui/admin_tenants/_show_catalog_xml.erb +62 -37
  166. data/app/views/kaui/admin_tenants/_show_overdue.erb +91 -75
  167. data/app/views/kaui/admin_tenants/_tenant_details.html.erb +106 -17
  168. data/app/views/kaui/admin_tenants/_tenants_table.html.erb +67 -6
  169. data/app/views/kaui/admin_tenants/_useful_links.html.erb +21 -16
  170. data/app/views/kaui/admin_tenants/index.html.erb +35 -11
  171. data/app/views/kaui/admin_tenants/index.js.erb +3 -0
  172. data/app/views/kaui/admin_tenants/new.html.erb +19 -13
  173. data/app/views/kaui/admin_tenants/new_catalog.html.erb +230 -98
  174. data/app/views/kaui/admin_tenants/new_overdue_config.html.erb +152 -80
  175. data/app/views/kaui/admin_tenants/new_plan_currency.html.erb +44 -30
  176. data/app/views/kaui/admin_tenants/show.html.erb +211 -78
  177. data/app/views/kaui/admin_tenants/show.js.erb +3 -0
  178. data/app/views/kaui/audit_logs/_multi_functions_bar.html.erb +298 -101
  179. data/app/views/kaui/audit_logs/index.html.erb +137 -38
  180. data/app/views/kaui/bundle_tags/_form_bar.html.erb +11 -4
  181. data/app/views/kaui/bundles/_bundle_details.html.erb +24 -12
  182. data/app/views/kaui/bundles/index.html.erb +79 -104
  183. data/app/views/kaui/bundles/pause_resume.html.erb +73 -38
  184. data/app/views/kaui/chargebacks/_form.html.erb +35 -18
  185. data/app/views/kaui/chargebacks/new.html.erb +16 -9
  186. data/app/views/kaui/charges/_form.html.erb +54 -42
  187. data/app/views/kaui/charges/new.html.erb +15 -8
  188. data/app/views/kaui/components/breadcrumb/_breadcrumb.html.erb +146 -0
  189. data/app/views/kaui/components/button/_button.html.erb +16 -0
  190. data/app/views/kaui/components/dashboard/_card.html.erb +15 -0
  191. data/app/views/kaui/components/dashboard/_setting.html.erb +15 -0
  192. data/app/views/kaui/components/form_input/_form_input.html.erb +4 -0
  193. data/app/views/kaui/components/form_password/_form_password.html.erb +6 -0
  194. data/app/views/kaui/components/logo/_logo.html.erb +1 -0
  195. data/app/views/kaui/components/menu_dropdown/_menu_dropdown.html.erb +59 -0
  196. data/app/views/kaui/components/search_input/_search_input.html.erb +81 -0
  197. data/app/views/kaui/credits/_form.html.erb +42 -25
  198. data/app/views/kaui/credits/new.html.erb +15 -8
  199. data/app/views/kaui/custom_fields/_form.html.erb +37 -25
  200. data/app/views/kaui/custom_fields/_list_bar.html.erb +11 -10
  201. data/app/views/kaui/custom_fields/index.html.erb +121 -27
  202. data/app/views/kaui/custom_fields/new.html.erb +19 -8
  203. data/app/views/kaui/errors/500.html.erb +1 -1
  204. data/app/views/kaui/home/index.html.erb +77 -30
  205. data/app/views/kaui/invoice_items/_edit_form.html.erb +30 -14
  206. data/app/views/kaui/invoice_items/edit.html.erb +15 -7
  207. data/app/views/kaui/invoice_tags/_form_bar.html.erb +13 -3
  208. data/app/views/kaui/invoices/_invoice_filterbar.html.erb +53 -69
  209. data/app/views/kaui/invoices/_invoice_table.html.erb +77 -92
  210. data/app/views/kaui/invoices/_multi_functions_bar.html.erb +351 -140
  211. data/app/views/kaui/invoices/index.html.erb +89 -27
  212. data/app/views/kaui/invoices/show.html.erb +392 -80
  213. data/app/views/kaui/layouts/kaui_account_sidebar.html.erb +42 -0
  214. data/app/views/kaui/layouts/kaui_application.html.erb +29 -15
  215. data/app/views/kaui/layouts/kaui_flash.html.erb +82 -31
  216. data/app/views/kaui/layouts/kaui_navbar.html.erb +109 -82
  217. data/app/views/kaui/layouts/kaui_setting_sidebar.html.erb +36 -0
  218. data/app/views/kaui/payment_methods/_form.html.erb +32 -11
  219. data/app/views/kaui/payment_methods/_new_creditcard_payment_method.html.erb +35 -34
  220. data/app/views/kaui/payment_methods/_payment_methods_details_table.html.erb +27 -29
  221. data/app/views/kaui/payment_methods/_payment_methods_table.html.erb +116 -38
  222. data/app/views/kaui/payment_methods/_plugin_properties.html.erb +19 -9
  223. data/app/views/kaui/payment_methods/new.html.erb +14 -8
  224. data/app/views/kaui/payments/_form.html.erb +30 -13
  225. data/app/views/kaui/payments/_multi_functions_bar.html.erb +351 -141
  226. data/app/views/kaui/payments/_payment_filterbar.html.erb +63 -79
  227. data/app/views/kaui/payments/_payment_invoice_table.html.erb +105 -0
  228. data/app/views/kaui/payments/_payment_table.html.erb +4 -67
  229. data/app/views/kaui/payments/index.html.erb +90 -26
  230. data/app/views/kaui/payments/new.html.erb +15 -8
  231. data/app/views/kaui/payments/show.html.erb +222 -28
  232. data/app/views/kaui/queues/index.html.erb +329 -111
  233. data/app/views/kaui/refunds/_form.html.erb +68 -45
  234. data/app/views/kaui/refunds/new.html.erb +15 -8
  235. data/app/views/kaui/role_definitions/_form.html.erb +104 -17
  236. data/app/views/kaui/role_definitions/new.html.erb +15 -8
  237. data/app/views/kaui/sessions/_form.html.erb +9 -19
  238. data/app/views/kaui/sessions/new.html.erb +10 -9
  239. data/app/views/kaui/subscriptions/_cancel_by_date_modal.html.erb +65 -35
  240. data/app/views/kaui/subscriptions/_edit_form.html.erb +66 -35
  241. data/app/views/kaui/subscriptions/_form.html.erb +63 -32
  242. data/app/views/kaui/subscriptions/_subscriptions_table.html.erb +215 -57
  243. data/app/views/kaui/subscriptions/edit.html.erb +19 -8
  244. data/app/views/kaui/subscriptions/edit_bcd.erb +46 -16
  245. data/app/views/kaui/subscriptions/new.html.erb +22 -15
  246. data/app/views/kaui/tag_definitions/_form.html.erb +51 -30
  247. data/app/views/kaui/tag_definitions/index.html.erb +151 -40
  248. data/app/views/kaui/tag_definitions/new.html.erb +15 -8
  249. data/app/views/kaui/tags/index.html.erb +136 -47
  250. data/app/views/kaui/tenants/_form.html.erb +8 -5
  251. data/app/views/kaui/tenants/index.html.erb +15 -9
  252. data/app/views/kaui/transactions/_control_plugin_names.html.erb +18 -10
  253. data/app/views/kaui/transactions/_form.html.erb +86 -25
  254. data/app/views/kaui/transactions/new.html.erb +15 -9
  255. data/config/routes.rb +1 -0
  256. data/lib/kaui/engine.rb +11 -0
  257. data/lib/kaui/version.rb +1 -1
  258. data/lib/kaui.rb +0 -1
  259. metadata +120 -2
@@ -1,60 +1,80 @@
1
- <% # Unclear why this url/method hack is needed %>
2
1
  <%= form_for @allowed_user, :url => @allowed_user.persisted? ? admin_allowed_user_path(@allowed_user.id) : admin_allowed_users_path, :method => @allowed_user.persisted? ? :put : :post, :html => {:class => 'form-horizontal'} do |f| %>
3
2
  <input type="hidden" id="killbillManaged" value="<%= @is_killbill_managed %>" />
4
- <div class='form-group'>
5
- <div class="col-sm-offset-2 col-sm-9">
3
+ <div class='form-group d-flex pb-3'>
4
+ <%= f.label ' ', :class => 'col-sm-3 control-label' %>
5
+ <div class="col-sm-9">
6
6
  <div class="checkbox">
7
- <%= f.label :external do %>
8
- <%= check_box_tag :external, '1', false, { :disabled => !@allowed_user.id.blank? } %>Managed externally (LDAP, Okta, etc.)?
9
- <% end %>
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" %>
9
+ Managed externally (LDAP, Okta, etc.)?
10
+ </label>
10
11
  </div>
12
+
11
13
  </div>
12
14
  </div>
13
- <div class="form-group">
14
- <%= f.label :kb_username, 'Name', :class => 'col-sm-2 control-label' %>
15
- <div class="col-sm-10">
15
+ <div class="form-group d-flex pb-3">
16
+ <%= f.label :kb_username, 'Name', :class => 'col-sm-3 control-label' %>
17
+ <div class="col-sm-9">
16
18
  <%= f.text_field :kb_username, :class => 'form-control', :required => true, :disabled => @allowed_user.persisted?, :readonly => @allowed_user.persisted? %>
17
19
  </div>
18
20
  </div>
19
- <div class="form-group">
20
- <%= f.label :password, 'Password', :class => 'col-sm-2 control-label' %>
21
- <div class="col-sm-10">
21
+ <div class="form-group d-flex pb-3">
22
+ <%= f.label :password, 'Password', :class => 'col-sm-3 control-label' %>
23
+ <div class="col-sm-9">
22
24
  <%= password_field_tag :password, nil, class:'form-control' %>
23
25
  </div>
24
26
  </div>
25
- <div class="form-group">
26
- <%= f.label :description, 'Description', :class => 'col-sm-2 control-label' %>
27
- <div class="col-sm-10">
27
+ <div class="form-group d-flex pb-3">
28
+ <%= f.label :description, 'Description', :class => 'col-sm-3 control-label' %>
29
+ <div class="col-sm-9">
28
30
  <%= f.text_field :description, :class => 'form-control' %>
29
31
  </div>
30
32
  </div>
31
- <div class="form-group">
32
- <%= label_tag :roles, 'Roles', :class => 'col-sm-2 control-label' %>
33
- <div class="col-sm-10">
34
- <%= text_field_tag :roles, @roles.join(','), :class => 'form-control' %>
35
- <p class="help-block">Comma separated, e.g. customer_support,finance.</p>
36
- <p class="help-block">Create a new role <%= link_to 'here', new_role_definition_path %>.</p>
33
+ <div class="form-group d-flex pb-3">
34
+ <%= label_tag :roles, 'Roles', :class => 'col-sm-3 control-label' %>
35
+ <div class="col-sm-9 d-flex gap-2">
36
+ <div id="chip-container" class="chip-input-container form-control d-flex flex-wrap align-items-center p-2" onclick="focusChipInput()">
37
+ <span id="chip-input" class="chip-text-input" contenteditable="true"></span>
38
+ </div>
39
+ <%= hidden_field_tag :roles, @roles.join(','), id: 'roles-hidden' %>
40
+
41
+ <%= link_to new_role_definition_path, class: "border-button custom-hover add-role-button" do %>
42
+ <%= image_tag("kaui/modal/plus.svg", width: 16, height: 16) %>
43
+ <% end %>
37
44
  </div>
38
45
  </div>
39
- <div class="form-group">
40
- <div class="col-sm-offset-2 col-sm-10">
41
- <%= f.submit 'Save', :class => 'btn btn-default' %>
42
- </div>
46
+ <div class="form-group d-flex justify-content-end pt-3 border-top mb-3">
47
+ <%= render "kaui/components/button/button", {
48
+ label: 'Close',
49
+ variant: "outline-secondary d-inline-flex align-items-center gap-1",
50
+ type: "button",
51
+ html_class: "kaui-button custom-hover mx-2",
52
+ html_options: {
53
+ id: "closeButton",
54
+ onclick: "window.history.back();"
55
+ }
56
+ } %>
57
+ <%= render "kaui/components/button/button", {
58
+ label: 'Save User',
59
+ variant: "outline-secondary d-inline-flex align-items-center gap-1",
60
+ type: "submit",
61
+ html_class: "kaui-dropdown custom-hover",
62
+ } %>
43
63
  </div>
44
64
  <% end %>
45
65
 
46
66
  <!-- is the user been edited? -->
47
67
  <% if @allowed_user.persisted? %>
48
- <div class="footer-notice managed-externally-notice">
49
- <div class="modal-footer">
50
- <div class="alert alert-warning">
51
- <strong>Notice</strong>
52
- <p id="noticeMessage">This user is managed externally (LDAP, Okta, etc.) or via Shiro configuration file.</p>
53
- </div>
68
+ <div class="notice-worning">
69
+ <%= image_tag("kaui/warning.png", width: 35, height: 35) %>
70
+ <div>
71
+ <strong>Notice</strong>
72
+ <p id="noticeMessage">This user is managed externally (LDAP, Okta, etc.) or via Shiro configuration file.</p>
54
73
  </div>
55
74
  </div>
56
75
  <% end %>
57
76
 
77
+
58
78
  <%= javascript_tag do %>
59
79
  $(document).ready(function() {
60
80
 
@@ -68,12 +88,18 @@
68
88
  if ($('#external').is(":checked") || !isKillbillManaged) {
69
89
  $('#password').attr('disabled', true);
70
90
  $('#roles').attr('disabled', true);
91
+ $('.add-role-button').hide();
92
+ $('#chip-container').addClass('disabled-container');
93
+ $('#chip-input').attr('contenteditable', false).addClass('disabled');
71
94
  $('.help-block').hide();
72
95
  $('.managed-externally-notice').show();
73
96
  }
74
97
  else {
75
98
  $('#password').attr('disabled', false);
76
99
  $('#roles').attr('disabled', false);
100
+ $('.add-role-button').show();
101
+ $('#chip-input').attr('contenteditable', true).removeClass('disabled');
102
+ $('#chip-container').removeClass('disabled-container');
77
103
  $('.help-block').show();
78
104
  $('.managed-externally-notice').hide();
79
105
  }
@@ -81,4 +107,70 @@
81
107
 
82
108
  is_killbill_managed();
83
109
  });
110
+
111
+ document.addEventListener("DOMContentLoaded", function () {
112
+ const chipContainer = document.getElementById("chip-container");
113
+ const chipInput = document.getElementById("chip-input");
114
+ const hiddenInput = document.getElementById("roles-hidden");
115
+
116
+ function addChip(text) {
117
+ if (!text) return;
118
+ const chip = document.createElement("span");
119
+ chip.className = "chip";
120
+ chip.innerHTML = `
121
+ ${text}
122
+ <span class="remove-chip">
123
+ <svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
124
+ <path d="M8.50049 1.5L1.50049 8.50001M1.50049 1.5L8.50049 8.50001" stroke="#A4A7AE" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
125
+ </svg>
126
+ </span>
127
+ `;
128
+ chip.querySelector(".remove-chip").addEventListener("click", () => {
129
+ chip.remove();
130
+ updateHiddenInput();
131
+ });
132
+ chipContainer.insertBefore(chip, chipInput);
133
+ updateHiddenInput();
134
+ }
135
+
136
+ function updateHiddenInput() {
137
+ const chips = chipContainer.querySelectorAll(".chip");
138
+ const values = Array.from(chips).map(chip => chip.childNodes[0].nodeValue.trim());
139
+ hiddenInput.value = values.join(",");
140
+ }
141
+
142
+ chipInput.addEventListener("keydown", function (e) {
143
+ if (e.key === ',' || e.key === 'Enter') {
144
+ e.preventDefault();
145
+ const text = chipInput.innerText.trim().replace(/,$/, '');
146
+ if (text !== "") {
147
+ addChip(text);
148
+ chipInput.innerText = "";
149
+ }
150
+ } else if (e.key === 'Backspace' && chipInput.innerText === '') {
151
+ const lastChip = chipContainer.querySelectorAll(".chip");
152
+ if (lastChip.length > 0) {
153
+ lastChip[lastChip.length - 1].remove();
154
+ updateHiddenInput();
155
+ }
156
+ }
157
+ });
158
+
159
+ chipInput.addEventListener("blur", () => {
160
+ const text = chipInput.innerText.trim();
161
+ if (text !== "") {
162
+ addChip(text);
163
+ chipInput.innerText = "";
164
+ }
165
+ });
166
+
167
+ // Load initial roles if any
168
+ const initialRoles = hiddenInput.value.split(',').filter(Boolean);
169
+ initialRoles.forEach(role => addChip(role));
170
+
171
+ // Focus handler
172
+ window.focusChipInput = function () {
173
+ chipInput.focus();
174
+ };
175
+ });
84
176
  <% end %>
@@ -1,10 +1,16 @@
1
- <div class="register">
2
- <div class="col-md-8 col-md-offset-2">
3
-
4
- <div class="column-block">
5
- <h1>Update user</h1>
6
- <%= render 'form' %>
1
+ <div class="register kaui-container kaui-tenant-select kaui-new-admin-allowed-users">
2
+ <div class="">
3
+ <div class="" style="max-width: 37.5rem; margin: 0 auto;">
4
+ <h5 class="new-user-title border-bottom">
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="M13.3334 5.83333C13.3334 7.67428 11.841 9.16667 10.0001 9.16667C8.15913 9.16667 6.66675 7.67428 6.66675 5.83333C6.66675 3.99238 8.15913 2.5 10.0001 2.5C11.841 2.5 13.3334 3.99238 13.3334 5.83333Z" stroke="#414651" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
8
+ <path d="M15.8334 15.8337C15.8334 13.5325 13.9679 11.667 11.6667 11.667H8.33341C6.03223 11.667 4.16675 13.5325 4.16675 15.8337V17.5003H15.8334V15.8337Z" stroke="#414651" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
9
+ </svg>
10
+ </span>
11
+ Update user
12
+ </h5>
13
+ <%= render 'form' %>
14
+ </div>
7
15
  </div>
8
-
9
- </div>
10
- </div>
16
+ </div>
@@ -1,40 +1,160 @@
1
- <div class="search">
2
-
3
- <div class="column-block">
4
-
5
- <h1>Kaui users
6
- <% if can? :create, Kaui::AdminTenant %>
7
- <%= link_to '&nbsp;<i class="fa fa-plus-square"></i>'.html_safe, new_admin_allowed_user_path %>
8
- <% end %></h1>
9
-
10
- <% unless @allowed_users.empty? %>
11
- <table id="allowed-users-table" class="table table-condensed table-striped mobile-data">
12
- <thead>
13
- <tr>
14
- <th>Name</th>
15
- <th>Description</th>
16
- </tr>
17
- </thead>
18
- <tbody>
19
- <% @allowed_users.each do |u| %>
1
+ <div class="kaui-container kaui-users-index">
2
+ <%= render partial: 'kaui/components/breadcrumb/breadcrumb', locals: {
3
+ breadcrumbs: [
4
+ { label: 'Settings', href: '/' },
5
+ { label: "Users", href: '#' }
6
+ ]
7
+ } %>
8
+
9
+ <div class="d-flex" style="gap: 4rem;">
10
+ <%= render :template => 'kaui/layouts/kaui_setting_sidebar' %>
11
+
12
+ <div class="users-details w-100">
13
+ <div class="d-flex flex-column">
14
+ <div class="users-details-header">
15
+ <h2>Users</h2>
16
+ <span>
17
+ <% if can? :create, Kaui::AdminTenant %>
18
+ <%= link_to new_admin_allowed_user_path do %>
19
+ <%= render "kaui/components/button/button", {
20
+ label: "Create User",
21
+ icon: "kaui/plus.svg",
22
+ variant: "outline-secondary d-inline-flex align-items-center gap-1",
23
+ type: "button",
24
+ html_class: "kaui-dropdown custom-hover",
25
+ } %>
26
+ <% end %>
27
+ <% end %>
28
+ </span>
29
+ </div>
30
+
31
+ <div class="mt-4">
32
+ <% unless @allowed_users.empty? %>
33
+ <table id="allowed-users-table" class="allowed-users-table">
34
+ <thead>
20
35
  <tr>
21
- <td><%= link_to u.kb_username, admin_allowed_user_path(u.id) %></td>
22
- <td><%= u.description %></td>
36
+ <th class="sortable-header" data-column="0">
37
+ <div class="header-content">
38
+ <span class="header-text">Name</span>
39
+ <div class="sort-icons">
40
+ <%= image_tag "kaui/sort-up.svg", class: "sort-icon sort-asc" %>
41
+ <%= image_tag "kaui/sort-down.svg", class: "sort-icon sort-desc" %>
42
+ </div>
43
+ </div>
44
+ </th>
45
+ <th class="sortable-header" data-column="1">
46
+ <div class="header-content">
47
+ <span class="header-text">Description</span>
48
+ <div class="sort-icons">
49
+ <%= image_tag "kaui/sort-up.svg", class: "sort-icon sort-asc" %>
50
+ <%= image_tag "kaui/sort-down.svg", class: "sort-icon sort-desc" %>
51
+ </div>
52
+ </div>
53
+ </th>
54
+ <th></th>
23
55
  </tr>
24
- <% end %>
25
- </tbody>
26
- </table>
27
- <% end %>
56
+ </thead>
57
+ <tbody>
58
+ <% @allowed_users.each do |u| %>
59
+ <tr>
60
+ <td><%= link_to u.kb_username, admin_allowed_user_path(u.id) %></td>
61
+ <td><%= u.description %></td>
62
+ <td class="text-end">
28
63
 
29
- </div>
64
+
65
+ <%= render "kaui/components/button/button", {
66
+ label: 'Delete',
67
+ variant: "outline-secondary d-inline-flex align-items-center gap-1",
68
+ type: "button",
69
+ html_class: "kaui-button delete-button custom-hover",
70
+ html_options: {
71
+ data: {
72
+ confirm: "Are you sure?",
73
+ method: "delete",
74
+ turbo: false,
75
+ "url": kaui_engine.admin_allowed_user_path(u.id)
76
+ }
77
+ }
78
+ } %>
79
+ <%= link_to kaui_engine.edit_admin_allowed_user_path(u.id), :class => '' do %>
80
+ <%= render "kaui/components/button/button", {
81
+ label: "Edit",
82
+ variant: "outline-secondary d-inline-flex align-items-center gap-1",
83
+ type: "button",
84
+ html_class: "kaui-button edit-button custom-hover",
85
+ } %>
86
+ <% end %>
87
+ </td>
88
+ </tr>
89
+ <% end %>
90
+ </tbody>
91
+ </table>
92
+ <% end %>
30
93
 
94
+ </div>
95
+ </div>
96
+ </div>
97
+ </div>
31
98
  </div>
32
99
 
33
100
  <%= javascript_tag do %>
34
101
  $(document).ready(function() {
35
- $('#allowed-users-table').dataTable({
36
- "dom": "t",
37
- "paging": false
38
- });
102
+ // Initialize DataTable for allowed users table
103
+ var allowedUsersTable;
104
+
105
+ // Wait for the table to be available
106
+ setTimeout(function() {
107
+ try {
108
+ // Check if table is already initialized as DataTable
109
+ if ($.fn.DataTable.isDataTable('#allowed-users-table')) {
110
+ allowedUsersTable = $('#allowed-users-table').DataTable();
111
+ } else {
112
+ allowedUsersTable = $('#allowed-users-table').DataTable({
113
+ "dom": "t",
114
+ "paging": false,
115
+ "ordering": true
116
+ });
117
+ }
118
+
119
+ // Custom sorting functionality for allowed users table
120
+ var currentSortColumn = -1;
121
+ var currentSortDirection = 'asc';
122
+
123
+ // Handle custom header clicks
124
+ $('.sortable-header').on('click', function() {
125
+ var columnIndex = parseInt($(this).data('column'));
126
+ var newDirection = 'asc';
127
+
128
+ // If clicking the same column, toggle direction
129
+ if (currentSortColumn === columnIndex) {
130
+ newDirection = currentSortDirection === 'asc' ? 'desc' : 'asc';
131
+ }
132
+
133
+ currentSortColumn = columnIndex;
134
+ currentSortDirection = newDirection;
135
+
136
+ // Update visual indicators
137
+ updateSortIndicators(columnIndex, newDirection);
138
+
139
+ // Apply DataTable sorting
140
+ if (allowedUsersTable && allowedUsersTable.order) {
141
+ allowedUsersTable.order([columnIndex, newDirection]).draw();
142
+ }
143
+ });
144
+
145
+ // Function to update sort indicators
146
+ function updateSortIndicators(columnIndex, direction) {
147
+ // Reset all headers
148
+ $('.sortable-header').removeClass('sort-asc-active sort-desc-active');
149
+ $('.sort-icon').removeClass('active');
150
+
151
+ // Set active state for current column
152
+ var $header = $('.sortable-header[data-column="' + columnIndex + '"]');
153
+ $header.addClass(direction + '-active');
154
+ $header.find('.sort-' + direction).addClass('active');
155
+ }
156
+
157
+ }
158
+ }, 100);
39
159
  });
40
160
  <% end %>
@@ -1,10 +1,16 @@
1
- <div class="register">
2
- <div class="col-md-8 col-md-offset-2">
3
-
4
- <div class="column-block">
5
- <h1>Add new user</h1>
6
- <%= render 'form' %>
1
+ <div class="register kaui-container kaui-tenant-select kaui-new-admin-allowed-users">
2
+ <div class="">
3
+ <div class="" style="max-width: 37.5rem; margin: 0 auto;">
4
+ <h5 class="new-user-title border-bottom">
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="M13.3334 5.83333C13.3334 7.67428 11.841 9.16667 10.0001 9.16667C8.15913 9.16667 6.66675 7.67428 6.66675 5.83333C6.66675 3.99238 8.15913 2.5 10.0001 2.5C11.841 2.5 13.3334 3.99238 13.3334 5.83333Z" stroke="#414651" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
8
+ <path d="M15.8334 15.8337C15.8334 13.5325 13.9679 11.667 11.6667 11.667H8.33341C6.03223 11.667 4.16675 13.5325 4.16675 15.8337V17.5003H15.8334V15.8337Z" stroke="#414651" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
9
+ </svg>
10
+ </span>
11
+ Add new user
12
+ </h5>
13
+ <%= render 'form' %>
14
+ </div>
7
15
  </div>
8
-
9
- </div>
10
16
  </div>
@@ -1,39 +1,86 @@
1
- <div class="column-block">
2
-
3
- <h1>User details
4
- <%= link_to 'Edit',
5
- kaui_engine.edit_admin_allowed_user_path(@allowed_user.id),
6
- :class => 'btn btn-xs' %>
7
- &nbsp;
8
- <%= link_to '<i class="fa fa-times"></i>'.html_safe,
9
- kaui_engine.admin_allowed_user_path(@allowed_user.id),
10
- :method => :delete,
11
- data: {:confirm => 'Are you sure?'} -%>
12
- </h1>
1
+ <div class="kaui-container">
2
+ <div class="user-details-container">
3
+ <div class="d-flex flex-column">
4
+ <div class="user-details-header mb-3">
5
+ <div class="d-flex align-items-start flex-column">
6
+ <h2>User details</h2>
7
+ </div>
8
+ <span>
9
+ <%= render "kaui/components/button/button", {
10
+ label: 'Delete',
11
+ variant: "outline-secondary d-inline-flex align-items-center gap-1",
12
+ type: "button",
13
+ html_class: "kaui-button delete-button custom-hover",
14
+ html_options: {
15
+ data: {
16
+ confirm: "Are you sure?",
17
+ method: "delete",
18
+ turbo: false, # Optional: disable Turbo if using Rails Turbo
19
+ "url": kaui_engine.admin_allowed_user_path(@allowed_user.id)
20
+ },
21
+ onclick: "if (confirm(this.dataset.confirm)) { Rails.ajax({ url: this.dataset.url, type: this.dataset.method }); }"
22
+ }
23
+ } %>
13
24
 
14
- <b>Name:</b> <%= @allowed_user.kb_username %>
15
- <br/>
16
- <b>Description:</b> <%= @allowed_user.description %>
17
- <br/>
18
- <b>Roles:</b> <%= @roles.join(',') %>
25
+ <%= link_to kaui_engine.edit_admin_allowed_user_path(@allowed_user.id),
26
+ :class => '' do %>
27
+ <%= render "kaui/components/button/button", {
28
+ label: "Edit",
29
+ icon: "kaui/account/edit.svg",
30
+ variant: "outline-secondary d-inline-flex align-items-center gap-1",
31
+ type: "button",
32
+ html_class: "kaui-dropdown custom-hover",
33
+ } %>
34
+ <% end %>
19
35
 
36
+ </span>
37
+ </div>
38
+ <div class="row">
39
+ <div class="col-md-4 d-flex flex-column">
40
+ <b>Name:</b> <span><%= @allowed_user.kb_username %></span>
41
+ </div>
42
+ <div class="col-md-4 d-flex flex-column">
43
+ <b>Description:</b> <span><%= @allowed_user.description %></span>
44
+ </div>
45
+ <div class="col-md-4 d-flex flex-column">
46
+ <b>Roles:</b> <span><%= @roles.join(', ') %></span>
47
+ </div>
48
+ </div>
49
+ </div>
50
+ </div>
20
51
  </div>
21
52
 
22
- <% if can? :create, Kaui::AdminTenant %>
23
- <div class="register">
24
- <div class="col-md-8 col-md-offset-2">
25
53
 
26
- <div class="column-block">
27
- <h1>Configured tenants</h1>
54
+ <% if can? :create, Kaui::AdminTenant %>
55
+ <div class="kaui-container mt-4">
56
+ <div class="user-details-container">
57
+ <div class="d-flex flex-column">
58
+ <div class="user-details-header mb-3">
59
+ <div class="d-flex align-items-start flex-column">
60
+ <h2>Configured tenants</h2>
61
+ </div>
62
+ <span>
63
+ </span>
64
+ </div>
65
+ <div>
28
66
  <%= form_for @allowed_user, :url => {:action => :add_tenant}, :html => {:method => :post, :class => 'form-horizontal'} do |f| %>
29
67
  <%= f.hidden_field(:id) %>
30
68
 
31
69
  <div class='form-group'>
32
70
  <div class="col-sm-offset-2 col-sm-10">
71
+ <!-- Check All/Uncheck All Section -->
72
+ <div class="checkbox pb-2">
73
+ <label class="d-flex align-items-center gap-2 control-label">
74
+ <%= check_box_tag "check_all_tenants", "all", false, :disabled => !current_user.root?, class: "pt-2", id: "check_all_tenants" %>
75
+ <span class="fw-bold"><strong>All Tenants</strong></span>
76
+ </label>
77
+ </div>
78
+
79
+ <!-- Individual Tenant Checkboxes -->
33
80
  <% @tenants.each do |tenant| %>
34
- <div class="checkbox">
35
- <label>
36
- <%= check_box_tag "tenant_#{tenant.id}", tenant.id, @allowed_user.kaui_tenants.map(&:id).include?(tenant.id), :disabled => !current_user.root? %>
81
+ <div class="checkbox pb-2">
82
+ <label class="d-flex align-items-center gap-2 control-label">
83
+ <%= check_box_tag "tenant_#{tenant.id}", tenant.id, @allowed_user.kaui_tenants.map(&:id).include?(tenant.id), :disabled => !current_user.root?, class: "pt-2 tenant-checkbox" %>
37
84
  <span><%= tenant.name || tenant.api_key %></span>
38
85
  </label>
39
86
  </div>
@@ -41,16 +88,74 @@
41
88
  </div>
42
89
  </div>
43
90
  <% unless !current_user.root? %>
44
- <div class="form-group">
45
- <div class="col-sm-offset-2 col-sm-10">
46
- <%= f.submit 'Save', :class => 'btn btn-default' %>
47
- </div>
48
- </div>
91
+ <div class="form-group d-flex justify-content-end pt-3 border-top">
92
+ <%= render "kaui/components/button/button", {
93
+ label: 'Close',
94
+ variant: "outline-secondary d-inline-flex align-items-center gap-1",
95
+ type: "button",
96
+ html_class: "kaui-button custom-hover mx-2",
97
+ html_options: {
98
+ id: "closeButton",
99
+ onclick: "window.history.back();"
100
+ }
101
+ } %>
102
+ <%= render "kaui/components/button/button", {
103
+ label: 'Save User',
104
+ variant: "outline-secondary d-inline-flex align-items-center gap-1",
105
+ type: "submit",
106
+ html_class: "kaui-dropdown custom-hover",
107
+ } %>
108
+ </div>
49
109
  <% end %>
50
110
  <% end %>
51
-
52
111
  </div>
53
-
54
112
  </div>
55
113
  </div>
114
+ </div>
56
115
  <% end %>
116
+
117
+ <script>
118
+ document.addEventListener('DOMContentLoaded', function() {
119
+ const checkAllCheckbox = document.getElementById('check_all_tenants');
120
+ const tenantCheckboxes = document.querySelectorAll('.tenant-checkbox');
121
+
122
+ if (checkAllCheckbox && tenantCheckboxes.length > 0) {
123
+ // Handle "Check All" checkbox change
124
+ checkAllCheckbox.addEventListener('change', function() {
125
+ const isChecked = this.checked;
126
+ tenantCheckboxes.forEach(function(checkbox) {
127
+ if (!checkbox.disabled) {
128
+ checkbox.checked = isChecked;
129
+ }
130
+ });
131
+ });
132
+
133
+ // Handle individual tenant checkbox changes
134
+ tenantCheckboxes.forEach(function(checkbox) {
135
+ checkbox.addEventListener('change', function() {
136
+ updateCheckAllState();
137
+ });
138
+ });
139
+
140
+ // Update "Check All" state based on individual checkboxes
141
+ function updateCheckAllState() {
142
+ const enabledCheckboxes = Array.from(tenantCheckboxes).filter(cb => !cb.disabled);
143
+ const checkedCount = enabledCheckboxes.filter(cb => cb.checked).length;
144
+
145
+ if (checkedCount === 0) {
146
+ checkAllCheckbox.checked = false;
147
+ checkAllCheckbox.indeterminate = false;
148
+ } else if (checkedCount === enabledCheckboxes.length) {
149
+ checkAllCheckbox.checked = true;
150
+ checkAllCheckbox.indeterminate = false;
151
+ } else {
152
+ checkAllCheckbox.checked = false;
153
+ checkAllCheckbox.indeterminate = true;
154
+ }
155
+ }
156
+
157
+ // Initialize the check all state
158
+ updateCheckAllState();
159
+ }
160
+ });
161
+ </script>