@rancher/shell 1.2.1 → 1.2.3
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/package.json +1 -1
- package/rancher-components/BadgeState/BadgeState.vue +3 -3
- package/rancher-components/Banner/Banner.test.ts +5 -1
- package/rancher-components/Banner/Banner.vue +2 -2
- package/rancher-components/Card/Card.vue +4 -4
- package/rancher-components/Form/Checkbox/Checkbox.vue +3 -4
- package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +1 -18
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +37 -65
- package/rancher-components/Form/Radio/RadioButton.test.ts +3 -1
- package/rancher-components/Form/Radio/RadioButton.vue +7 -13
- package/rancher-components/Form/Radio/RadioGroup.vue +3 -4
- package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +4 -6
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +4 -7
- package/rancher-components/LabeledTooltip/LabeledTooltip.vue +4 -9
- package/rancher-components/StringList/StringList.test.ts +0 -270
- package/rancher-components/StringList/StringList.vue +26 -65
- package/scripts/publish-shell.sh +1 -0
- package/rancher-components/Accordion/Accordion.test.ts +0 -45
- package/rancher-components/Accordion/Accordion.vue +0 -86
- package/rancher-components/Accordion/index.ts +0 -1
- package/rancher-components/BadgeState/BadgeState.test.ts +0 -12
- package/rancher-components/components/Accordion/Accordion.test.ts +0 -45
- package/rancher-components/components/Accordion/Accordion.vue +0 -86
- package/rancher-components/components/Accordion/index.ts +0 -1
- package/rancher-components/components/BadgeState/BadgeState.test.ts +0 -12
- package/rancher-components/components/BadgeState/BadgeState.vue +0 -111
- package/rancher-components/components/BadgeState/index.ts +0 -1
- package/rancher-components/components/Banner/Banner.test.ts +0 -63
- package/rancher-components/components/Banner/Banner.vue +0 -244
- package/rancher-components/components/Banner/index.ts +0 -1
- package/rancher-components/components/Card/Card.test.ts +0 -37
- package/rancher-components/components/Card/Card.vue +0 -167
- package/rancher-components/components/Card/index.ts +0 -1
- package/rancher-components/components/Form/Checkbox/Checkbox.test.ts +0 -68
- package/rancher-components/components/Form/Checkbox/Checkbox.vue +0 -420
- package/rancher-components/components/Form/Checkbox/index.ts +0 -1
- package/rancher-components/components/Form/LabeledInput/LabeledInput.test.ts +0 -23
- package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +0 -369
- package/rancher-components/components/Form/LabeledInput/index.ts +0 -1
- package/rancher-components/components/Form/Radio/RadioButton.test.ts +0 -35
- package/rancher-components/components/Form/Radio/RadioButton.vue +0 -287
- package/rancher-components/components/Form/Radio/RadioGroup.test.ts +0 -30
- package/rancher-components/components/Form/Radio/RadioGroup.vue +0 -258
- package/rancher-components/components/Form/Radio/index.ts +0 -2
- package/rancher-components/components/Form/TextArea/TextAreaAutoGrow.vue +0 -170
- package/rancher-components/components/Form/TextArea/index.ts +0 -1
- package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.test.ts +0 -94
- package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.vue +0 -149
- package/rancher-components/components/Form/ToggleSwitch/index.ts +0 -1
- package/rancher-components/components/Form/index.ts +0 -5
- package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +0 -151
- package/rancher-components/components/LabeledTooltip/index.ts +0 -1
- package/rancher-components/components/StringList/StringList.test.ts +0 -484
- package/rancher-components/components/StringList/StringList.vue +0 -611
- package/rancher-components/components/StringList/index.ts +0 -1
- /package/rancher-components/{components/BadgeState → BadgeState}/BadgeState.spec.ts +0 -0
|
@@ -398,276 +398,6 @@ describe('stringList.vue', () => {
|
|
|
398
398
|
});
|
|
399
399
|
});
|
|
400
400
|
|
|
401
|
-
describe('bulk delimiter', () => {
|
|
402
|
-
const delimiter = /;/;
|
|
403
|
-
|
|
404
|
-
describe('add', () => {
|
|
405
|
-
const items: string[] = [];
|
|
406
|
-
|
|
407
|
-
beforeEach(() => {
|
|
408
|
-
wrapper = mount(StringList, {
|
|
409
|
-
propsData: {
|
|
410
|
-
items,
|
|
411
|
-
bulkAdditionDelimiter: delimiter,
|
|
412
|
-
errorMessages: { duplicate: 'error, item is duplicate.' },
|
|
413
|
-
}
|
|
414
|
-
});
|
|
415
|
-
});
|
|
416
|
-
|
|
417
|
-
it('should split values if delimiter set', async() => {
|
|
418
|
-
const value = 'test;test1;test2';
|
|
419
|
-
const result = ['test', 'test1', 'test2'];
|
|
420
|
-
|
|
421
|
-
// activate create mode
|
|
422
|
-
await wrapper.setData({ isCreateItem: true });
|
|
423
|
-
const inputField = wrapper.find('[data-testid="item-create"]');
|
|
424
|
-
|
|
425
|
-
await inputField.setValue(value);
|
|
426
|
-
|
|
427
|
-
// press enter
|
|
428
|
-
await inputField.trigger('keydown.enter');
|
|
429
|
-
await wrapper.vm.$nextTick();
|
|
430
|
-
|
|
431
|
-
const itemsResult = (wrapper.emitted('change') || [])[0][0];
|
|
432
|
-
|
|
433
|
-
expect(JSON.stringify(itemsResult)).toBe(JSON.stringify(result));
|
|
434
|
-
});
|
|
435
|
-
|
|
436
|
-
it('should show warning if one of the values is a duplicate', async() => {
|
|
437
|
-
const value = 'test;test1;test2';
|
|
438
|
-
|
|
439
|
-
await wrapper.setProps({ items: ['test1'] });
|
|
440
|
-
|
|
441
|
-
// activate create mode
|
|
442
|
-
await wrapper.setData({ isCreateItem: true });
|
|
443
|
-
const inputField = wrapper.find('[data-testid="item-create"]');
|
|
444
|
-
|
|
445
|
-
await inputField.setValue(value);
|
|
446
|
-
|
|
447
|
-
// press enter
|
|
448
|
-
await inputField.trigger('keydown.enter');
|
|
449
|
-
await wrapper.vm.$nextTick();
|
|
450
|
-
|
|
451
|
-
const isDuplicate = (wrapper.emitted('errors') || [])[0][0].duplicate;
|
|
452
|
-
|
|
453
|
-
expect(isDuplicate).toBe(true);
|
|
454
|
-
});
|
|
455
|
-
|
|
456
|
-
it('should show a warning if the new values are all duplicates', async() => {
|
|
457
|
-
const value = 'test;test';
|
|
458
|
-
|
|
459
|
-
// activate create mode
|
|
460
|
-
await wrapper.setData({ isCreateItem: true });
|
|
461
|
-
const inputField = wrapper.find('[data-testid="item-create"]');
|
|
462
|
-
|
|
463
|
-
await inputField.setValue(value);
|
|
464
|
-
|
|
465
|
-
// press enter
|
|
466
|
-
await inputField.trigger('keydown.enter');
|
|
467
|
-
await wrapper.vm.$nextTick();
|
|
468
|
-
|
|
469
|
-
const isDuplicate = (wrapper.emitted('errors') || [])[0][0].duplicate;
|
|
470
|
-
|
|
471
|
-
expect(isDuplicate).toBe(true);
|
|
472
|
-
});
|
|
473
|
-
|
|
474
|
-
it('should not consider empty strings at the beginning', async() => {
|
|
475
|
-
const value = ';test;test1;test2';
|
|
476
|
-
const result = ['test', 'test1', 'test2'];
|
|
477
|
-
|
|
478
|
-
// activate create mode
|
|
479
|
-
await wrapper.setData({ isCreateItem: true });
|
|
480
|
-
const inputField = wrapper.find('[data-testid="item-create"]');
|
|
481
|
-
|
|
482
|
-
await inputField.setValue(value);
|
|
483
|
-
|
|
484
|
-
// press enter
|
|
485
|
-
await inputField.trigger('keydown.enter');
|
|
486
|
-
await wrapper.vm.$nextTick();
|
|
487
|
-
|
|
488
|
-
const itemsResult = (wrapper.emitted('change') || [])[0][0];
|
|
489
|
-
|
|
490
|
-
expect(JSON.stringify(itemsResult)).toBe(JSON.stringify(result));
|
|
491
|
-
});
|
|
492
|
-
|
|
493
|
-
it('should not consider empty strings in the middle', async() => {
|
|
494
|
-
const value = 'test;test1;;test2';
|
|
495
|
-
const result = ['test', 'test1', 'test2'];
|
|
496
|
-
|
|
497
|
-
// activate create mode
|
|
498
|
-
await wrapper.setData({ isCreateItem: true });
|
|
499
|
-
const inputField = wrapper.find('[data-testid="item-create"]');
|
|
500
|
-
|
|
501
|
-
await inputField.setValue(value);
|
|
502
|
-
|
|
503
|
-
// press enter
|
|
504
|
-
await inputField.trigger('keydown.enter');
|
|
505
|
-
await wrapper.vm.$nextTick();
|
|
506
|
-
|
|
507
|
-
const itemsResult = (wrapper.emitted('change') || [])[0][0];
|
|
508
|
-
|
|
509
|
-
expect(JSON.stringify(itemsResult)).toBe(JSON.stringify(result));
|
|
510
|
-
});
|
|
511
|
-
|
|
512
|
-
it('should not consider empty strings at the end', async() => {
|
|
513
|
-
const value = 'test;test1;test2;';
|
|
514
|
-
const result = ['test', 'test1', 'test2'];
|
|
515
|
-
|
|
516
|
-
// activate create mode
|
|
517
|
-
await wrapper.setData({ isCreateItem: true });
|
|
518
|
-
const inputField = wrapper.find('[data-testid="item-create"]');
|
|
519
|
-
|
|
520
|
-
await inputField.setValue(value);
|
|
521
|
-
|
|
522
|
-
// press enter
|
|
523
|
-
await inputField.trigger('keydown.enter');
|
|
524
|
-
await wrapper.vm.$nextTick();
|
|
525
|
-
|
|
526
|
-
const itemsResult = (wrapper.emitted('change') || [])[0][0];
|
|
527
|
-
|
|
528
|
-
expect(JSON.stringify(itemsResult)).toBe(JSON.stringify(result));
|
|
529
|
-
});
|
|
530
|
-
});
|
|
531
|
-
|
|
532
|
-
describe('edit', () => {
|
|
533
|
-
const items = ['test1', 'test2'];
|
|
534
|
-
|
|
535
|
-
beforeEach(() => {
|
|
536
|
-
wrapper = mount(StringList, {
|
|
537
|
-
propsData: {
|
|
538
|
-
items,
|
|
539
|
-
bulkAdditionDelimiter: delimiter,
|
|
540
|
-
errorMessages: { duplicate: 'error, item is duplicate.' },
|
|
541
|
-
}
|
|
542
|
-
});
|
|
543
|
-
});
|
|
544
|
-
|
|
545
|
-
it('should split values if delimiter set', async() => {
|
|
546
|
-
const newValue = 'test1;new;values';
|
|
547
|
-
const result = ['test1', 'new', 'values', 'test2'];
|
|
548
|
-
|
|
549
|
-
await wrapper.setData({ editedItem: items[0] });
|
|
550
|
-
const inputField = wrapper.find('[data-testid^="item-edit"]');
|
|
551
|
-
|
|
552
|
-
await inputField.setValue(newValue);
|
|
553
|
-
|
|
554
|
-
// press enter
|
|
555
|
-
await inputField.trigger('keydown.enter');
|
|
556
|
-
await wrapper.vm.$nextTick();
|
|
557
|
-
|
|
558
|
-
const itemsResult = (wrapper.emitted('change') || [])[0][0];
|
|
559
|
-
|
|
560
|
-
expect(JSON.stringify(itemsResult)).toBe(JSON.stringify(result));
|
|
561
|
-
});
|
|
562
|
-
|
|
563
|
-
it('should show warning if one of the values is a duplicate', async() => {
|
|
564
|
-
const newValue = 'test1;test2';
|
|
565
|
-
|
|
566
|
-
await wrapper.setData({ editedItem: items[0] });
|
|
567
|
-
const inputField = wrapper.find('[data-testid^="item-edit"]');
|
|
568
|
-
|
|
569
|
-
await inputField.setValue(newValue);
|
|
570
|
-
|
|
571
|
-
// press enter
|
|
572
|
-
await inputField.trigger('keydown.enter');
|
|
573
|
-
await wrapper.vm.$nextTick();
|
|
574
|
-
|
|
575
|
-
const isDuplicate = (wrapper.emitted('errors') || [])[0][0].duplicate;
|
|
576
|
-
|
|
577
|
-
expect(isDuplicate).toBe(true);
|
|
578
|
-
});
|
|
579
|
-
|
|
580
|
-
it('should show a warning if the new values are all duplicates', async() => {
|
|
581
|
-
const newValue = 'test;test';
|
|
582
|
-
|
|
583
|
-
await wrapper.setData({ editedItem: items[0] });
|
|
584
|
-
const inputField = wrapper.find('[data-testid^="item-edit"]');
|
|
585
|
-
|
|
586
|
-
await inputField.setValue(newValue);
|
|
587
|
-
|
|
588
|
-
// press enter
|
|
589
|
-
await inputField.trigger('keydown.enter');
|
|
590
|
-
await wrapper.vm.$nextTick();
|
|
591
|
-
|
|
592
|
-
const isDuplicate = (wrapper.emitted('errors') || [])[0][0].duplicate;
|
|
593
|
-
|
|
594
|
-
expect(isDuplicate).toBe(true);
|
|
595
|
-
});
|
|
596
|
-
|
|
597
|
-
it('should not consider empty strings at the beginning', async() => {
|
|
598
|
-
const newValue = ';test1;new;value';
|
|
599
|
-
const result = ['test1', 'new', 'value', 'test2'];
|
|
600
|
-
|
|
601
|
-
await wrapper.setData({ editedItem: items[0] });
|
|
602
|
-
const inputField = wrapper.find('[data-testid^="item-edit"]');
|
|
603
|
-
|
|
604
|
-
await inputField.setValue(newValue);
|
|
605
|
-
|
|
606
|
-
// press enter
|
|
607
|
-
await inputField.trigger('keydown.enter');
|
|
608
|
-
await wrapper.vm.$nextTick();
|
|
609
|
-
|
|
610
|
-
const itemsResult = (wrapper.emitted('change') || [])[0][0];
|
|
611
|
-
|
|
612
|
-
expect(JSON.stringify(itemsResult)).toBe(JSON.stringify(result));
|
|
613
|
-
});
|
|
614
|
-
|
|
615
|
-
it('should not consider empty strings in the middle 1', async() => {
|
|
616
|
-
const newValue = 'test1; ;new;value';
|
|
617
|
-
const result = ['test1', 'new', 'value', 'test2'];
|
|
618
|
-
|
|
619
|
-
await wrapper.setData({ editedItem: items[0] });
|
|
620
|
-
const inputField = wrapper.find('[data-testid^="item-edit"]');
|
|
621
|
-
|
|
622
|
-
await inputField.setValue(newValue);
|
|
623
|
-
|
|
624
|
-
// press enter
|
|
625
|
-
await inputField.trigger('keydown.enter');
|
|
626
|
-
await wrapper.vm.$nextTick();
|
|
627
|
-
|
|
628
|
-
const itemsResult = (wrapper.emitted('change') || [])[0][0];
|
|
629
|
-
|
|
630
|
-
expect(JSON.stringify(itemsResult)).toBe(JSON.stringify(result));
|
|
631
|
-
});
|
|
632
|
-
|
|
633
|
-
it('should not consider empty strings in the middle 2', async() => {
|
|
634
|
-
const newValue = 'test1;;new;value';
|
|
635
|
-
const result = ['test1', 'new', 'value', 'test2'];
|
|
636
|
-
|
|
637
|
-
await wrapper.setData({ editedItem: items[0] });
|
|
638
|
-
const inputField = wrapper.find('[data-testid^="item-edit"]');
|
|
639
|
-
|
|
640
|
-
await inputField.setValue(newValue);
|
|
641
|
-
|
|
642
|
-
// press enter
|
|
643
|
-
await inputField.trigger('keydown.enter');
|
|
644
|
-
await wrapper.vm.$nextTick();
|
|
645
|
-
|
|
646
|
-
const itemsResult = (wrapper.emitted('change') || [])[0][0];
|
|
647
|
-
|
|
648
|
-
expect(JSON.stringify(itemsResult)).toBe(JSON.stringify(result));
|
|
649
|
-
});
|
|
650
|
-
|
|
651
|
-
it('should not consider empty strings at the end', async() => {
|
|
652
|
-
const newValue = 'test1;new;value;';
|
|
653
|
-
const result = ['test1', 'new', 'value', 'test2'];
|
|
654
|
-
|
|
655
|
-
await wrapper.setData({ editedItem: items[0] });
|
|
656
|
-
const inputField = wrapper.find('[data-testid^="item-edit"]');
|
|
657
|
-
|
|
658
|
-
await inputField.setValue(newValue);
|
|
659
|
-
|
|
660
|
-
// press enter
|
|
661
|
-
await inputField.trigger('keydown.enter');
|
|
662
|
-
await wrapper.vm.$nextTick();
|
|
663
|
-
|
|
664
|
-
const itemsResult = (wrapper.emitted('change') || [])[0][0];
|
|
665
|
-
|
|
666
|
-
expect(JSON.stringify(itemsResult)).toBe(JSON.stringify(result));
|
|
667
|
-
});
|
|
668
|
-
});
|
|
669
|
-
});
|
|
670
|
-
|
|
671
401
|
describe('errors handling', () => {
|
|
672
402
|
it('show duplicate warning icon when errorMessages is defined', async() => {
|
|
673
403
|
const items = ['test'];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import Vue, { PropType
|
|
2
|
+
import Vue, { PropType } from 'vue';
|
|
3
3
|
|
|
4
4
|
import LabeledInput from '@components/Form/LabeledInput/LabeledInput.vue';
|
|
5
5
|
import { findStringIndex, hasDuplicatedStrings } from '@shell/utils/array';
|
|
@@ -29,7 +29,7 @@ const CLASS = {
|
|
|
29
29
|
/**
|
|
30
30
|
* Manage a list of strings
|
|
31
31
|
*/
|
|
32
|
-
export default
|
|
32
|
+
export default Vue.extend({
|
|
33
33
|
|
|
34
34
|
name: 'StringList',
|
|
35
35
|
components: { LabeledInput },
|
|
@@ -82,19 +82,12 @@ export default defineComponent({
|
|
|
82
82
|
return {} as ErrorMessages;
|
|
83
83
|
},
|
|
84
84
|
},
|
|
85
|
-
/**
|
|
86
|
-
* Enables bulk addition and defines the delimiter to split the input string.
|
|
87
|
-
*/
|
|
88
|
-
bulkAdditionDelimiter: {
|
|
89
|
-
type: RegExp,
|
|
90
|
-
default: null,
|
|
91
|
-
}
|
|
92
85
|
},
|
|
93
86
|
data() {
|
|
94
87
|
return {
|
|
95
|
-
value:
|
|
88
|
+
value: null as string | null,
|
|
96
89
|
selected: null as string | null,
|
|
97
|
-
editedItem:
|
|
90
|
+
editedItem: null as string | null,
|
|
98
91
|
isCreateItem: false,
|
|
99
92
|
errors: { duplicate: false } as Record<Error, boolean>
|
|
100
93
|
};
|
|
@@ -132,9 +125,13 @@ export default defineComponent({
|
|
|
132
125
|
},
|
|
133
126
|
|
|
134
127
|
methods: {
|
|
135
|
-
onChange(value: string
|
|
128
|
+
onChange(value: string) {
|
|
136
129
|
this.value = value;
|
|
137
|
-
|
|
130
|
+
|
|
131
|
+
const items = [
|
|
132
|
+
...this.items,
|
|
133
|
+
this.value
|
|
134
|
+
];
|
|
138
135
|
|
|
139
136
|
this.toggleError(
|
|
140
137
|
'duplicate',
|
|
@@ -281,7 +278,7 @@ export default defineComponent({
|
|
|
281
278
|
this.isCreateItem = true;
|
|
282
279
|
this.setFocus(INPUT.create);
|
|
283
280
|
} else {
|
|
284
|
-
this.value =
|
|
281
|
+
this.value = null;
|
|
285
282
|
this.toggleError('duplicate', false);
|
|
286
283
|
this.onSelectLeave();
|
|
287
284
|
|
|
@@ -303,11 +300,11 @@ export default defineComponent({
|
|
|
303
300
|
this.editedItem = item || '';
|
|
304
301
|
this.setFocus(INPUT.edit);
|
|
305
302
|
} else {
|
|
306
|
-
this.value =
|
|
303
|
+
this.value = null;
|
|
307
304
|
this.toggleError('duplicate', false);
|
|
308
305
|
this.onSelectLeave();
|
|
309
306
|
|
|
310
|
-
this.editedItem =
|
|
307
|
+
this.editedItem = null;
|
|
311
308
|
}
|
|
312
309
|
},
|
|
313
310
|
|
|
@@ -324,7 +321,10 @@ export default defineComponent({
|
|
|
324
321
|
const value = this.value?.trim();
|
|
325
322
|
|
|
326
323
|
if (value) {
|
|
327
|
-
const items =
|
|
324
|
+
const items = [
|
|
325
|
+
...this.items,
|
|
326
|
+
value,
|
|
327
|
+
];
|
|
328
328
|
|
|
329
329
|
if (!hasDuplicatedStrings(items, this.caseSensitive)) {
|
|
330
330
|
this.updateItems(items);
|
|
@@ -343,8 +343,12 @@ export default defineComponent({
|
|
|
343
343
|
const value = this.value?.trim();
|
|
344
344
|
|
|
345
345
|
if (value) {
|
|
346
|
-
const
|
|
347
|
-
const
|
|
346
|
+
const items = [...this.items];
|
|
347
|
+
const index = findStringIndex(items, item, false);
|
|
348
|
+
|
|
349
|
+
if (index !== -1) {
|
|
350
|
+
items[index] = value;
|
|
351
|
+
}
|
|
348
352
|
|
|
349
353
|
if (!hasDuplicatedStrings(items, this.caseSensitive)) {
|
|
350
354
|
this.updateItems(items);
|
|
@@ -356,49 +360,6 @@ export default defineComponent({
|
|
|
356
360
|
}
|
|
357
361
|
},
|
|
358
362
|
|
|
359
|
-
/**
|
|
360
|
-
* Add a new or update an exiting item in the items list.
|
|
361
|
-
*
|
|
362
|
-
* @param items The current items list.
|
|
363
|
-
* @param value The new value to be added.
|
|
364
|
-
* @param index The list index of the item to be updated (optional).
|
|
365
|
-
* @returns Updated items list.
|
|
366
|
-
*/
|
|
367
|
-
addValueToItems(items: string[], value: string, index?: number): string[] {
|
|
368
|
-
const updatedItems = [...items];
|
|
369
|
-
|
|
370
|
-
// Add new item
|
|
371
|
-
if (index === undefined) {
|
|
372
|
-
if (this.bulkAdditionDelimiter && value.search(this.bulkAdditionDelimiter) >= 0) {
|
|
373
|
-
updatedItems.push(...this.splitBulkValue(value));
|
|
374
|
-
} else {
|
|
375
|
-
updatedItems.push(value);
|
|
376
|
-
}
|
|
377
|
-
} else { // Update existing item
|
|
378
|
-
if (this.bulkAdditionDelimiter && value.search(this.bulkAdditionDelimiter) >= 0) {
|
|
379
|
-
updatedItems.splice(index, 1, ...this.splitBulkValue(value));
|
|
380
|
-
} else {
|
|
381
|
-
updatedItems[index] = value;
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
return updatedItems;
|
|
386
|
-
},
|
|
387
|
-
|
|
388
|
-
/**
|
|
389
|
-
* Split the value by the defined delimiter and remove empty strings.
|
|
390
|
-
*
|
|
391
|
-
* @param value The value to be split.
|
|
392
|
-
* @returns Array containing split values.
|
|
393
|
-
*/
|
|
394
|
-
splitBulkValue(value: string): string[] {
|
|
395
|
-
return value
|
|
396
|
-
.split(this.bulkAdditionDelimiter)
|
|
397
|
-
.filter((item) => {
|
|
398
|
-
return item.trim().length > 0;
|
|
399
|
-
});
|
|
400
|
-
},
|
|
401
|
-
|
|
402
363
|
/**
|
|
403
364
|
* Remove an item from items list
|
|
404
365
|
*/
|
|
@@ -432,7 +393,7 @@ export default defineComponent({
|
|
|
432
393
|
@dblclick="onClickEmptyBody()"
|
|
433
394
|
>
|
|
434
395
|
<div
|
|
435
|
-
v-for="
|
|
396
|
+
v-for="item in items"
|
|
436
397
|
:key="item"
|
|
437
398
|
:ref="item"
|
|
438
399
|
:class="{
|
|
@@ -460,7 +421,7 @@ export default defineComponent({
|
|
|
460
421
|
:data-testid="`item-edit-${item}`"
|
|
461
422
|
class="edit-input static"
|
|
462
423
|
:value="value != null ? value : item"
|
|
463
|
-
@input="onChange($event
|
|
424
|
+
@input="onChange($event)"
|
|
464
425
|
@blur.prevent="updateItem(item)"
|
|
465
426
|
@keydown.native.enter="updateItem(item, !errors.duplicate)"
|
|
466
427
|
/>
|
|
@@ -502,7 +463,7 @@ export default defineComponent({
|
|
|
502
463
|
<button
|
|
503
464
|
data-testid="button-add"
|
|
504
465
|
class="btn btn-sm role-tertiary add-button"
|
|
505
|
-
:disabled="
|
|
466
|
+
:disabled="isCreateItem || editedItem"
|
|
506
467
|
@click.prevent="onClickPlusButton"
|
|
507
468
|
>
|
|
508
469
|
<span class="icon icon-plus icon-sm" />
|
package/scripts/publish-shell.sh
CHANGED
|
@@ -57,6 +57,7 @@ function publish() {
|
|
|
57
57
|
# For now, copy the rancher components into the shell and ship them with it
|
|
58
58
|
if [ "$NAME" == "Shell" ]; then
|
|
59
59
|
echo "Adding Rancher Components"
|
|
60
|
+
rm -rf ./rancher-components
|
|
60
61
|
cp -R ${BASE_DIR}/pkg/rancher-components/src/components ./rancher-components/
|
|
61
62
|
fi
|
|
62
63
|
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { shallowMount } from '@vue/test-utils';
|
|
2
|
-
import { Accordion } from './index';
|
|
3
|
-
|
|
4
|
-
describe('component: Accordion', () => {
|
|
5
|
-
it('is closed initially by default', () => {
|
|
6
|
-
const title = 'Test Title';
|
|
7
|
-
|
|
8
|
-
const wrapper = shallowMount(Accordion, { propsData: { title } });
|
|
9
|
-
|
|
10
|
-
expect(wrapper.find('[data-testid="accordion-body"]').isVisible()).toBe(false);
|
|
11
|
-
expect(wrapper.find('[data-testid="accordion-header"]').text()).toBe(title);
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
it('is opened initially when openInitially prop is true', () => {
|
|
15
|
-
const wrapper = shallowMount(Accordion, { propsData: { openInitially: true } });
|
|
16
|
-
|
|
17
|
-
expect(wrapper.find('[data-testid="accordion-body"]').isVisible()).toBe(true);
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it('when closed, opens when the header is clicked', async() => {
|
|
21
|
-
const wrapper = shallowMount(Accordion, { });
|
|
22
|
-
|
|
23
|
-
await wrapper.find('[data-testid="accordion-header"]').trigger('click');
|
|
24
|
-
expect(wrapper.find('[data-testid="accordion-body"]').isVisible()).toBe(true);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it('when open, closes when the header is clicked', async() => {
|
|
28
|
-
const wrapper = shallowMount(Accordion, { propsData: { openInitially: true } });
|
|
29
|
-
|
|
30
|
-
await wrapper.find('[data-testid="accordion-header"]').trigger('click');
|
|
31
|
-
expect(wrapper.find('[data-testid="accordion-body"]').isVisible()).toBe(false);
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it('displays a chevron when closed', async() => {
|
|
35
|
-
const wrapper = shallowMount(Accordion, { propsData: { } });
|
|
36
|
-
|
|
37
|
-
expect(wrapper.find('[data-testid="accordion-header"] .icon-chevron-up').exists()).toBe(true);
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it('displays an inverted chevron when open', async() => {
|
|
41
|
-
const wrapper = shallowMount(Accordion, { propsData: { openInitially: true } });
|
|
42
|
-
|
|
43
|
-
expect(wrapper.find('[data-testid="accordion-header"] .icon-chevron-down').exists()).toBe(true);
|
|
44
|
-
});
|
|
45
|
-
});
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import { defineComponent } from 'vue';
|
|
3
|
-
import { mapGetters } from 'vuex';
|
|
4
|
-
|
|
5
|
-
export default defineComponent({
|
|
6
|
-
props: {
|
|
7
|
-
title: {
|
|
8
|
-
type: String,
|
|
9
|
-
default: ''
|
|
10
|
-
},
|
|
11
|
-
|
|
12
|
-
titleKey: {
|
|
13
|
-
type: String,
|
|
14
|
-
default: null
|
|
15
|
-
},
|
|
16
|
-
|
|
17
|
-
openInitially: {
|
|
18
|
-
type: Boolean,
|
|
19
|
-
default: false
|
|
20
|
-
}
|
|
21
|
-
},
|
|
22
|
-
|
|
23
|
-
data() {
|
|
24
|
-
return { isOpen: this.openInitially };
|
|
25
|
-
},
|
|
26
|
-
|
|
27
|
-
computed: { ...mapGetters({ t: 'i18n/t' }) },
|
|
28
|
-
|
|
29
|
-
methods: {
|
|
30
|
-
toggle() {
|
|
31
|
-
this.isOpen = !this.isOpen;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
</script>
|
|
36
|
-
|
|
37
|
-
<template>
|
|
38
|
-
<div class="accordion-container">
|
|
39
|
-
<div
|
|
40
|
-
class="accordion-header"
|
|
41
|
-
data-testid="accordion-header"
|
|
42
|
-
@click="toggle"
|
|
43
|
-
>
|
|
44
|
-
<i
|
|
45
|
-
class="icon text-primary"
|
|
46
|
-
:class="{'icon-chevron-down':isOpen, 'icon-chevron-up':!isOpen}"
|
|
47
|
-
data-testid="accordion-chevron"
|
|
48
|
-
/>
|
|
49
|
-
<slot name="header">
|
|
50
|
-
<h4
|
|
51
|
-
data-testid="accordion-title-slot-content"
|
|
52
|
-
class="mb-0"
|
|
53
|
-
>
|
|
54
|
-
{{ titleKey ? t(titleKey) : title }}
|
|
55
|
-
</h4>
|
|
56
|
-
</slot>
|
|
57
|
-
</div>
|
|
58
|
-
<div
|
|
59
|
-
v-show="isOpen"
|
|
60
|
-
class="accordion-body"
|
|
61
|
-
data-testid="accordion-body"
|
|
62
|
-
>
|
|
63
|
-
<slot />
|
|
64
|
-
</div>
|
|
65
|
-
</div>
|
|
66
|
-
</template>
|
|
67
|
-
|
|
68
|
-
<style lang="scss" scoped>
|
|
69
|
-
.accordion-container {
|
|
70
|
-
border: 1px solid var(--border)
|
|
71
|
-
}
|
|
72
|
-
.accordion-header {
|
|
73
|
-
padding: 5px;
|
|
74
|
-
display: flex;
|
|
75
|
-
align-items: center;
|
|
76
|
-
&>*{
|
|
77
|
-
padding: 5px 0px 5px 0px;
|
|
78
|
-
}
|
|
79
|
-
I {
|
|
80
|
-
margin: 0px 10px 0px 10px;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
.accordion-body {
|
|
84
|
-
padding: 10px;
|
|
85
|
-
}
|
|
86
|
-
</style>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default as Accordion } from './Accordion.vue';
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { shallowMount } from '@vue/test-utils';
|
|
2
|
-
import { BadgeState } from './index';
|
|
3
|
-
|
|
4
|
-
describe('BadgeState.vue', () => {
|
|
5
|
-
it('renders props.msg when passed', () => {
|
|
6
|
-
const label = 'Hello, World!';
|
|
7
|
-
|
|
8
|
-
const wrapper = shallowMount(BadgeState, { propsData: { label } });
|
|
9
|
-
|
|
10
|
-
expect(wrapper.find('span').text()).toMatch(label);
|
|
11
|
-
});
|
|
12
|
-
});
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { shallowMount } from '@vue/test-utils';
|
|
2
|
-
import { Accordion } from './index';
|
|
3
|
-
|
|
4
|
-
describe('component: Accordion', () => {
|
|
5
|
-
it('is closed initially by default', () => {
|
|
6
|
-
const title = 'Test Title';
|
|
7
|
-
|
|
8
|
-
const wrapper = shallowMount(Accordion, { propsData: { title } });
|
|
9
|
-
|
|
10
|
-
expect(wrapper.find('[data-testid="accordion-body"]').isVisible()).toBe(false);
|
|
11
|
-
expect(wrapper.find('[data-testid="accordion-header"]').text()).toBe(title);
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
it('is opened initially when openInitially prop is true', () => {
|
|
15
|
-
const wrapper = shallowMount(Accordion, { propsData: { openInitially: true } });
|
|
16
|
-
|
|
17
|
-
expect(wrapper.find('[data-testid="accordion-body"]').isVisible()).toBe(true);
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it('when closed, opens when the header is clicked', async() => {
|
|
21
|
-
const wrapper = shallowMount(Accordion, { });
|
|
22
|
-
|
|
23
|
-
await wrapper.find('[data-testid="accordion-header"]').trigger('click');
|
|
24
|
-
expect(wrapper.find('[data-testid="accordion-body"]').isVisible()).toBe(true);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it('when open, closes when the header is clicked', async() => {
|
|
28
|
-
const wrapper = shallowMount(Accordion, { propsData: { openInitially: true } });
|
|
29
|
-
|
|
30
|
-
await wrapper.find('[data-testid="accordion-header"]').trigger('click');
|
|
31
|
-
expect(wrapper.find('[data-testid="accordion-body"]').isVisible()).toBe(false);
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it('displays a chevron when closed', async() => {
|
|
35
|
-
const wrapper = shallowMount(Accordion, { propsData: { } });
|
|
36
|
-
|
|
37
|
-
expect(wrapper.find('[data-testid="accordion-header"] .icon-chevron-up').exists()).toBe(true);
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it('displays an inverted chevron when open', async() => {
|
|
41
|
-
const wrapper = shallowMount(Accordion, { propsData: { openInitially: true } });
|
|
42
|
-
|
|
43
|
-
expect(wrapper.find('[data-testid="accordion-header"] .icon-chevron-down').exists()).toBe(true);
|
|
44
|
-
});
|
|
45
|
-
});
|