killbill-kpm-ui 3.0.5 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 55803ed5551cdcab2b23e4ac0081deaa16778d824cd183402d738076976b491d
4
- data.tar.gz: a212cf3898bd59d5196f949c7c58458f5be6e60893d1ece855e8fd185b08a0c2
3
+ metadata.gz: 1fc366b7b5c96f7e052a2982904acdc365190441a3558e7dd3f8fcb85c2977c2
4
+ data.tar.gz: 006307a23c7b922d22bb8345c366c53d3952dd4d0d86df2189969dbfa16e236e
5
5
  SHA512:
6
- metadata.gz: ec2a01fb25913558e3cb9daafccf8fcb4944d6730a80c5838b36a6ccf96b1ee91fa0b7c67ceaffc0bc2d79bb74bbfb366d8e95880f46239cdf72ad4c41d31ad5
7
- data.tar.gz: 80c9b5375acd29ca0a696313387a695617e4f9a8531731106cb376eac484f408b536ad32fe23bb7b1512a5ca393aa5d41600711198395602347d653f1ba38e8b
6
+ metadata.gz: 98d2c027a8c4edfe04de86b2b0b4d519b812ea2b8a3c5e7a30e55d5b310786ed0d22e40609a04ef46d9218a0c0ee81f15ae9b73dd93216c4241f7646b50b8208
7
+ data.tar.gz: 887316e8cc4dc10c78fe12b6fd00a7ce419e3d148920e2036bc0fdaa17ee5256690ae27e323bccf5c58a046aea43d00c12e9159c0e2f70f8066bbad63c03a004
@@ -4,3 +4,592 @@
4
4
  * the top of the compiled file, but it's generally better to create a new file per style scope.
5
5
  *= require_tree .
6
6
  */
7
+
8
+ /* app/views/kpm/nodes_info/_logs_table.html.erb */
9
+
10
+ .form-api-search input {
11
+ width: 20rem;
12
+ height: 2.2rem;
13
+ padding: 0.3rem 1rem;
14
+ border: 0.0625rem solid #e5e7eb;
15
+ border-radius: 0.375rem;
16
+ font-weight: 500;
17
+ font-size: 0.875rem;
18
+ line-height: 1.25rem;
19
+ color: #414651;
20
+ outline: none;
21
+ }
22
+
23
+ #logs-table_filter input {
24
+ width: 20rem;
25
+ height: 2.2rem;
26
+ padding: 0.3rem 1rem;
27
+ border: 0.0625rem solid #e5e7eb;
28
+ border-radius: 0.375rem;
29
+ font-weight: 500;
30
+ font-size: 0.875rem;
31
+ line-height: 1.25rem;
32
+ color: #414651;
33
+ outline: none;
34
+ }
35
+
36
+ #logs-table_filter input:focus {
37
+ border: 0.0625rem solid #1a73e8;
38
+ outline: none;
39
+ box-shadow: 0;
40
+ }
41
+
42
+ /* app/views/kpm/nodes_info/_nodes_table.html.erb */
43
+
44
+ .nodes-info b {
45
+ font-weight: 600;
46
+ font-size: 0.875rem;
47
+ line-height: 1.25rem;
48
+ color: #414651;
49
+ }
50
+
51
+ .nodes-info p,
52
+ .nodes-info p a {
53
+ font-weight: 400;
54
+ font-size: 0.875rem;
55
+ line-height: 1.25rem;
56
+ margin-bottom: 0;
57
+ color: #717680;
58
+ text-decoration: none;
59
+ }
60
+
61
+ /* app/views/kpm/nodes_info/_official_plugins.html.erb */
62
+
63
+ .official-plugins-data .official-plugin {
64
+ padding: 1rem 0;
65
+ display: flex;
66
+ justify-content: space-between;
67
+ align-items: center;
68
+ border-bottom: 0.0625rem solid #e9eaeb;
69
+ }
70
+
71
+ .official-plugins-data .official-plugin:last-child {
72
+ border-bottom: none;
73
+ }
74
+
75
+ .official-plugins-data .official-plugin-icon {
76
+ width: 2.75rem;
77
+ height: 2.75rem;
78
+ border: 0.0625rem solid #e9eaeb;
79
+ border-radius: 0.375rem;
80
+ padding: 0.25rem;
81
+ margin-right: 1rem;
82
+ }
83
+
84
+ .official-plugins-data .official-plugin h4 {
85
+ font-weight: 600;
86
+ font-size: 1rem;
87
+ line-height: 1.5rem;
88
+ margin-bottom: 0;
89
+ color: #414651;
90
+ }
91
+
92
+ .official-plugins-data .official-plugin p {
93
+ font-weight: 400;
94
+ font-size: 0.875rem;
95
+ line-height: 1.25rem;
96
+ color: #535862;
97
+ margin: 0;
98
+ }
99
+
100
+ .official-plugins-data .dots-menu {
101
+ padding: 0 !important;
102
+ width: 1.25rem;
103
+ height: 1.25rem;
104
+ background-color: transparent !important;
105
+ border: none !important;
106
+ }
107
+
108
+ .official-plugins-data .dots-menu:hover {
109
+ background-color: transparent !important;
110
+ }
111
+
112
+ .official-plugins-data .label-success {
113
+ display: inline-flex;
114
+ align-items: center;
115
+ gap: 0.125rem;
116
+ padding: 0.125rem 0.5rem;
117
+ border-radius: 3.90234375rem;
118
+ background-color: #ecfdf3;
119
+ border: 0.0625rem solid #dcfae6;
120
+ color: #067647 !important;
121
+ font-weight: 500;
122
+ font-size: 0.75rem;
123
+ line-height: 1.125rem;
124
+ margin: 0;
125
+ }
126
+
127
+ .official-plugins-data .label-danger {
128
+ display: inline-flex;
129
+ align-items: center;
130
+ gap: 0.125rem;
131
+ padding: 0.125rem 0.5rem;
132
+ border-radius: 3.90234375rem;
133
+ background-color: #fef3f2;
134
+ border: 0.0625rem solid #fee4e2;
135
+ color: #b42318 !important;
136
+ font-weight: 500;
137
+ font-size: 0.75rem;
138
+ line-height: 1.125rem;
139
+ margin: 0;
140
+ }
141
+
142
+ /* Toggle Switch */
143
+ .official-plugins-data .switch {
144
+ position: relative;
145
+ display: inline-block;
146
+ width: 2.5rem;
147
+ height: 1.25rem;
148
+ margin-left: 0.75rem;
149
+ }
150
+
151
+ .official-plugins-data .switch input {
152
+ opacity: 0;
153
+ width: 0;
154
+ height: 0;
155
+ }
156
+
157
+ .official-plugins-data .slider {
158
+ position: absolute;
159
+ cursor: pointer;
160
+ background-color: #ccc;
161
+ transition: 0.4s;
162
+ top: 0;
163
+ left: 0;
164
+ right: 0;
165
+ bottom: 0;
166
+ border-radius: 1.25rem;
167
+ }
168
+
169
+ .official-plugins-data .slider:before {
170
+ position: absolute;
171
+ content: "";
172
+ height: 0.875rem;
173
+ width: 0.875rem;
174
+ left: 0.1875rem;
175
+ bottom: 0.1875rem;
176
+ background-color: white;
177
+ transition: 0.4s;
178
+ border-radius: 50%;
179
+ }
180
+
181
+ .official-plugins-data input:checked + .slider {
182
+ background-color: #1a73e8;
183
+ }
184
+
185
+ .official-plugins-data input:checked + .slider:before {
186
+ transform: translateX(1.25rem);
187
+ }
188
+
189
+ .official-plugins-data .dropdown {
190
+ position: relative;
191
+ display: inline-block;
192
+ margin-left: 0.75rem;
193
+ }
194
+
195
+ .official-plugins-data .dots-menu {
196
+ background: transparent;
197
+ border: none;
198
+ cursor: pointer;
199
+ font-size: 1.125rem;
200
+ color: #6b7280;
201
+ }
202
+
203
+ .official-plugins-data .dropdown-content {
204
+ display: none;
205
+ position: absolute;
206
+ right: 0;
207
+ background-color: #fff;
208
+ min-width: 7.5rem;
209
+ box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.15);
210
+ border-radius: 0.375rem;
211
+ overflow: hidden;
212
+ padding: 0.25rem 0;
213
+ z-index: 1000;
214
+ }
215
+
216
+ .official-plugins-data .dropdown-content a {
217
+ display: flex;
218
+ align-items: center;
219
+ gap: 0.5rem;
220
+ padding: 0.5rem 0.625rem;
221
+ font-size: 0.875rem;
222
+ text-decoration: none;
223
+ font-weight: 500;
224
+ line-height: 1.25rem;
225
+ color: #414651;
226
+ }
227
+
228
+ .official-plugins-data .dropdown-content a:hover {
229
+ background-color: #f2f2f2;
230
+ }
231
+
232
+ .official-plugins-data .dropdown.show .dropdown-content {
233
+ display: block;
234
+ }
235
+
236
+ .official-plugins-data .toggle-icon.playpause {
237
+ display: inline-block;
238
+ width: 2.5rem;
239
+ height: 1.25rem;
240
+ border-radius: 9999px;
241
+ position: relative;
242
+ margin-left: 0.75rem;
243
+ background-color: #f5f5f5;
244
+ transition: background-color 0.3s ease;
245
+ }
246
+
247
+ .official-plugins-data .toggle-icon.playpause::before {
248
+ content: "";
249
+ position: absolute;
250
+ top: 0.125rem;
251
+ left: 0.125rem;
252
+ width: 1rem;
253
+ height: 1rem;
254
+ background-color: #fff;
255
+ border-radius: 50%;
256
+ transition: transform 0.3s ease;
257
+ }
258
+
259
+ .official-plugins-data .toggle-icon.playpause.running {
260
+ background-color: #1a73e8;
261
+ }
262
+
263
+ .official-plugins-data .toggle-icon.playpause.running::before {
264
+ transform: translateX(1.25rem);
265
+ }
266
+
267
+ .plugin-link.loading {
268
+ pointer-events: none;
269
+ opacity: 1;
270
+ }
271
+
272
+ .plugin-link.toggle-icon.loading {
273
+ position: relative;
274
+ }
275
+
276
+ .plugin-link.toggle-icon.loading::after {
277
+ content: '';
278
+ position: absolute;
279
+ top: 50%;
280
+ left: 50%;
281
+ width: 0.75rem;
282
+ height: 0.75rem;
283
+ margin: -0.375rem 0 0 -0.375rem;
284
+ border: 0.125rem solid #1a73e8;
285
+ border-top: 0.125rem solid transparent;
286
+ border-radius: 50%;
287
+ animation: spin 1s linear infinite;
288
+ z-index: 10;
289
+ }
290
+
291
+ .plugin-link:not(.toggle-icon).loading i {
292
+ animation: spin 1s linear infinite;
293
+ }
294
+
295
+ .official-plugin.loading {
296
+ position: relative;
297
+ }
298
+
299
+ .official-plugin.loading::before {
300
+ content: '';
301
+ position: absolute;
302
+ top: 0;
303
+ left: 0;
304
+ right: 0;
305
+ bottom: 0;
306
+ background: rgba(255, 255, 255, 0.8);
307
+ z-index: 5;
308
+ }
309
+
310
+ .official-plugin.loading::after {
311
+ content: '';
312
+ position: absolute;
313
+ top: 50%;
314
+ left: 50%;
315
+ transform: translate(-50%, -50%);
316
+ font-size: 1.5rem;
317
+ z-index: 10;
318
+ animation: pulse 1.5s ease-in-out infinite;
319
+ }
320
+
321
+ @keyframes spin {
322
+ 0% { transform: rotate(0deg); }
323
+ 100% { transform: rotate(360deg); }
324
+ }
325
+
326
+ @keyframes pulse {
327
+ 0%, 100% { opacity: 0.7; }
328
+ 50% { opacity: 1; }
329
+ }
330
+
331
+ /* app/views/kpm/plugins/index.html.erb */
332
+
333
+ .kpm-plugins-index .official-plugins .official-plugins-header {
334
+ display: flex;
335
+ align-items: start;
336
+ justify-content: space-between;
337
+ padding: 0;
338
+ border-bottom: 0.0625rem solid #e9eaeb;
339
+ }
340
+
341
+ .kpm-plugins-index .official-plugins .official-plugins-header h2 {
342
+ font-weight: 600;
343
+ font-size: 1.125rem;
344
+ line-height: 1.75rem;
345
+ color: #414651;
346
+ margin-bottom: 1.25rem;
347
+ }
348
+
349
+ .kpm-plugins-index .official-plugins #plugins-table tr td:last-child {
350
+ text-align: end;
351
+ }
352
+
353
+ .kpm-plugins-index .official-plugins #plugins-table tr td:last-child a {
354
+ text-decoration: none;
355
+ color: #175cd3;
356
+ }
357
+
358
+ .kpm-plugins-index .upload-plugin-title {
359
+ display: flex;
360
+ align-items: center;
361
+ gap: 1rem;
362
+ font-weight: 600;
363
+ font-size: 1.125rem;
364
+ line-height: 1.75rem;
365
+ letter-spacing: 0;
366
+ color: #1b1c1e;
367
+ padding: 1rem 0;
368
+ margin-bottom: 1.5rem;
369
+ }
370
+
371
+ .kpm-plugins-index .icon-container {
372
+ display: inline-flex;
373
+ justify-content: center;
374
+ align-items: center;
375
+ border: 0.0625rem solid #d5d7da;
376
+ border-radius: 0.375rem;
377
+ width: 2.5rem;
378
+ height: 2.5rem;
379
+ padding: 0.25rem;
380
+ }
381
+
382
+ .kpm-plugins-index .icon-container img {
383
+ width: 1rem;
384
+ height: 1rem;
385
+ }
386
+
387
+ .kpm-plugins-index table {
388
+ overflow-x: auto;
389
+ min-width: 100%;
390
+ }
391
+
392
+ .kpm-plugins-index table th {
393
+ padding: 0.375rem 0.75rem !important;
394
+ padding-right: 2rem !important;
395
+ font-weight: 500;
396
+ font-size: 0.875rem;
397
+ color: #717680;
398
+ text-transform: capitalize;
399
+ position: relative;
400
+ }
401
+
402
+ .kpm-plugins-index table td {
403
+ font-weight: 500 !important;
404
+ font-size: 0.875rem !important;
405
+ padding: 1rem 0.5rem !important;
406
+ color: #535862 !important;
407
+ text-transform: capitalize !important;
408
+ }
409
+
410
+ .kpm-plugins-index table thead tr th:not(:last-child)::after,
411
+ .kpm-plugins-index table thead tr th:not(:last-child)::before {
412
+ content: "" !important;
413
+ display: inline-block !important;
414
+ width: 0.75rem !important;
415
+ height: 0.75rem !important;
416
+ background-repeat: no-repeat !important;
417
+ background-position: center !important;
418
+ background-size: 0.75rem 0.75rem !important;
419
+ position: absolute !important;
420
+ left: 4rem !important;
421
+ }
422
+
423
+ .kpm-plugins-index table thead tr th:not(:last-child)::after {
424
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 5.5L6 2.5L9 5.5' stroke='%23A4A7AE' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
425
+ top: 45% !important;
426
+ transform: translateY(-50%) !important;
427
+ }
428
+
429
+ .kpm-plugins-index table thead tr th:not(:last-child)::before {
430
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 6.5L6 9.5L9 6.5' stroke='%23A4A7AE' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
431
+ bottom: 45% !important;
432
+ transform: translateY(50%) !important;
433
+ }
434
+
435
+ /* app/views/kpm/nodes_info/index.html.erb */
436
+
437
+ .kpm-nodes-info-index .admin-tenant-details-header {
438
+ display: flex;
439
+ align-items: start;
440
+ justify-content: space-between;
441
+ padding: 0;
442
+ border-bottom: 0.0625rem solid #e9eaeb;
443
+ }
444
+
445
+ .kpm-nodes-info-index .admin-tenant-details-header h2 {
446
+ font-weight: 600;
447
+ font-size: 1.125rem;
448
+ color: #414651;
449
+ margin-bottom: 1.25rem;
450
+ }
451
+
452
+ .kpm-nodes-info-index .plugin-tabs {
453
+ background-color: #fafafa;
454
+ border: 0.0625rem solid #e9eaeb;
455
+ border-radius: 0.375rem;
456
+ display: flex;
457
+ align-items: center;
458
+ gap: 0.25rem;
459
+ margin-bottom: 1.5rem;
460
+ padding: 0.25rem;
461
+ width: fit-content;
462
+ height: 2.5rem;
463
+ }
464
+
465
+ .kpm-nodes-info-index .plugin-tabs button {
466
+ background: transparent;
467
+ border: none;
468
+ font-weight: 500;
469
+ font-size: 0.875rem;
470
+ color: #717680;
471
+ padding: 0.375rem 0.75rem;
472
+ border-radius: 0.25rem;
473
+ cursor: pointer;
474
+ height: 2rem;
475
+ display: flex;
476
+ align-items: center;
477
+ }
478
+
479
+ .kpm-nodes-info-index .plugin-tabs .activelink {
480
+ color: #414651;
481
+ background-color: #ffffff;
482
+ box-shadow: 0 0.0625rem 0.188rem rgba(10, 13, 18, 0.1);
483
+ }
484
+
485
+ .kpm-nodes-info-index table {
486
+ overflow-x: auto;
487
+ min-width: 100%;
488
+ }
489
+
490
+ .kpm-nodes-info-index table th {
491
+ padding: 0.375rem 0.75rem !important;
492
+ font-weight: 500;
493
+ font-size: 0.875rem;
494
+ color: #717680;
495
+ text-transform: capitalize;
496
+ }
497
+
498
+ .kpm-nodes-info-index table td {
499
+ font-weight: 500 !important;
500
+ font-size: 0.875rem !important;
501
+ padding: 1rem 0.5rem !important;
502
+ color: #535862 !important;
503
+ text-transform: capitalize !important;
504
+ }
505
+
506
+ /* app/views/kpm/plugins/_form.html.erb */
507
+
508
+ .upload-plugin-form .control-label {
509
+ font-size: 0.875rem !important;
510
+ font-weight: 500 !important;
511
+ line-height: 1.25rem !important;
512
+ color: #414651 !important;
513
+ }
514
+
515
+ .upload-plugin-form .form-group.d-flex.pb-3 .form-control {
516
+ height: 2.5rem;
517
+ border-radius: 0.375rem;
518
+ }
519
+
520
+ .upload-plugin-form .form-group.d-flex .form-control:focus {
521
+ outline: none;
522
+ box-shadow: none;
523
+ }
524
+
525
+ .upload-plugin-form .toggle-segment {
526
+ display: flex;
527
+ align-items: center;
528
+ border: 0.0625rem solid #d5d7da;
529
+ width: fit-content;
530
+ border-radius: 0.375rem;
531
+ overflow: hidden;
532
+ font-size: 0.875rem;
533
+ }
534
+
535
+ .upload-plugin-form .toggle-segment .radio label {
536
+ display: flex;
537
+ align-items: center;
538
+ padding: 0.625rem 1rem !important;
539
+ cursor: pointer;
540
+ color: #414651;
541
+ border-right: 0.0625rem solid #d5d7da;
542
+ font-weight: 500;
543
+ font-size: 0.875rem;
544
+ line-height: 1.25rem;
545
+ letter-spacing: 0;
546
+ }
547
+
548
+ .upload-plugin-form .toggle-segment .radio:last-child label {
549
+ border-right: none;
550
+ }
551
+
552
+ .upload-plugin-form .toggle-segment .radio label input[type="radio"] {
553
+ appearance: none;
554
+ -webkit-appearance: none;
555
+ -moz-appearance: none;
556
+ cursor: pointer;
557
+ position: relative;
558
+ outline: none;
559
+ border: 0;
560
+ background-color: transparent;
561
+ margin: 0;
562
+ padding: 0;
563
+ }
564
+
565
+ .upload-plugin-form
566
+ .toggle-segment
567
+ .radio
568
+ label
569
+ input[type="radio"]:checked::before {
570
+ content: "";
571
+ position: absolute;
572
+ top: 0.25rem;
573
+ left: 0;
574
+ width: 0.5rem;
575
+ height: 0.5rem;
576
+ background-color: #17b26a;
577
+ border-radius: 50%;
578
+ }
579
+
580
+ .upload-plugin-form
581
+ .toggle-segment
582
+ .radio
583
+ label:has(input[type="radio"]:checked) {
584
+ background-color: #fafafa;
585
+ font-weight: 600;
586
+ color: #252b37;
587
+ gap: 1rem;
588
+ }
589
+
590
+ .upload-plugin-form
591
+ .toggle-segment
592
+ .radio
593
+ label:not(:has(input[type="radio"]:checked)) {
594
+ gap: 0;
595
+ }
@@ -0,0 +1,8 @@
1
+ <%#
2
+ This is a placeholder breadcrumb component for standalone gem usage.
3
+
4
+ This placeholder prevents "missing template" errors when running
5
+ the gem independently during development or testing.
6
+ %>
7
+
8
+ <!-- Breadcrumb placeholder for standalone gem -->
@@ -0,0 +1,8 @@
1
+ <%#
2
+ This is a placeholder button component for standalone gem usage.
3
+
4
+ This placeholder prevents "missing template" errors when running
5
+ the gem independently during development or testing.
6
+ %>
7
+
8
+ <!-- Button placeholder for standalone gem -->
@@ -0,0 +1,8 @@
1
+ <%#
2
+ This is a placeholder sidebar component for standalone gem usage.
3
+
4
+ This placeholder prevents "missing template" errors when running
5
+ the gem independently during development or testing.
6
+ %>
7
+
8
+ <!-- Sidebar placeholder for standalone gem -->
@@ -1,4 +1,4 @@
1
- <table id="logs-table" class="table table-condensed table-striped mobile-data">
1
+ <table id="logs-table" class="">
2
2
  <thead>
3
3
  <tr>
4
4
  <th>Time</th>
@@ -12,9 +12,17 @@
12
12
 
13
13
  <%= form_tag url_for, :method => 'get', :format => :js, :id => 'kb_host-form', :class => 'form-horizontal', :style => 'display: none;' do %>
14
14
  <div id="logs-form">
15
- <div class="form-inline">
15
+ <div class="form-inline form-api-search d-flex align-items-center">
16
16
  <%= text_field_tag :kb_host, kb_host, :class => 'form-control' %>
17
- <%= button_tag '', :type => 'submit', :class => 'glyphicon glyphicon-search' %>
17
+ <%= render "kaui/components/button/button", {
18
+ label: '<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
19
+ <path d="M14.167 14.167L17.5003 17.5003" stroke="#FFFFFF" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
20
+ <path d="M15.8333 9.16667C15.8333 5.48477 12.8486 2.5 9.16667 2.5C5.48477 2.5 2.5 5.48477 2.5 9.16667C2.5 12.8486 5.48477 15.8333 9.16667 15.8333C12.8486 15.8333 15.8333 12.8486 15.8333 9.16667Z" stroke="#FFFFFF" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
21
+ </svg>'.html_safe,
22
+ variant: "outline-secondary d-inline-flex align-items-center gap-1",
23
+ type: "submit",
24
+ html_class: "kaui-dropdown custom-hover mx-2",
25
+ } %>
18
26
  </div>
19
27
  </div>
20
28
  <% end %>
@@ -1,66 +1,32 @@
1
- <table id="nodes-table" class="table table-condensed table-striped mobile-data">
2
- <thead>
3
- <tr>
4
- <th>Node</th>
5
- <th>Uptime</th>
6
- <th>Kill Bill version</th>
7
- <th>Dependencies</th>
8
- <th>Plugins</th>
9
- </tr>
10
- </thead>
11
- <tbody>
12
- <%- has_kpm_plugin = kpm_plugin_installed?(nodes_info) %>
13
- <% nodes_info.each do |node_info| %>
14
- <tr>
15
- <td><%= node_info.node_name %></td>
16
- <td>
17
- <% unless node_info.boot_time.blank? %>
18
- <%= time_ago_in_words(DateTime.parse(node_info.boot_time)) %>
19
- <% end %>
20
- </td>
21
- <td><%= node_info.kb_version %></td>
22
- <td>
23
- <ul>
24
- <li>API: <%= node_info.api_version %></li>
25
- <li>Plugin API: <%= node_info.plugin_api_version %></li>
26
- <li>Platform: <%= node_info.platform_version %></li>
27
- <li>Commons: <%= node_info.common_version %></li>
28
- </ul>
29
- </td>
30
- <td>
31
- <% unless (node_info.plugins_info || []).empty? %>
32
- <ul>
33
- <% node_info.plugins_info.each do |plugin_info| %>
34
- <li>
35
- <%= plugin_info.plugin_name %> <%= plugin_info.version %> <span class="label label-<%= plugin_info.state == 'RUNNING' ? 'success' : (plugin_info.state == 'INSTALLED' ? 'warning' : 'danger') %>"><%= plugin_info.state %></span>
36
- <% if plugin_info.state == 'RUNNING' %>
37
- <%-# If there is not plugin_key, this is most likely a pure OSGI bundle. In that case, we don't want to allow stopping it as we would lose track of it (once it's removed from the OSGI bundle registry, we don't know about it anymore) -%>
38
- <% unless plugin_info.plugin_key.nil? %>
39
- <%= link_to '<i class="fa fa-pause"></i>'.html_safe, plugin_stop_path(:plugin_key => plugin_info.plugin_key, :plugin_name => plugin_info.plugin_name, :plugin_version => plugin_info.version), :method => :post, :title => 'Stop', :remote => true, :class => 'plugin-link' %>
40
- <% end %>
41
- <%= link_to '<i class="fa fa-refresh"></i>'.html_safe, plugin_restart_path(:plugin_key => plugin_info.plugin_key, :plugin_name => plugin_info.plugin_name, :plugin_version => plugin_info.version), :method => :post, :title => 'Restart', :remote => true, :class => 'plugin-link' %>
42
- <% elsif plugin_info.state == 'INSTALLED' || plugin_info.state == 'STOPPED' %>
43
- <%= link_to '<i class="fa fa-play"></i>'.html_safe, plugin_start_path(:plugin_key => plugin_info.plugin_key, :plugin_name => plugin_info.plugin_name, :plugin_version => plugin_info.version), :method => :post, :title => 'Start', :remote => true, :class => 'plugin-link' %>
44
- <% end %>
45
- <% if !plugin_info.version.nil? && has_kpm_plugin %>
46
- <%= link_to '<i class="fa fa-eject"></i>'.html_safe, plugin_uninstall_path(:plugin_key => plugin_info.plugin_key, :plugin_name => plugin_info.plugin_name, :plugin_version => plugin_info.version), :method => :post, :title => 'Uninstall', :remote => true, :class => 'plugin-link' %>
47
- <% end %>
48
- </li>
49
- <% end %>
50
- </ul>
51
- <% end %>
52
- </td>
53
- </tr>
54
- <% end %>
55
- </tbody>
56
- </table>
57
-
58
- <%= javascript_tag do %>
59
- $(document).ready(function() {
60
- $('#nodes-table').dataTable({
61
- "dom": "t",
62
- "paging": false,
63
- "ordering": false
64
- });
65
- });
1
+ <%- has_kpm_plugin = kpm_plugin_installed?(nodes_info) %>
2
+ <% nodes_info.each do |node_info| %>
3
+ <div class="row nodes-info">
4
+ <div class="col-sm-6">
5
+ <div class="mb-3">
6
+ <b>Node</b>
7
+ <p>
8
+ <%= node_info.node_name %>
9
+ </p>
10
+ </div>
11
+ <div>
12
+ <b>Kill Bill Version</b>
13
+ <p><%= node_info.kb_version %></p>
14
+ </div>
15
+ </div>
16
+ <div class="col-sm-6">
17
+ <% unless node_info.boot_time.blank? %>
18
+ <div class="mb-3">
19
+ <b>Uptime</b>
20
+ <p class="transaction-status"> <%= time_ago_in_words(DateTime.parse(node_info.boot_time)) %></p>
21
+ </div>
22
+ <% end %>
23
+ <div>
24
+ <b>Dependencies</b>
25
+ <p>API: <%= node_info.api_version %></p>
26
+ <p>Plugin API: <%= node_info.plugin_api_version %></p>
27
+ <p>Platform: <%= node_info.platform_version %></p>
28
+ <p>Commons: <%= node_info.common_version %></p>
29
+ </div>
30
+ </div>
31
+ </div>
66
32
  <% end %>
@@ -0,0 +1,75 @@
1
+ <div class="official-plugins-data">
2
+ <%- has_kpm_plugin = kpm_plugin_installed?(nodes_info) %>
3
+ <% nodes_info.each do |node_info| %>
4
+ <% unless (node_info.plugins_info || []).empty? %>
5
+ <% node_info.plugins_info.each do |plugin_info| %>
6
+ <div class="official-plugin ">
7
+ <div class="d-flex align-items-center">
8
+ <div class="official-plugin-icon"></div>
9
+ <div class="d-flex flex-column">
10
+ <h4><%= plugin_info.plugin_name %></h4>
11
+ <p><%= plugin_info.version %> </p>
12
+ </div>
13
+ </div>
14
+ <div class="d-flex align-items-center">
15
+ <span class="label label-<%= plugin_info.state == 'RUNNING' ? 'success' : (plugin_info.state == 'INSTALLED' ? 'warning' : 'danger') %>"><%= plugin_info.state %></span>
16
+ <% if plugin_info.state == 'RUNNING' %>
17
+ <%= link_to '', plugin_stop_path(:plugin_key => plugin_info.plugin_key, :plugin_name => plugin_info.plugin_name, :plugin_version => plugin_info.version), :method => :post, :title => 'Stop', :remote => true, :class => 'plugin-link toggle-icon playpause running' %>
18
+ <% elsif plugin_info.state == 'INSTALLED' || plugin_info.state == 'STOPPED' %>
19
+ <%= link_to '', plugin_start_path(:plugin_key => plugin_info.plugin_key, :plugin_name => plugin_info.plugin_name, :plugin_version => plugin_info.version), :method => :post, :title => 'Start', :remote => true, :class => 'plugin-link toggle-icon playpause stopped' %>
20
+ <% end %>
21
+ <% if plugin_info.state == 'RUNNING' %>
22
+ <div class="dropdown">
23
+ <button class="dots-menu" onclick="toggleDropdown(this)">
24
+ <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
25
+ <path d="M10.0003 10.833C10.4606 10.833 10.8337 10.4599 10.8337 9.99967C10.8337 9.53944 10.4606 9.16634 10.0003 9.16634C9.54009 9.16634 9.16699 9.53944 9.16699 9.99967C9.16699 10.4599 9.54009 10.833 10.0003 10.833Z" stroke="#A4A7AE" stroke-width="1.66667" stroke-linecap="round" stroke-linejoin="round"/>
26
+ <path d="M10.0003 4.99967C10.4606 4.99967 10.8337 4.62658 10.8337 4.16634C10.8337 3.7061 10.4606 3.33301 10.0003 3.33301C9.54009 3.33301 9.16699 3.7061 9.16699 4.16634C9.16699 4.62658 9.54009 4.99967 10.0003 4.99967Z" stroke="#A4A7AE" stroke-width="1.66667" stroke-linecap="round" stroke-linejoin="round"/>
27
+ <path d="M10.0003 16.6663C10.4606 16.6663 10.8337 16.2932 10.8337 15.833C10.8337 15.3728 10.4606 14.9997 10.0003 14.9997C9.54009 14.9997 9.16699 15.3728 9.16699 15.833C9.16699 16.2932 9.54009 16.6663 10.0003 16.6663Z" stroke="#A4A7AE" stroke-width="1.66667" stroke-linecap="round" stroke-linejoin="round"/>
28
+ </svg>
29
+
30
+ </button>
31
+ <div class="dropdown-content">
32
+ <% unless plugin_info.plugin_key.nil? %>
33
+ <%= link_to '<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
34
+ <path d="M3.33366 13.3337H6.00033C6.36851 13.3337 6.66699 13.0352 6.66699 12.667V3.33366C6.66699 2.96547 6.36851 2.66699 6.00033 2.66699H3.33366C2.96547 2.66699 2.66699 2.96547 2.66699 3.33366V12.667C2.66699 13.0352 2.96547 13.3337 3.33366 13.3337Z" stroke="#A4A7AE" stroke-linejoin="round"/>
35
+ <path d="M9.99967 13.3337H12.6663C13.0345 13.3337 13.333 13.0352 13.333 12.667V3.33366C13.333 2.96547 13.0345 2.66699 12.6663 2.66699H9.99967C9.63147 2.66699 9.33301 2.96547 9.33301 3.33366V12.667C9.33301 13.0352 9.63147 13.3337 9.99967 13.3337Z" stroke="#A4A7AE" stroke-linejoin="round"/>
36
+ </svg> Pause'.html_safe, plugin_stop_path(:plugin_key => plugin_info.plugin_key, :plugin_name => plugin_info.plugin_name, :plugin_version => plugin_info.version), :method => :post, :title => 'Stop', :remote => true, :class => 'plugin-link' %>
37
+ <% end %>
38
+ <%= link_to '<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
39
+ <path d="M9.66667 1.33301L10.3333 3.03177C9.5386 2.60711 8.63073 2.36637 7.66667 2.36637C4.53705 2.36637 2 4.90342 2 8.03303C2 9.2271 2.36933 10.4194 3 11.333" stroke="#A4A7AE" stroke-linecap="round" stroke-linejoin="round"/>
40
+ <path d="M5.66667 14.667L5 12.9682C5.79477 13.3928 6.7026 13.6336 7.66667 13.6336C10.7963 13.6336 13.3333 11.0966 13.3333 7.96695C13.3333 6.77282 12.964 5.58055 12.3333 4.66699" stroke="#A4A7AE" stroke-linecap="round" stroke-linejoin="round"/>
41
+ </svg>
42
+ Restart'.html_safe, plugin_restart_path(:plugin_key => plugin_info.plugin_key, :plugin_name => plugin_info.plugin_name, :plugin_version => plugin_info.version), :method => :post, :title => 'Restart', :remote => true, :class => 'plugin-link' %>
43
+ <% if !plugin_info.version.nil? && has_kpm_plugin %>
44
+ <%= link_to '<svg width="16" height="16" viewBox="0 0 448 512" fill="#A4A7AE" xmlns="http://www.w3.org/2000/svg">
45
+ <path d="M224 32C217.7 32 211.7 34.5 207 39L23 223C13.7 232.2 13.7 247.8 23 257C32.2 266.3 47.8 266.3 57 257L224 90.98L391 257C400.2 266.3 415.8 266.3 425 257C434.3 247.8 434.3 232.2 425 223L241 39C236.3 34.5 230.3 32 224 32ZM64 320C55.16 320 48 327.2 48 336V368C48 376.8 55.16 384 64 384H384C392.8 384 400 376.8 400 368V336C400 327.2 392.8 320 384 320H64Z"/>
46
+ </svg> Uninstall'.html_safe, plugin_uninstall_path(:plugin_key => plugin_info.plugin_key, :plugin_name => plugin_info.plugin_name, :plugin_version => plugin_info.version), :method => :post, :title => 'Uninstall', :remote => true, :class => 'plugin-link' %>
47
+ <% end %>
48
+ </div>
49
+ </div>
50
+ <% end %>
51
+ </div>
52
+ </div>
53
+ <% end %>
54
+ <% end %>
55
+ <% end %>
56
+ </div>
57
+
58
+ <%= javascript_tag do %>
59
+ function toggleDropdown(button) {
60
+ const dropdown = button.closest(".dropdown");
61
+ dropdown.classList.toggle("show");
62
+
63
+ // Close other dropdowns
64
+ document.querySelectorAll(".dropdown").forEach(d => {
65
+ if (d !== dropdown) d.classList.remove("show");
66
+ });
67
+ }
68
+
69
+ document.addEventListener("click", function (e) {
70
+ if (!e.target.closest(".dropdown")) {
71
+ document.querySelectorAll(".dropdown").forEach(d => d.classList.remove("show"));
72
+ }
73
+ });
74
+
75
+ <% end %>
@@ -1,68 +1,130 @@
1
- <div class="search">
1
+ <div class="kaui-container kpm-nodes-info-index">
2
+ <%= render partial: 'kaui/components/breadcrumb/breadcrumb', locals: {
3
+ breadcrumbs: [
4
+ { label: 'Settings', href: '/' },
5
+ { label: "Plugin Manager", href: '#' }
6
+ ]
7
+ } %>
8
+
9
+ <div class="d-flex" style="gap: 4rem;">
10
+ <%= render :template => 'kaui/layouts/kaui_setting_sidebar' %>
11
+
12
+ <div class="admin-tenant-details w-100">
13
+ <div class="d-flex flex-column">
14
+ <div class="admin-tenant-details-header">
15
+ <h2>Plugin Manager</h2>
16
+ <span>
17
+ <div id="install-in-progress" class="btn btn-xs text-success" style="display: none;">
18
+ <i class="fa fa-refresh"></i>&nbsp;Operation in progress
19
+ </div>
20
+ <%= link_to url_for, id: "reload-page", style: "display: none;" do %>
21
+ <%= render "kaui/components/button/button", {
22
+ label: '<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
23
+ <path d="M9.66667 1.33301L10.3333 3.03177C9.5386 2.60711 8.63073 2.36637 7.66667 2.36637C4.53705 2.36637 2 4.90342 2 8.03303C2 9.2271 2.36933 10.4194 3 11.333" stroke="#A4A7AE" stroke-linecap="round" stroke-linejoin="round"/>
24
+ <path d="M5.66667 14.667L5 12.9682C5.79477 13.3928 6.7026 13.6336 7.66667 13.6336C10.7963 13.6336 13.3333 11.0966 13.3333 7.96695C13.3333 6.77282 12.964 5.58055 12.3333 4.66699" stroke="#A4A7AE" stroke-linecap="round" stroke-linejoin="round"/>
25
+ </svg> Operation Complete, Reload Page'.html_safe,
26
+ variant: "outline-secondary d-inline-flex align-items-center gap-1",
27
+ type: "button",
28
+ html_class: "kaui-button custom-hover mx-2"
29
+ } %>
30
+ <% end %>
31
+
32
+
33
+ <% if kpm_plugin_installed?(@nodes_info) %>
34
+ <div class="pull-right">
35
+ <%= link_to plugins_path do %>
36
+ <%= render "kaui/components/button/button", {
37
+ label: 'Install new plugin',
38
+ variant: "outline-secondary d-inline-flex align-items-center gap-1",
39
+ type: "button",
40
+ html_class: "kaui-dropdown custom-hover",
41
+ } %>
42
+ <% end %>
43
+ </div>
44
+ <% end %>
45
+ </span>
46
+ </div>
2
47
 
3
- <div class="column-block">
48
+ <!-- Button Tabs -->
49
+ <div class="plugin-tabs my-4">
50
+ <button type="button" class="plugin-tab activelink" data-target=".official-plugins-table">Official Plugins</button>
51
+ <button type="button" class="plugin-tab" data-target=".nodes-table-wrapper">Configured Instances</button>
52
+ <button type="button" class="plugin-tab" data-target=".logs-table-wrapper">Logs</button>
53
+ </div>
4
54
 
5
- <h1>Configured instances
6
- <div id="install-in-progress" class="btn btn-xs text-success" style="display: none;"><i class="fa fa-refresh"></i>&nbsp;Operation in progress</div>
7
- <%= link_to('<i class="fa fa-refresh"></i>&nbsp;Operation complete, reload page'.html_safe, url_for, :id => "reload-page", :class => 'btn btn-xs text-success', :style => "display: none;") %>
8
- <% if kpm_plugin_installed?(@nodes_info) %>
9
- <div class="pull-right">
10
- <%= link_to 'Install new plugin', plugins_path %>
55
+ <!-- Plugin Sections -->
56
+ <div id="official-plugins-table">
57
+ <div class="official-plugins-table" style="display: block;">
58
+ <%= render partial: 'kpm/nodes_info/official_plugins', locals: { nodes_info: @nodes_info } %>
59
+ </div>
11
60
  </div>
12
- <% end %>
13
- </h1>
14
61
 
15
- <div id="nodes-table-wrapper">
16
- <%= render :partial => 'kpm/nodes_info/nodes_table', :locals => {:nodes_info => @nodes_info} %>
17
- </div>
62
+ <div id="nodes-table-wrapper" style="">
63
+ <div class="nodes-table-wrapper" style="display: none;">
64
+ <%= render partial: 'kpm/nodes_info/nodes_table', locals: { nodes_info: @nodes_info } %>
65
+ </div>
66
+ </div>
18
67
 
68
+ <div id="logs-table-wrapper">
69
+ <div class="logs-table-wrapper" style="display: none;">
70
+ <%= render partial: 'kpm/nodes_info/logs_table', locals: { kb_host: @kb_host } %>
71
+ </div>
72
+ </div>
73
+ </div>
74
+ </div>
19
75
  </div>
76
+ </div>
20
77
 
21
- <div class="column-block">
22
78
 
23
- <h1>Logs</h1>
79
+ <!-- JavaScript -->
80
+ <%= javascript_tag do %>
81
+ $(document).ready(function () {
82
+ refreshLogs('<%= nodes_info_refresh_path(kb_host: @kb_host, last_event_id: @last_event_id, format: :js) %>');
24
83
 
25
- <div id="logs-table-wrapper">
26
- <%= render :partial => 'kpm/nodes_info/logs_table', :locals => {:kb_host => @kb_host} %>
27
- </div>
84
+ $('.plugin-tab').on('click', function () {
85
+ $('.plugin-tab').removeClass('activelink');
86
+ $(this).addClass('activelink');
28
87
 
29
- </div>
30
- </div>
88
+ const target = $(this).data('target');
31
89
 
32
- <%= javascript_tag do %>
33
- $(document).ready(function() {
34
- refreshLogs('<%= nodes_info_refresh_path(:kb_host => @kb_host, :last_event_id => @last_event_id, :format => :js) %>');
90
+ // Hide all
91
+ $('.official-plugins-table, .nodes-table-wrapper, .logs-table-wrapper').css('display', 'none');
92
+ // Show selected
93
+ $(target).css('display', 'block');
94
+ });
35
95
 
36
- $('.plugin-link').one('ajax:beforeSend', function() {
37
- // Prevent other clicks
38
- $('.plugin-link').removeAttr('data-remote')
39
- .removeAttr('data-method')
40
- .removeAttr('href')
96
+ $('.plugin-link').one('ajax:beforeSend', function () {
97
+ const $link = $(this);
98
+ const $pluginContainer = $link.closest('.official-plugin');
41
99
 
42
- // Spin
100
+ $('.plugin-link').removeAttr('data-remote').removeAttr('data-method').removeAttr('href');
43
101
  $(this).children().addClass('fa-spin');
102
+
103
+ $(this).addClass('loading');
104
+
105
+ if ($pluginContainer.length) {
106
+ $pluginContainer.addClass('loading');
107
+ }
44
108
  });
45
- $('.plugin-link').one('ajax:complete', function() {
46
- // Delay a bit, to give time for the plugin state to change before the next refresh
109
+
110
+ $('.plugin-link').one('ajax:complete', function () {
47
111
  setTimeout(fakeOperationComplete, 6000);
48
112
  });
49
113
 
50
- <%- if @installing %>
51
- // Prevent other clicks
52
- $('.plugin-link').removeAttr('data-remote')
53
- .removeAttr('data-method')
54
- .removeAttr('href')
114
+ <% if @installing %>
115
+ $('.plugin-link').removeAttr('data-remote').removeAttr('data-method').removeAttr('href');
55
116
  $('#nodes-table-wrapper').css({ opacity: 0.5 });
56
-
57
117
  $('#install-in-progress').show();
58
118
  $('#install-in-progress').children().addClass('fa-spin');
59
-
119
+ $('.plugin-link').addClass('loading');
120
+ $('.official-plugin').addClass('loading');
60
121
  setTimeout(fakeOperationComplete, 6000);
61
122
  <% end %>
62
123
 
63
124
  function fakeOperationComplete() {
64
125
  $('#install-in-progress').hide();
65
-
126
+ $('.plugin-link').removeClass('loading');
127
+ $('.official-plugin').removeClass('loading');
66
128
  $('.plugin-link').children().removeClass('fa-spin');
67
129
  $('#nodes-table-wrapper').fadeTo("slow", 0.5);
68
130
  $('#reload-page').fadeIn("slow");
@@ -1,37 +1,57 @@
1
+ <div class="upload-plugin-form">
1
2
  <%= form_tag plugin_install_path, :class => 'form-horizontal' do %>
2
- <div class="form-group">
3
- <%= label_tag :plugin_key, 'Plugin key', :class => 'col-sm-2 control-label' %>
3
+ <div class="form-group d-flex pb-3">
4
+ <%= label_tag :plugin_key, 'Plugin key', :class => 'col-sm-3 control-label' %>
4
5
  <div class="col-sm-9">
5
6
  <%= text_field_tag :plugin_key, '', :class => 'form-control', :placeholder => 'Unique identifier for this plugin, e.g. myCompany:myPluginName', :required => true %>
6
7
  </div>
7
8
  </div>
8
- <div class="form-group">
9
- <%= label_tag :plugin_version, 'Version', :class => 'col-sm-2 control-label' %>
9
+ <div class="form-group d-flex pb-3">
10
+ <%= label_tag :plugin_version, 'Version', :class => 'col-sm-3 control-label' %>
10
11
  <div class="col-sm-9">
11
12
  <%= text_field_tag :plugin_version, '', :class => 'form-control', :placeholder => 'Plugin version', :required => true %>
12
13
  </div>
13
14
  </div>
14
- <div class="form-group">
15
- <%= label_tag :plugin_uri, 'URI', :class => 'col-sm-2 control-label' %>
15
+ <div class="form-group d-flex pb-3">
16
+ <%= label_tag :plugin_uri, 'URI', :class => 'col-sm-3 control-label' %>
16
17
  <div class="col-sm-9">
17
18
  <%= text_field_tag :plugin_uri, '', :class => 'form-control', :placeholder => 'HTTP(S) url accessible from all Kill Bill nodes', :required => true %>
18
19
  </div>
19
20
  </div>
20
- <div class='form-group'>
21
- <div class="col-sm-offset-2 col-sm-10">
22
- <% %w(java ruby).each do |type| %>
23
- <div class="checkbox">
24
- <%= label_tag :plugin_type do %>
25
- <%= radio_button_tag :plugin_type, type, (type == 'java') %>
26
- <%= type %>
21
+
22
+ <div class="form-group d-flex pb-3">
23
+ <%= label_tag :plugin_type, 'Type', class: 'col-sm-3 control-label' %>
24
+ <div class="col-sm-offset-2 col-sm-9">
25
+ <div class="toggle-segment">
26
+ <% %w(java ruby).each do |type| %>
27
+ <div class="radio">
28
+ <%= label_tag "plugin_type_#{type}" do %>
29
+ <%= radio_button_tag :plugin_type, type, (type == 'java'), id: "plugin_type_#{type}" %>
30
+ <%= type.capitalize %>
27
31
  <% end %>
28
32
  </div>
29
- <% end %>
33
+ <% end %>
34
+ </div>
30
35
  </div>
31
36
  </div>
32
- <div class="form-group">
33
- <div class="col-sm-offset-2 col-sm-10">
34
- <%= submit_tag 'Install', :class => 'btn btn-default' %>
35
- </div>
37
+
38
+ <div class="form-group d-flex justify-content-end pt-3 border-top">
39
+ <%= render "kaui/components/button/button", {
40
+ label: 'Close',
41
+ variant: "outline-secondary d-inline-flex align-items-center gap-1",
42
+ type: "button",
43
+ html_class: "kaui-button custom-hover mx-2",
44
+ html_options: {
45
+ id: "closeButton",
46
+ onclick: "window.history.back();"
47
+ }
48
+ } %>
49
+ <%= render "kaui/components/button/button", {
50
+ label: 'Install',
51
+ variant: "outline-secondary d-inline-flex align-items-center gap-1",
52
+ type: "submit",
53
+ html_class: "kaui-dropdown custom-hover"
54
+ } %>
36
55
  </div>
37
56
  <% end %>
57
+ </div>
@@ -1,5 +1,5 @@
1
1
  <% if @warning_message.blank? %>
2
- <table id="plugins-table" class="table table-condensed table-striped mobile-data">
2
+ <table id="plugins-table">
3
3
  <thead>
4
4
  <tr>
5
5
  <th>Name</th>
@@ -12,7 +12,7 @@
12
12
  <tr>
13
13
  <td><%= name %></td>
14
14
  <td><%= version %></td>
15
- <td><%= link_to '<i class="fa fa-cloud-download"></i>'.html_safe, plugin_install_path(:plugin_key => name), :method => :post, :title => 'Install' %></td>
15
+ <td><%= link_to 'Install', plugin_install_path(:plugin_key => name), :method => :post, :title => 'Install' %></td>
16
16
  </tr>
17
17
  <% end %>
18
18
  </tbody>
@@ -26,7 +26,11 @@
26
26
  $('#plugins-table').dataTable({
27
27
  "dom": "t",
28
28
  "paging": false,
29
- "ordering": false
29
+ "ordering": true,
30
+ "columnDefs": [
31
+ { "orderable": true, "targets": [0, 1] },
32
+ { "orderable": false, "targets": [2] }
33
+ ]
30
34
  });
31
35
  });
32
36
  <% end %>
@@ -1,18 +1,45 @@
1
- <div class="search">
2
1
 
3
- <div class="column-block">
4
-
5
- <h1>Official plugins</h1>
6
-
7
- <%= render :partial => 'kpm/plugins/plugins_table', :locals => {:plugins => @plugins} %>
8
-
9
- </div>
10
-
11
- <div class="column-block">
12
-
13
- <h1>Upload plugin</h1>
14
- <%= render 'form' %>
15
2
 
3
+ <div class="kaui-container kpm-plugins-index">
4
+ <%= render partial: 'kaui/components/breadcrumb/breadcrumb', locals: {
5
+ breadcrumbs: [
6
+ { label: 'Settings', href: '/' },
7
+ { label: "Plugin Manager", href: '#' }
8
+ ]
9
+ } %>
10
+ <div class="d-flex " style="gap: 4rem;">
11
+ <%= render :template => 'kaui/layouts/kaui_setting_sidebar' %>
12
+
13
+ <div class="official-plugins w-100" style="max-width: <%= request.path.include?('/accounts/') ? '67.5rem' : '80rem' %>;">
14
+ <div class="d-flex flex-column ">
15
+ <div class="official-plugins-header mb-4">
16
+ <div class="d-flex align-items-center">
17
+ <h2>Official plugins</h2>
18
+ </div>
19
+ </div>
20
+ <%= render :partial => 'kpm/plugins/plugins_table', :locals => {:plugins => @plugins} %>
21
+ </div>
22
+ </div>
16
23
  </div>
24
+ </div>
17
25
 
26
+ <div class="register kpm-plugins-index">
27
+ <div class="">
28
+ <div class="mx-auto" style="max-width: 37.5rem;">
29
+ <h5 class="upload-plugin-title border-bottom">
30
+ <span class="icon-container">
31
+ <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
32
+ <path d="M16.25 3.74967L17.9167 2.08301" stroke="#414651" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
33
+ <path d="M2.08301 17.9167L3.74967 16.25" stroke="#414651" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
34
+ <path d="M9.82774 13.5773L6.00625 9.75578C5.68081 9.43036 5.15318 9.43036 4.82773 9.75578L2.91699 11.6665V14.3095C2.91699 14.7515 3.09258 15.1754 3.40515 15.488L4.0955 16.1784C4.40807 16.4909 4.83198 16.6665 5.27402 16.6665H7.91699L9.82774 14.7558C10.1532 14.4304 10.1532 13.9027 9.82774 13.5773Z" stroke="#414651" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
35
+ <path d="M10.1728 5.24375C9.84736 5.56919 9.84736 6.09682 10.1728 6.42227L13.9943 10.2438C14.3197 10.5692 14.8474 10.5692 15.1728 10.2438L17.0835 8.33301V5.69003C17.0835 5.248 16.9079 4.82408 16.5954 4.51152L15.905 3.82117C15.5924 3.5086 15.1685 3.33301 14.7265 3.33301H12.0835L10.1728 5.24375Z" stroke="#414651" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
36
+ <path d="M7.08301 10.4167L8.74967 8.75M9.58301 12.9167L11.2497 11.25" stroke="#414651" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
37
+ </svg>
38
+ </span>
39
+ Upload plugin
40
+ </h5>
41
+ <%= render 'form' %>
42
+
43
+ </div>
44
+ </div>
18
45
  </div>
data/lib/kpm/client.rb CHANGED
@@ -32,7 +32,7 @@ module Killbill
32
32
  def stream_osgi_logs(writer, host, last_event_id_ref)
33
33
  url = host
34
34
  url = "http://#{url}" unless url.starts_with?('http:')
35
- SSE::Client.new(url + KILLBILL_OSGI_LOGGER_PREFIX, last_event_id: last_event_id_ref.get, logger: Rails.logger) do |client|
35
+ SSE::Client.new(url + KILLBILL_OSGI_LOGGER_PREFIX, last_event_id: last_event_id_ref.get, logger: Logger.new($stdout)) do |client|
36
36
  client.on_event do |event|
37
37
  writer.write(event.data, id: event.id)
38
38
  last_event_id_ref.set(event.id)
data/lib/kpm/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KPM
4
- VERSION = '3.0.5'
4
+ VERSION = '4.0.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: killbill-kpm-ui
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.5
4
+ version: 4.0.0
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: 2025-04-10 00:00:00.000000000 Z
11
+ date: 2025-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: killbill-assets-ui
@@ -86,9 +86,13 @@ files:
86
86
  - app/controllers/kpm/nodes_info_controller.rb
87
87
  - app/controllers/kpm/plugins_controller.rb
88
88
  - app/helpers/kpm/application_helper.rb
89
+ - app/views/kaui/components/breadcrumb/_breadcrumb.html.erb
90
+ - app/views/kaui/components/button/_button.html.erb
91
+ - app/views/kaui/layouts/kaui_setting_sidebar.html.erb
89
92
  - app/views/kpm/layouts/kpm_application.html.erb
90
93
  - app/views/kpm/nodes_info/_logs_table.html.erb
91
94
  - app/views/kpm/nodes_info/_nodes_table.html.erb
95
+ - app/views/kpm/nodes_info/_official_plugins.html.erb
92
96
  - app/views/kpm/nodes_info/index.html.erb
93
97
  - app/views/kpm/plugins/_form.html.erb
94
98
  - app/views/kpm/plugins/_plugins_table.html.erb