@rancher/shell 0.3.22 → 0.3.23
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.
- package/babel.config.js +3 -0
- package/components/SortableTable/paging.js +10 -0
- package/components/form/GitPicker.vue +16 -0
- package/components/form/SelectOrCreateAuthSecret.vue +9 -3
- package/edit/resources.cattle.io.backup.vue +3 -1
- package/edit/resources.cattle.io.restore.vue +3 -1
- package/package.json +1 -1
- package/rancher-components/BadgeState/BadgeState.vue +1 -5
- package/rancher-components/Banner/Banner.test.ts +1 -51
- package/rancher-components/Banner/Banner.vue +53 -134
- package/rancher-components/Card/Card.vue +7 -24
- package/rancher-components/Form/Checkbox/Checkbox.test.ts +29 -20
- package/rancher-components/Form/Checkbox/Checkbox.vue +20 -45
- package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +8 -2
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +10 -22
- package/rancher-components/Form/Radio/RadioButton.vue +13 -30
- package/rancher-components/Form/Radio/RadioGroup.vue +7 -26
- package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +6 -7
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.test.ts +38 -25
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +11 -23
- package/rancher-components/LabeledTooltip/LabeledTooltip.vue +5 -19
- package/rancher-components/StringList/StringList.test.ts +49 -453
- package/rancher-components/StringList/StringList.vue +58 -92
- package/types/shell/index.d.ts +15 -9
- package/utils/__tests__/formatter.test.ts +77 -0
- package/utils/formatter.js +11 -0
- package/vue.config.js +6 -2
- package/rancher-components/Card/Card.test.ts +0 -37
- package/rancher-components/Form/Radio/RadioButton.test.ts +0 -31
- package/yarn-error.log +0 -200
|
@@ -30,10 +30,10 @@ const CLASS = {
|
|
|
30
30
|
* Manage a list of strings
|
|
31
31
|
*/
|
|
32
32
|
export default Vue.extend({
|
|
33
|
-
|
|
34
|
-
name: 'StringList',
|
|
35
33
|
components: { LabeledInput },
|
|
36
34
|
|
|
35
|
+
name: 'StringList',
|
|
36
|
+
|
|
37
37
|
props: {
|
|
38
38
|
/**
|
|
39
39
|
* The items source
|
|
@@ -85,11 +85,11 @@ export default Vue.extend({
|
|
|
85
85
|
},
|
|
86
86
|
data() {
|
|
87
87
|
return {
|
|
88
|
-
value:
|
|
89
|
-
selected:
|
|
90
|
-
|
|
91
|
-
isCreateItem:
|
|
92
|
-
errors:
|
|
88
|
+
value: null as string | null,
|
|
89
|
+
selected: null as string | null,
|
|
90
|
+
isEditItem: null as string | null,
|
|
91
|
+
isCreateItem: false,
|
|
92
|
+
errors: { duplicate: false } as Record<Error, boolean>
|
|
93
93
|
};
|
|
94
94
|
},
|
|
95
95
|
|
|
@@ -100,8 +100,8 @@ export default Vue.extend({
|
|
|
100
100
|
*/
|
|
101
101
|
errorMessagesArray(): string[] {
|
|
102
102
|
return (Object.keys(this.errors) as Error[])
|
|
103
|
-
.filter(
|
|
104
|
-
.map(
|
|
103
|
+
.filter(f => !!(this.errors)[f])
|
|
104
|
+
.map(k => this.errorMessages[k]);
|
|
105
105
|
},
|
|
106
106
|
},
|
|
107
107
|
|
|
@@ -113,35 +113,23 @@ export default Vue.extend({
|
|
|
113
113
|
this.toggleEditMode(false);
|
|
114
114
|
this.toggleCreateMode(false);
|
|
115
115
|
},
|
|
116
|
-
value(val) {
|
|
117
|
-
this.$emit('type:item', val);
|
|
118
|
-
},
|
|
119
|
-
errors: {
|
|
120
|
-
handler(val) {
|
|
121
|
-
this.$emit('errors', val);
|
|
122
|
-
},
|
|
123
|
-
deep: true
|
|
124
|
-
}
|
|
125
116
|
},
|
|
126
117
|
|
|
127
118
|
methods: {
|
|
128
119
|
onChange(value: string) {
|
|
129
120
|
this.value = value;
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
this.value
|
|
134
|
-
];
|
|
135
|
-
|
|
121
|
+
/**
|
|
122
|
+
* Remove duplicate error when a new value is typed
|
|
123
|
+
*/
|
|
136
124
|
this.toggleError(
|
|
137
125
|
'duplicate',
|
|
138
|
-
|
|
139
|
-
this.isCreateItem ? INPUT.create : INPUT.edit
|
|
126
|
+
false,
|
|
127
|
+
this.isCreateItem ? INPUT.create : INPUT.edit,
|
|
140
128
|
);
|
|
141
129
|
},
|
|
142
130
|
|
|
143
131
|
onSelect(item: string) {
|
|
144
|
-
if (this.
|
|
132
|
+
if (this.isCreateItem || this.isEditItem === item) {
|
|
145
133
|
return;
|
|
146
134
|
}
|
|
147
135
|
this.selected = item;
|
|
@@ -172,7 +160,7 @@ export default Vue.extend({
|
|
|
172
160
|
},
|
|
173
161
|
|
|
174
162
|
onClickEmptyBody() {
|
|
175
|
-
if (!this.isCreateItem && !this.
|
|
163
|
+
if (!this.isCreateItem && !this.isEditItem) {
|
|
176
164
|
this.toggleCreateMode(true);
|
|
177
165
|
}
|
|
178
166
|
},
|
|
@@ -188,43 +176,38 @@ export default Vue.extend({
|
|
|
188
176
|
|
|
189
177
|
return;
|
|
190
178
|
}
|
|
191
|
-
if (this.
|
|
192
|
-
this.deleteAndSelectNext(this.editedItem);
|
|
179
|
+
if (this.isEditItem) {
|
|
193
180
|
this.toggleEditMode(false);
|
|
194
181
|
|
|
195
182
|
return;
|
|
196
183
|
}
|
|
197
184
|
if (this.selected) {
|
|
198
|
-
this.
|
|
199
|
-
}
|
|
200
|
-
},
|
|
201
|
-
|
|
202
|
-
deleteAndSelectNext(currItem: string) {
|
|
203
|
-
const index = findStringIndex(this.items, currItem, false);
|
|
185
|
+
const index = findStringIndex(this.items, this.selected, false);
|
|
204
186
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
187
|
+
if (index !== -1) {
|
|
188
|
+
/**
|
|
189
|
+
* Select the next item in the list when an item is to be deleted.
|
|
190
|
+
*/
|
|
191
|
+
const item = (this.items[index + 1] || this.items[index - 1]);
|
|
210
192
|
|
|
211
|
-
|
|
212
|
-
|
|
193
|
+
this.onSelect(item);
|
|
194
|
+
this.setFocus(item);
|
|
213
195
|
|
|
214
|
-
|
|
196
|
+
this.deleteItem(this.items[index]);
|
|
197
|
+
}
|
|
215
198
|
}
|
|
216
199
|
},
|
|
217
200
|
|
|
218
201
|
setFocus(refId: string) {
|
|
219
|
-
this.$nextTick(() =>
|
|
202
|
+
this.$nextTick(() => this.getElemByRef(refId)?.focus());
|
|
220
203
|
},
|
|
221
204
|
|
|
222
205
|
/**
|
|
223
206
|
* Move scrollbar when the selected item is over the top or bottom side of the box
|
|
224
207
|
*/
|
|
225
208
|
moveScrollbar(arrow: Arrow, value?: number) {
|
|
226
|
-
const box = this.getElemByRef(BOX)
|
|
227
|
-
const item = this.getElemByRef(this.selected || '')
|
|
209
|
+
const box = this.getElemByRef(BOX);
|
|
210
|
+
const item = this.getElemByRef(this.selected || '');
|
|
228
211
|
|
|
229
212
|
if (box && item && item.className.includes(CLASS.item)) {
|
|
230
213
|
const boxRect = box.getClientRects()[0];
|
|
@@ -246,14 +229,13 @@ export default Vue.extend({
|
|
|
246
229
|
*/
|
|
247
230
|
toggleError(type: Error, val: boolean, refId?: string) {
|
|
248
231
|
this.errors[type] = val;
|
|
249
|
-
|
|
250
232
|
if (refId) {
|
|
251
233
|
this.toggleErrorClass(refId, val);
|
|
252
234
|
}
|
|
253
235
|
},
|
|
254
236
|
|
|
255
237
|
toggleErrorClass(refId: string, val: boolean) {
|
|
256
|
-
const input =
|
|
238
|
+
const input = this.getElemByRef(refId)?.$el;
|
|
257
239
|
|
|
258
240
|
if (input) {
|
|
259
241
|
if (val) {
|
|
@@ -268,11 +250,7 @@ export default Vue.extend({
|
|
|
268
250
|
* Show/Hide the input line to create new item
|
|
269
251
|
*/
|
|
270
252
|
toggleCreateMode(show: boolean) {
|
|
271
|
-
if (this.readonly) {
|
|
272
|
-
return;
|
|
273
|
-
}
|
|
274
253
|
if (show) {
|
|
275
|
-
this.toggleEditMode(false);
|
|
276
254
|
this.value = '';
|
|
277
255
|
|
|
278
256
|
this.isCreateItem = true;
|
|
@@ -290,34 +268,31 @@ export default Vue.extend({
|
|
|
290
268
|
* Show/Hide the in-line editing to edit an existing item
|
|
291
269
|
*/
|
|
292
270
|
toggleEditMode(show: boolean, item?: string) {
|
|
293
|
-
if (this.readonly) {
|
|
294
|
-
return;
|
|
295
|
-
}
|
|
296
271
|
if (show) {
|
|
297
272
|
this.toggleCreateMode(false);
|
|
298
|
-
this.value = this.
|
|
273
|
+
this.value = this.isEditItem;
|
|
299
274
|
|
|
300
|
-
this.
|
|
275
|
+
this.isEditItem = item || '';
|
|
301
276
|
this.setFocus(INPUT.edit);
|
|
302
277
|
} else {
|
|
303
278
|
this.value = null;
|
|
304
279
|
this.toggleError('duplicate', false);
|
|
305
280
|
this.onSelectLeave();
|
|
306
281
|
|
|
307
|
-
this.
|
|
282
|
+
this.isEditItem = null;
|
|
308
283
|
}
|
|
309
284
|
},
|
|
310
285
|
|
|
311
286
|
getElemByRef(id: string) {
|
|
312
287
|
const ref = this.$refs[id];
|
|
313
288
|
|
|
314
|
-
return Array.isArray(ref) ? ref[0] : ref;
|
|
289
|
+
return (Array.isArray(ref) ? ref[0] : ref) as any;
|
|
315
290
|
},
|
|
316
291
|
|
|
317
292
|
/**
|
|
318
293
|
* Create a new item and insert in the items list
|
|
319
294
|
*/
|
|
320
|
-
saveItem(
|
|
295
|
+
saveItem() {
|
|
321
296
|
const value = this.value?.trim();
|
|
322
297
|
|
|
323
298
|
if (value) {
|
|
@@ -326,20 +301,21 @@ export default Vue.extend({
|
|
|
326
301
|
value,
|
|
327
302
|
];
|
|
328
303
|
|
|
329
|
-
if (
|
|
330
|
-
this.
|
|
304
|
+
if (hasDuplicatedStrings(items, this.caseSensitive)) {
|
|
305
|
+
this.toggleError('duplicate', true, INPUT.create);
|
|
306
|
+
|
|
307
|
+
return;
|
|
331
308
|
}
|
|
332
|
-
}
|
|
333
309
|
|
|
334
|
-
|
|
335
|
-
this.toggleCreateMode(false);
|
|
310
|
+
this.updateItems(items);
|
|
336
311
|
}
|
|
312
|
+
this.toggleCreateMode(false);
|
|
337
313
|
},
|
|
338
314
|
|
|
339
315
|
/**
|
|
340
316
|
* Update an existing item in the items list
|
|
341
317
|
*/
|
|
342
|
-
updateItem(item: string
|
|
318
|
+
updateItem(item: string) {
|
|
343
319
|
const value = this.value?.trim();
|
|
344
320
|
|
|
345
321
|
if (value) {
|
|
@@ -350,21 +326,22 @@ export default Vue.extend({
|
|
|
350
326
|
items[index] = value;
|
|
351
327
|
}
|
|
352
328
|
|
|
353
|
-
if (
|
|
354
|
-
this.
|
|
329
|
+
if (hasDuplicatedStrings(items, this.caseSensitive)) {
|
|
330
|
+
this.toggleError('duplicate', true, INPUT.edit);
|
|
331
|
+
|
|
332
|
+
return;
|
|
355
333
|
}
|
|
356
|
-
}
|
|
357
334
|
|
|
358
|
-
|
|
359
|
-
this.toggleEditMode(false);
|
|
335
|
+
this.updateItems(items);
|
|
360
336
|
}
|
|
337
|
+
this.toggleEditMode(false);
|
|
361
338
|
},
|
|
362
339
|
|
|
363
340
|
/**
|
|
364
341
|
* Remove an item from items list
|
|
365
342
|
*/
|
|
366
343
|
deleteItem(item?: string) {
|
|
367
|
-
const items = this.items.filter(
|
|
344
|
+
const items = this.items.filter(f => f !== item);
|
|
368
345
|
|
|
369
346
|
this.updateItems(items);
|
|
370
347
|
},
|
|
@@ -410,20 +387,19 @@ export default Vue.extend({
|
|
|
410
387
|
@blur="onSelectLeave(item)"
|
|
411
388
|
>
|
|
412
389
|
<span
|
|
413
|
-
v-if="!
|
|
390
|
+
v-if="!isEditItem || isEditItem !== item"
|
|
414
391
|
class="label static"
|
|
415
392
|
>
|
|
416
393
|
{{ item }}
|
|
417
394
|
</span>
|
|
418
395
|
<LabeledInput
|
|
419
|
-
v-if="
|
|
396
|
+
v-if="isEditItem && isEditItem === item"
|
|
420
397
|
ref="item-edit"
|
|
421
|
-
:data-testid="`item-edit-${item}`"
|
|
422
398
|
class="edit-input static"
|
|
423
399
|
:value="value != null ? value : item"
|
|
424
400
|
@input="onChange($event)"
|
|
425
|
-
@blur.prevent="
|
|
426
|
-
@keydown.native.enter="updateItem(item
|
|
401
|
+
@blur.prevent="toggleEditMode(false)"
|
|
402
|
+
@keydown.native.enter="updateItem(item)"
|
|
427
403
|
/>
|
|
428
404
|
</div>
|
|
429
405
|
<div
|
|
@@ -432,14 +408,12 @@ export default Vue.extend({
|
|
|
432
408
|
>
|
|
433
409
|
<LabeledInput
|
|
434
410
|
ref="item-create"
|
|
435
|
-
data-testid="item-create"
|
|
436
411
|
class="create-input static"
|
|
437
412
|
type="text"
|
|
438
413
|
:value="value"
|
|
439
414
|
:placeholder="placeholder"
|
|
440
415
|
@input="onChange($event)"
|
|
441
|
-
@
|
|
442
|
-
@keydown.native.enter="saveItem(!errors.duplicate)"
|
|
416
|
+
@keydown.native.enter="saveItem"
|
|
443
417
|
/>
|
|
444
418
|
</div>
|
|
445
419
|
</div>
|
|
@@ -453,32 +427,25 @@ export default Vue.extend({
|
|
|
453
427
|
class="action-buttons"
|
|
454
428
|
>
|
|
455
429
|
<button
|
|
456
|
-
data-testid="button-remove"
|
|
457
430
|
class="btn btn-sm role-tertiary remove-button"
|
|
458
|
-
:disabled="!selected && !isCreateItem && !
|
|
431
|
+
:disabled="!selected && !isCreateItem && !isEditItem"
|
|
459
432
|
@mousedown.prevent="onClickMinusButton"
|
|
460
433
|
>
|
|
461
434
|
<span class="icon icon-minus icon-sm" />
|
|
462
435
|
</button>
|
|
463
436
|
<button
|
|
464
|
-
data-testid="button-add"
|
|
465
437
|
class="btn btn-sm role-tertiary add-button"
|
|
466
|
-
:disabled="isCreateItem
|
|
438
|
+
:disabled="isCreateItem"
|
|
467
439
|
@click.prevent="onClickPlusButton"
|
|
468
440
|
>
|
|
469
441
|
<span class="icon icon-plus icon-sm" />
|
|
470
442
|
</button>
|
|
471
443
|
</div>
|
|
472
444
|
<div class="messages">
|
|
473
|
-
<i
|
|
474
|
-
v-if="errorMessagesArray.length > 0"
|
|
475
|
-
data-testid="i-warning-icon"
|
|
476
|
-
class="icon icon-warning icon-lg"
|
|
477
|
-
/>
|
|
445
|
+
<i v-if="errorMessagesArray.length > 0" class="icon icon-warning icon-lg" />
|
|
478
446
|
<span
|
|
479
447
|
v-for="(msg, idx) in errorMessagesArray"
|
|
480
448
|
:key="idx"
|
|
481
|
-
:data-testid="`span-error-message-${msg}`"
|
|
482
449
|
class="error"
|
|
483
450
|
>
|
|
484
451
|
{{ idx > 0 ? '; ' : '' }}
|
|
@@ -532,7 +499,6 @@ export default Vue.extend({
|
|
|
532
499
|
width: auto;
|
|
533
500
|
user-select: none;
|
|
534
501
|
overflow: hidden;
|
|
535
|
-
white-space: no-wrap;
|
|
536
502
|
text-overflow: ellipsis;
|
|
537
503
|
padding-top: 1px;
|
|
538
504
|
}
|
package/types/shell/index.d.ts
CHANGED
|
@@ -3376,6 +3376,12 @@ export function haveSetFavIcon(): boolean;
|
|
|
3376
3376
|
export function setFavIcon(store: any): void;
|
|
3377
3377
|
}
|
|
3378
3378
|
|
|
3379
|
+
// @shell/utils/formatter
|
|
3380
|
+
|
|
3381
|
+
declare module '@shell/utils/formatter' {
|
|
3382
|
+
export function formatEncryptionSecretNames(secrets: any, chartNamespace: any): any;
|
|
3383
|
+
}
|
|
3384
|
+
|
|
3379
3385
|
// @shell/utils/grafana
|
|
3380
3386
|
|
|
3381
3387
|
declare module '@shell/utils/grafana' {
|
|
@@ -3599,35 +3605,35 @@ export namespace KEY {
|
|
|
3599
3605
|
}
|
|
3600
3606
|
}
|
|
3601
3607
|
|
|
3602
|
-
// @shell/utils/poller
|
|
3608
|
+
// @shell/utils/poller
|
|
3603
3609
|
|
|
3604
|
-
declare module '@shell/utils/poller
|
|
3605
|
-
export default class
|
|
3610
|
+
declare module '@shell/utils/poller' {
|
|
3611
|
+
export default class Poller {
|
|
3606
3612
|
constructor(fn: any, pollRateMs: any, maxRetries?: number);
|
|
3607
3613
|
fn: any;
|
|
3608
3614
|
pollRateMs: any;
|
|
3609
3615
|
maxRetries: number;
|
|
3610
|
-
|
|
3616
|
+
intervalId: any;
|
|
3611
3617
|
tryCount: number;
|
|
3612
3618
|
start(): void;
|
|
3613
3619
|
stop(): void;
|
|
3614
|
-
_poll(): void;
|
|
3615
3620
|
_intervalMethod(): Promise<void>;
|
|
3616
3621
|
}
|
|
3617
3622
|
}
|
|
3618
3623
|
|
|
3619
|
-
// @shell/utils/poller
|
|
3624
|
+
// @shell/utils/poller-sequential
|
|
3620
3625
|
|
|
3621
|
-
declare module '@shell/utils/poller' {
|
|
3622
|
-
export default class
|
|
3626
|
+
declare module '@shell/utils/poller-sequential' {
|
|
3627
|
+
export default class PollerSequential {
|
|
3623
3628
|
constructor(fn: any, pollRateMs: any, maxRetries?: number);
|
|
3624
3629
|
fn: any;
|
|
3625
3630
|
pollRateMs: any;
|
|
3626
3631
|
maxRetries: number;
|
|
3627
|
-
|
|
3632
|
+
timeoutId: any;
|
|
3628
3633
|
tryCount: number;
|
|
3629
3634
|
start(): void;
|
|
3630
3635
|
stop(): void;
|
|
3636
|
+
_poll(): void;
|
|
3631
3637
|
_intervalMethod(): Promise<void>;
|
|
3632
3638
|
}
|
|
3633
3639
|
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { formatEncryptionSecretNames } from '@shell/utils/formatter';
|
|
2
|
+
|
|
3
|
+
describe('formatter', () => {
|
|
4
|
+
const secrets = [
|
|
5
|
+
{
|
|
6
|
+
id: 'test5',
|
|
7
|
+
_type: 'Opaque',
|
|
8
|
+
data: { hash: 'test5', 'encryption-provider-config.yaml': 'MTIzNFFhYWEh' },
|
|
9
|
+
metadata: {
|
|
10
|
+
name: 'test5',
|
|
11
|
+
namespace: 'test',
|
|
12
|
+
state: {
|
|
13
|
+
error: false, message: 'Resource is always ready', name: 'active', transitioning: false
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
id: 'test2',
|
|
19
|
+
_type: 'Opaque',
|
|
20
|
+
data: { hash: 'test', 'encryption-provider-config.yaml': 'MTIzNFFhYWEh' },
|
|
21
|
+
metadata: {
|
|
22
|
+
name: 'test2',
|
|
23
|
+
namespace: 'test',
|
|
24
|
+
state: {
|
|
25
|
+
error: false, message: 'Resource is always ready', name: 'active', transitioning: false
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
id: 'test4',
|
|
31
|
+
_type: 'Opaque',
|
|
32
|
+
data: { hash: 'test4' },
|
|
33
|
+
metadata: {
|
|
34
|
+
name: 'test4',
|
|
35
|
+
namespace: 'test',
|
|
36
|
+
state: {
|
|
37
|
+
error: false, message: 'Resource is always ready', name: 'active', transitioning: false
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
id: 'test1',
|
|
43
|
+
_type: 'Custom',
|
|
44
|
+
data: { hash: 'test1', 'encryption-provider-config.yaml': 'MTIzNFFhYWEh' },
|
|
45
|
+
metadata: {
|
|
46
|
+
name: 'test1',
|
|
47
|
+
namespace: 'test',
|
|
48
|
+
state: {
|
|
49
|
+
error: false, message: 'Resource is always ready', name: 'active', transitioning: false
|
|
50
|
+
},
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: 'test6',
|
|
55
|
+
_type: 'Opaque',
|
|
56
|
+
data: { hash: 'test5', 'encryption-provider-config.yaml': 'MTIzNFFhYWEh' },
|
|
57
|
+
metadata: {
|
|
58
|
+
name: 'test5',
|
|
59
|
+
namespace: 'test',
|
|
60
|
+
state: {
|
|
61
|
+
error: true, message: 'Failed', name: 'active', transitioning: true
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}];
|
|
65
|
+
const chart = 'test';
|
|
66
|
+
|
|
67
|
+
it.each([[chart, 2], ['test1', 0]])('should show correct number of secrets', (chartVal: string, result: number) => {
|
|
68
|
+
const res = formatEncryptionSecretNames(secrets, chartVal);
|
|
69
|
+
|
|
70
|
+
expect(res).toHaveLength(result);
|
|
71
|
+
});
|
|
72
|
+
it('should return correct results in a correct order', () => {
|
|
73
|
+
const res = formatEncryptionSecretNames(secrets, chart);
|
|
74
|
+
|
|
75
|
+
expect(res).toStrictEqual(['test2', 'test5']);
|
|
76
|
+
});
|
|
77
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
|
|
2
|
+
import { SECRET_TYPES } from '@shell/config/secret';
|
|
3
|
+
|
|
4
|
+
export function formatEncryptionSecretNames(secrets, chartNamespace) {
|
|
5
|
+
return secrets.filter(
|
|
6
|
+
(secret) => (secret.data || {})['encryption-provider-config.yaml'] &&
|
|
7
|
+
secret.metadata.namespace === chartNamespace &&
|
|
8
|
+
!secret.metadata?.state?.error &&
|
|
9
|
+
secret._type === SECRET_TYPES.OPAQUE
|
|
10
|
+
).map((secret) => secret.metadata.name).sort();
|
|
11
|
+
}
|
package/vue.config.js
CHANGED
|
@@ -72,7 +72,9 @@ module.exports = function(dir, _appConfig) {
|
|
|
72
72
|
];
|
|
73
73
|
|
|
74
74
|
if (instrumentCode) {
|
|
75
|
-
babelPlugins.push(
|
|
75
|
+
babelPlugins.push([
|
|
76
|
+
'babel-plugin-istanbul', { extension: ['.js', '.vue'] }, 'add-vue'
|
|
77
|
+
]);
|
|
76
78
|
|
|
77
79
|
console.warn('Instrumenting code for coverage'); // eslint-disable-line no-console
|
|
78
80
|
}
|
|
@@ -451,7 +453,9 @@ module.exports = function(dir, _appConfig) {
|
|
|
451
453
|
];
|
|
452
454
|
|
|
453
455
|
if (instrumentCode) {
|
|
454
|
-
babelPlugins.push(
|
|
456
|
+
babelPlugins.push([
|
|
457
|
+
'babel-plugin-istanbul', { extension: ['.js', '.vue'] }, 'add-vue'
|
|
458
|
+
]);
|
|
455
459
|
|
|
456
460
|
console.warn('Instrumenting code for coverage'); // eslint-disable-line no-console
|
|
457
461
|
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { mount } from '@vue/test-utils';
|
|
2
|
-
import { Card } from './index';
|
|
3
|
-
|
|
4
|
-
describe('component: Card', () => {
|
|
5
|
-
const title = 'Card title';
|
|
6
|
-
const body = 'Card body';
|
|
7
|
-
|
|
8
|
-
it('should have a card title', () => {
|
|
9
|
-
const wrapper = mount(Card, {
|
|
10
|
-
propsData: { title },
|
|
11
|
-
slots: { title: '<div>Card title</div>' }
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
const element = wrapper.find('[data-testid="card-title-slot"]');
|
|
15
|
-
|
|
16
|
-
expect(element.exists()).toBe(true);
|
|
17
|
-
expect(element.text()).toBe(title);
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it('should have a card body', () => {
|
|
21
|
-
const wrapper = mount(Card, {
|
|
22
|
-
propsData: { body },
|
|
23
|
-
slots: { body: '<div>Card body</div>' }
|
|
24
|
-
});
|
|
25
|
-
const element = wrapper.find('[data-testid="card-body-slot"]');
|
|
26
|
-
|
|
27
|
-
expect(element.exists()).toBe(true);
|
|
28
|
-
expect(element.text()).toBe(body);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it('should display the default card actions', () => {
|
|
32
|
-
const wrapper = mount(Card);
|
|
33
|
-
const element = wrapper.find('[data-testid="card-actions-slot"]');
|
|
34
|
-
|
|
35
|
-
expect(element.exists()).toBe(true);
|
|
36
|
-
});
|
|
37
|
-
});
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { shallowMount } from '@vue/test-utils';
|
|
2
|
-
import { RadioButton } from './index';
|
|
3
|
-
import { cleanHtmlDirective } from '@shell/plugins/clean-html-directive';
|
|
4
|
-
|
|
5
|
-
describe('radioButton.vue', () => {
|
|
6
|
-
it('renders label slot contents', () => {
|
|
7
|
-
const wrapper = shallowMount(RadioButton, { slots: { label: 'Test Label' } });
|
|
8
|
-
|
|
9
|
-
expect(wrapper.find('.radio-label').text()).toBe('Test Label');
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
it('renders label prop contents', () => {
|
|
13
|
-
const wrapper = shallowMount(
|
|
14
|
-
RadioButton,
|
|
15
|
-
{
|
|
16
|
-
directives: { cleanHtmlDirective },
|
|
17
|
-
propsData: { label: 'Test Label' }
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
expect(wrapper.find('.radio-label').text()).toBe('Test Label');
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
it('renders slot contents when both slot and label prop are provided', () => {
|
|
24
|
-
const wrapper = shallowMount(RadioButton, {
|
|
25
|
-
slots: { label: 'Test Label - Slot' },
|
|
26
|
-
propsData: { label: 'Test Label - Props' },
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
expect(wrapper.find('.radio-label').text()).toBe('Test Label - Slot');
|
|
30
|
-
});
|
|
31
|
-
});
|