@rancher/shell 3.0.0-rc.1 → 3.0.0-rc.2
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/assets/styles/base/_variables.scss +1 -0
- package/assets/styles/global/_layout.scss +3 -3
- package/assets/styles/global/_select.scss +1 -1
- package/assets/styles/global/_tooltip.scss +37 -71
- package/components/ActionDropdown.vue +9 -13
- package/components/ActionMenu.vue +1 -1
- package/components/ButtonDropdown.vue +9 -8
- package/components/CruResource.vue +4 -2
- package/components/InputOrDisplay.vue +21 -33
- package/components/LocaleSelector.vue +1 -1
- package/components/Questions/__tests__/Boolean.test.ts +1 -2
- package/components/Questions/__tests__/Float.test.ts +1 -2
- package/components/Questions/__tests__/Int.test.ts +1 -2
- package/components/Questions/__tests__/String.test.ts +1 -2
- package/components/Questions/__tests__/Yaml.test.ts +1 -1
- package/components/Questions/__tests__/utils/questions-defaults.ts +2 -2
- package/components/SideNav.vue +3 -3
- package/components/__tests__/CodeMirror.test.ts +91 -94
- package/components/__tests__/ConsumptionGauge.test.ts +2 -2
- package/components/__tests__/NamespaceFilter.test.ts +10 -7
- package/components/auth/AllowedPrincipals.vue +2 -2
- package/components/auth/RoleDetailEdit.vue +13 -17
- package/components/auth/SelectPrincipal.vue +1 -1
- package/components/fleet/FleetStatus.vue +13 -14
- package/components/form/ArrayList.vue +1 -1
- package/components/form/ArrayListGrouped.vue +18 -5
- package/components/form/LabeledSelect.vue +16 -11
- package/components/form/Select.vue +17 -1
- package/components/form/__tests__/Command.test.ts +6 -5
- package/components/form/__tests__/Taints.test.ts +9 -9
- package/components/formatter/AppSummaryGraph.vue +1 -1
- package/components/formatter/FleetSummaryGraph.vue +1 -1
- package/components/formatter/MachineSummaryGraph.vue +1 -1
- package/components/formatter/Scale.vue +1 -1
- package/components/formatter/Weight.vue +1 -1
- package/components/nav/Header.vue +31 -14
- package/components/nav/NamespaceFilter.vue +1 -1
- package/components/nav/TopLevelMenu.vue +7 -6
- package/components/nav/WindowManager/ContainerLogs.vue +1 -1
- package/components/nav/WindowManager/ContainerShell.vue +7 -2
- package/components/nav/WindowManager/__tests__/ContainerLogs.test.ts +195 -192
- package/components/nav/WindowManager/__tests__/ContainerShell.test.ts +23 -19
- package/core/plugin-routes.ts +42 -29
- package/core/plugins-loader.js +2 -0
- package/detail/__tests__/autoscaling.horizontalpodautoscaler.test.ts +16 -8
- package/detail/helm.cattle.io.projecthelmchart.vue +26 -27
- package/edit/__tests__/namespace.test.ts +7 -9
- package/edit/__tests__/service.test.ts +14 -2
- package/edit/auth/__tests__/azuread.test.ts +10 -11
- package/edit/auth/azuread.vue +1 -1
- package/edit/fleet.cattle.io.clustergroup.vue +3 -3
- package/edit/management.cattle.io.fleetworkspace.vue +3 -3
- package/edit/management.cattle.io.node.vue +3 -2
- package/edit/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +3 -2
- package/edit/namespace.vue +3 -1
- package/edit/networking.k8s.io.ingress/index.vue +3 -2
- package/edit/networking.k8s.io.networkpolicy/index.vue +2 -2
- package/edit/node.vue +3 -3
- package/edit/persistentvolume/__tests__/persistentvolume.test.ts +9 -4
- package/edit/persistentvolume/index.vue +3 -3
- package/edit/persistentvolumeclaim.vue +3 -3
- package/edit/policy.poddisruptionbudget.vue +3 -3
- package/edit/provisioning.cattle.io.cluster/__tests__/Basics.test.ts +5 -6
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +13 -6
- package/edit/provisioning.cattle.io.cluster/rke2.vue +7 -1
- package/edit/provisioning.cattle.io.cluster/tabs/registries/__tests__/RegistryConfigs.test.ts +6 -7
- package/edit/service.vue +2 -2
- package/edit/serviceaccount.vue +3 -3
- package/edit/storage.k8s.io.storageclass/index.vue +3 -3
- package/edit/workload/Job.vue +2 -2
- package/edit/workload/__tests__/Job.test.ts +5 -5
- package/edit/workload/index.vue +2 -2
- package/edit/workload/storage/Mount.vue +7 -4
- package/edit/workload/storage/__tests__/Mount.test.ts +6 -2
- package/edit/workload/storage/index.vue +10 -23
- package/initialize/entry-helpers.js +0 -5
- package/mixins/page-actions.js +1 -1
- package/package.json +1 -1
- package/pages/c/_cluster/istio/index.vue +2 -2
- package/pages/c/_cluster/longhorn/__tests__/longhorn.index.test.ts +3 -2
- package/pages/c/_cluster/monitoring/index.vue +1 -1
- package/pages/c/_cluster/uiplugins/__tests__/AddExtensionRepos.test.ts +7 -29
- package/rancher-components/LabeledTooltip/LabeledTooltip.vue +1 -0
- package/vue.config.js +409 -391
- package/plugins/clean-html-directive.js +0 -10
- package/plugins/clean-tooltip-directive.js +0 -9
- package/plugins/int-number.js +0 -9
- package/plugins/positive-int-number.js +0 -9
- package/plugins/trim-whitespace.js +0 -10
|
@@ -1,96 +1,93 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
//
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
describe.skip('(Vue3 Skip) it must have one test', () => {
|
|
93
|
-
it('will pass', () => {
|
|
94
|
-
expect(true).toBe(true);
|
|
1
|
+
import { nextTick } from 'vue';
|
|
2
|
+
import { shallowMount, Wrapper } from '@vue/test-utils';
|
|
3
|
+
import CodeMirror from '@shell/components/CodeMirror.vue';
|
|
4
|
+
import { _EDIT, _YAML } from '@shell/config/query-params';
|
|
5
|
+
|
|
6
|
+
// eslint-disable-next-line jest/no-disabled-tests
|
|
7
|
+
describe('component: CodeMirror.vue', () => {
|
|
8
|
+
let wrapper: Wrapper<InstanceType<typeof CodeMirror>>;
|
|
9
|
+
|
|
10
|
+
const options = {
|
|
11
|
+
readOnly: false,
|
|
12
|
+
gutters: [
|
|
13
|
+
'CodeMirror-lint-markers',
|
|
14
|
+
'CodeMirror-foldgutter'
|
|
15
|
+
],
|
|
16
|
+
mode: 'yaml',
|
|
17
|
+
lint: true,
|
|
18
|
+
lineNumbers: true,
|
|
19
|
+
styleActiveLine: true,
|
|
20
|
+
tabSize: 2,
|
|
21
|
+
indentWithTabs: false,
|
|
22
|
+
cursorBlinkRate: 530,
|
|
23
|
+
extraKeys: { 'Ctrl-Space': 'autocomplete' }
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const mountOptions = {
|
|
27
|
+
propsData: {
|
|
28
|
+
value: '',
|
|
29
|
+
mode: _EDIT,
|
|
30
|
+
options,
|
|
31
|
+
asTextArea: false,
|
|
32
|
+
showKeyMapBox: true,
|
|
33
|
+
},
|
|
34
|
+
global: {
|
|
35
|
+
mocks: {
|
|
36
|
+
$store: {
|
|
37
|
+
getters: {
|
|
38
|
+
currentStore: () => 'current_store',
|
|
39
|
+
'current_store/schemaFor': jest.fn(),
|
|
40
|
+
'current_store/all': jest.fn(),
|
|
41
|
+
'i18n/t': () => 'Vim',
|
|
42
|
+
'prefs/get': () => 'Vim',
|
|
43
|
+
'prefs/theme': jest.fn(),
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
$route: { query: { AS: _YAML } },
|
|
47
|
+
$router: { applyQuery: jest.fn() },
|
|
48
|
+
},
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// eslint-disable-next-line jest/no-disabled-tests
|
|
54
|
+
describe('keyMap info', () => {
|
|
55
|
+
(window as any).__codeMirrorLoader = () => new Promise((resolve) => {
|
|
56
|
+
resolve(true);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
wrapper = shallowMount(
|
|
60
|
+
CodeMirror,
|
|
61
|
+
mountOptions,
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
it(`should show keyMap preference`, async() => {
|
|
65
|
+
await nextTick();
|
|
66
|
+
|
|
67
|
+
const keyMapBox = wrapper.find('[data-testid="code-mirror-keymap"] .keymap-indicator');
|
|
68
|
+
|
|
69
|
+
const closeIcon = wrapper.find('[data-testid="code-mirror-keymap"] .icon-close');
|
|
70
|
+
|
|
71
|
+
expect(keyMapBox).toBeDefined();
|
|
72
|
+
expect(closeIcon).toBeDefined();
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it(`should remove keyMap box`, async() => {
|
|
76
|
+
await nextTick();
|
|
77
|
+
|
|
78
|
+
let keyMapBox = wrapper.find('[data-testid="code-mirror-keymap"]');
|
|
79
|
+
|
|
80
|
+
keyMapBox.trigger('mouseenter');
|
|
81
|
+
await nextTick();
|
|
82
|
+
|
|
83
|
+
const closeIcon = keyMapBox.find('.icon-close');
|
|
84
|
+
|
|
85
|
+
closeIcon.element.click();
|
|
86
|
+
await nextTick();
|
|
87
|
+
|
|
88
|
+
keyMapBox = wrapper.find('[data-testid="code-mirror-keymap"]');
|
|
89
|
+
|
|
90
|
+
expect(keyMapBox.exists()).toBe(false);
|
|
91
|
+
});
|
|
95
92
|
});
|
|
96
93
|
});
|
|
@@ -3,7 +3,7 @@ import ConsumptionGauge from '@shell/components/ConsumptionGauge.vue';
|
|
|
3
3
|
import PercentageBar from '@shell/components/PercentageBar.vue';
|
|
4
4
|
|
|
5
5
|
describe('component: ConsumptionGauge', () => {
|
|
6
|
-
it
|
|
6
|
+
it('should render component with the correct data applied', () => {
|
|
7
7
|
const colorStops = {
|
|
8
8
|
0: '--success', 30: '--warning', 70: '--error'
|
|
9
9
|
};
|
|
@@ -36,7 +36,7 @@ describe('component: ConsumptionGauge', () => {
|
|
|
36
36
|
|
|
37
37
|
// checking PercentageBar component render
|
|
38
38
|
expect(percentageBar.exists()).toBe(true);
|
|
39
|
-
expect(
|
|
39
|
+
expect(percentageBar.props().modelValue).toBe(20);
|
|
40
40
|
expect(percentageBar.props().colorStops).toStrictEqual(colorStops);
|
|
41
41
|
});
|
|
42
42
|
|
|
@@ -17,8 +17,7 @@ describe('component: NamespaceFilter', () => {
|
|
|
17
17
|
expect(filter).toBeDefined();
|
|
18
18
|
});
|
|
19
19
|
|
|
20
|
-
it
|
|
21
|
-
const text = 'none';
|
|
20
|
+
it('should display no namespace selection', () => {
|
|
22
21
|
const wrapper = mount(NamespaceFilter, {
|
|
23
22
|
computed: {
|
|
24
23
|
filtered: () => [],
|
|
@@ -27,17 +26,17 @@ describe('component: NamespaceFilter', () => {
|
|
|
27
26
|
},
|
|
28
27
|
global: {
|
|
29
28
|
mocks: {
|
|
30
|
-
$store: { getters: {
|
|
29
|
+
$store: { getters: { namespaceFilterMode: () => undefined } },
|
|
31
30
|
$fetchState: { pending: false }
|
|
32
31
|
},
|
|
33
32
|
}
|
|
34
33
|
});
|
|
35
34
|
const element = wrapper.find(`[data-testid="namespaces-values-none"]`).element.textContent;
|
|
36
35
|
|
|
37
|
-
expect(element).toContain(
|
|
36
|
+
expect(element).toContain('nav.ns.all');
|
|
38
37
|
});
|
|
39
38
|
|
|
40
|
-
it
|
|
39
|
+
it('should display the default namespace', () => {
|
|
41
40
|
const text = 'special namespace';
|
|
42
41
|
const wrapper = mount(NamespaceFilter, {
|
|
43
42
|
computed: {
|
|
@@ -47,6 +46,7 @@ describe('component: NamespaceFilter', () => {
|
|
|
47
46
|
label: text,
|
|
48
47
|
kind: 'special',
|
|
49
48
|
}]),
|
|
49
|
+
isSingleSpecial: () => true
|
|
50
50
|
},
|
|
51
51
|
global: { mocks: { $fetchState: { pending: false } } }
|
|
52
52
|
});
|
|
@@ -77,7 +77,7 @@ describe('component: NamespaceFilter', () => {
|
|
|
77
77
|
expect(element).toContain(text);
|
|
78
78
|
});
|
|
79
79
|
|
|
80
|
-
it
|
|
80
|
+
it('should display the selected namespace from user preferences if options are available', () => {
|
|
81
81
|
const text = 'my preference';
|
|
82
82
|
const key = 'local';
|
|
83
83
|
const preferences = {
|
|
@@ -97,6 +97,7 @@ describe('component: NamespaceFilter', () => {
|
|
|
97
97
|
}],
|
|
98
98
|
currentProduct: () => undefined,
|
|
99
99
|
key: () => key,
|
|
100
|
+
value: () => [{ label: text }]
|
|
100
101
|
},
|
|
101
102
|
global: {
|
|
102
103
|
mocks: {
|
|
@@ -194,7 +195,7 @@ describe('component: NamespaceFilter', () => {
|
|
|
194
195
|
expect(option).toContain(text);
|
|
195
196
|
});
|
|
196
197
|
|
|
197
|
-
it
|
|
198
|
+
it('should set the option as user preference', async() => {
|
|
198
199
|
const text = 'my option';
|
|
199
200
|
const key = 'my key';
|
|
200
201
|
const value = {
|
|
@@ -205,8 +206,10 @@ describe('component: NamespaceFilter', () => {
|
|
|
205
206
|
const action = jest.fn();
|
|
206
207
|
|
|
207
208
|
jest.spyOn(NamespaceFilter.computed.value, 'get').mockReturnValue([]);
|
|
209
|
+
|
|
208
210
|
const wrapper = mount(NamespaceFilter, {
|
|
209
211
|
computed: {
|
|
212
|
+
...NamespaceFilter.computed,
|
|
210
213
|
options: () => [],
|
|
211
214
|
currentProduct: () => undefined,
|
|
212
215
|
key: () => key,
|
|
@@ -4,7 +4,7 @@ import ArrayList from '@shell/components/form/ArrayList';
|
|
|
4
4
|
import Principal from '@shell/components/auth/Principal';
|
|
5
5
|
import SelectPrincipal from '@shell/components/auth/SelectPrincipal';
|
|
6
6
|
import { _EDIT } from '@shell/config/query-params';
|
|
7
|
-
import
|
|
7
|
+
import uniq from 'lodash/uniq';
|
|
8
8
|
|
|
9
9
|
export default {
|
|
10
10
|
components: {
|
|
@@ -56,7 +56,7 @@ export default {
|
|
|
56
56
|
|
|
57
57
|
methods: {
|
|
58
58
|
addPrincipal(id) {
|
|
59
|
-
|
|
59
|
+
this.authConfig.allowedPrincipalIds = uniq([...this.authConfig.allowedPrincipalIds, id]);
|
|
60
60
|
},
|
|
61
61
|
}
|
|
62
62
|
};
|
|
@@ -16,6 +16,7 @@ import SortableTable from '@shell/components/SortableTable';
|
|
|
16
16
|
import { _CLONE, _DETAIL } from '@shell/config/query-params';
|
|
17
17
|
import { SCOPED_RESOURCES, SCOPED_RESOURCE_GROUPS } from '@shell/config/roles';
|
|
18
18
|
import { Banner } from '@components/Banner';
|
|
19
|
+
import LabeledInput from '@components/Form/LabeledInput/LabeledInput.vue';
|
|
19
20
|
|
|
20
21
|
import { SUBTYPE_MAPPING, VERBS } from '@shell/models/management.cattle.io.roletemplate';
|
|
21
22
|
import Loading from '@shell/components/Loading';
|
|
@@ -63,7 +64,8 @@ export default {
|
|
|
63
64
|
SortableTable,
|
|
64
65
|
Loading,
|
|
65
66
|
Error,
|
|
66
|
-
Banner
|
|
67
|
+
Banner,
|
|
68
|
+
LabeledInput
|
|
67
69
|
},
|
|
68
70
|
|
|
69
71
|
mixins: [CreateEditView, FormValidation],
|
|
@@ -706,6 +708,7 @@ export default {
|
|
|
706
708
|
:options="verbOptions"
|
|
707
709
|
:multiple="true"
|
|
708
710
|
:mode="mode"
|
|
711
|
+
:compact="true"
|
|
709
712
|
:data-testid="`grant-resources-verbs${props.i}`"
|
|
710
713
|
@update:value="updateSelectValue(props.row.value, 'verbs', $event)"
|
|
711
714
|
/>
|
|
@@ -719,31 +722,32 @@ export default {
|
|
|
719
722
|
:searchable="true"
|
|
720
723
|
:taggable="true"
|
|
721
724
|
:mode="mode"
|
|
725
|
+
:compact="true"
|
|
722
726
|
:data-testid="`grant-resources-resources${props.i}`"
|
|
723
727
|
@update:value="setRule('resources', props.row.value, $event)"
|
|
724
728
|
@createdListItem="setRule('resources', props.row.value, $event)"
|
|
725
729
|
/>
|
|
726
730
|
</div>
|
|
727
731
|
<div :class="ruleClass">
|
|
728
|
-
<
|
|
732
|
+
<LabeledInput
|
|
729
733
|
:value="getRule('apiGroups', props.row.value)"
|
|
730
734
|
:disabled="isBuiltin"
|
|
731
735
|
:mode="mode"
|
|
732
736
|
:data-testid="`grant-resources-api-groups${props.i}`"
|
|
733
737
|
@input="setRule('apiGroups', props.row.value, $event.target.value)"
|
|
734
|
-
|
|
738
|
+
/>
|
|
735
739
|
</div>
|
|
736
740
|
<div
|
|
737
741
|
v-if="!isNamespaced"
|
|
738
742
|
:class="ruleClass"
|
|
739
743
|
>
|
|
740
|
-
<
|
|
744
|
+
<LabeledInput
|
|
741
745
|
:value="getRule('nonResourceURLs', props.row.value)"
|
|
742
746
|
:disabled="isBuiltin"
|
|
743
747
|
:mode="mode"
|
|
744
748
|
:data-testid="`grant-resources-non-resource-urls${props.i}`"
|
|
745
749
|
@input="setRule('nonResourceURLs', props.row.value, $event.target.value)"
|
|
746
|
-
|
|
750
|
+
/>
|
|
747
751
|
</div>
|
|
748
752
|
</div>
|
|
749
753
|
</template>
|
|
@@ -777,6 +781,7 @@ export default {
|
|
|
777
781
|
option-key="value"
|
|
778
782
|
option-label="label"
|
|
779
783
|
:mode="mode"
|
|
784
|
+
:compact="true"
|
|
780
785
|
@on-focus="selectFocused = props.i"
|
|
781
786
|
@on-blur="selectFocused = null"
|
|
782
787
|
/>
|
|
@@ -813,18 +818,9 @@ export default {
|
|
|
813
818
|
}
|
|
814
819
|
|
|
815
820
|
.columns {
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
}
|
|
820
|
-
|
|
821
|
-
&:first-of-type {
|
|
822
|
-
min-height: $input-height;
|
|
823
|
-
}
|
|
824
|
-
|
|
825
|
-
& > * {
|
|
826
|
-
height: 100%;
|
|
827
|
-
}
|
|
821
|
+
.col > .unlabeled-select:not(.taggable) {
|
|
822
|
+
// override the odd padding-top from shell/assets/styles/global/_select.scss
|
|
823
|
+
padding: $unlabaled-select-padding
|
|
828
824
|
}
|
|
829
825
|
}
|
|
830
826
|
}
|
|
@@ -188,7 +188,7 @@ export default {
|
|
|
188
188
|
:filterable="false"
|
|
189
189
|
class="select-principal"
|
|
190
190
|
:class="{'retain-selection': retainSelection}"
|
|
191
|
-
@
|
|
191
|
+
@update:value="add"
|
|
192
192
|
@search="onSearch"
|
|
193
193
|
@on-open="resetTooltipContent()"
|
|
194
194
|
@on-close="setTooltipContent()"
|
|
@@ -168,21 +168,20 @@ function toPercent(value, min, max) {
|
|
|
168
168
|
<div class="meta-title">
|
|
169
169
|
{{ meta.readyCount }} / {{ meta.total }} {{ title }} ready <i class="icon toggle icon-chevron-down" />
|
|
170
170
|
</div>
|
|
171
|
-
<template
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
class="list-unstyled dropdown"
|
|
177
|
-
@click.stop="showMenu(false)"
|
|
178
|
-
>
|
|
179
|
-
<li
|
|
180
|
-
v-for="(val, idx) in values"
|
|
181
|
-
:key="idx"
|
|
171
|
+
<template #popper>
|
|
172
|
+
<div class="resources-status-list">
|
|
173
|
+
<ul
|
|
174
|
+
class="list-unstyled dropdown"
|
|
175
|
+
@click.stop="showMenu(false)"
|
|
182
176
|
>
|
|
183
|
-
<
|
|
184
|
-
|
|
185
|
-
|
|
177
|
+
<li
|
|
178
|
+
v-for="(val, idx) in values"
|
|
179
|
+
:key="idx"
|
|
180
|
+
>
|
|
181
|
+
<span>{{ val.label }}</span><span class="list-count">{{ val.count }}</span>
|
|
182
|
+
</li>
|
|
183
|
+
</ul>
|
|
184
|
+
</div>
|
|
186
185
|
</template>
|
|
187
186
|
</v-dropdown>
|
|
188
187
|
</div>
|
|
@@ -37,8 +37,17 @@ export default {
|
|
|
37
37
|
type: String,
|
|
38
38
|
default: _EDIT,
|
|
39
39
|
},
|
|
40
|
+
|
|
41
|
+
value: {
|
|
42
|
+
type: Object,
|
|
43
|
+
default: () => {
|
|
44
|
+
return {};
|
|
45
|
+
},
|
|
46
|
+
},
|
|
40
47
|
},
|
|
41
48
|
|
|
49
|
+
emits: ['update:value', 'add', 'remove'],
|
|
50
|
+
|
|
42
51
|
computed: {
|
|
43
52
|
isView() {
|
|
44
53
|
return this.mode === _VIEW;
|
|
@@ -67,6 +76,7 @@ export default {
|
|
|
67
76
|
<template>
|
|
68
77
|
<ArrayList
|
|
69
78
|
class="array-list-grouped"
|
|
79
|
+
:value="value"
|
|
70
80
|
v-bind="$attrs"
|
|
71
81
|
:add-allowed="canAdd && !isView"
|
|
72
82
|
:mode="mode"
|
|
@@ -95,12 +105,15 @@ export default {
|
|
|
95
105
|
<!-- Pass down templates provided by the caller -->
|
|
96
106
|
<template
|
|
97
107
|
v-for="(_, slot) of $slots"
|
|
98
|
-
|
|
108
|
+
#[slot]="scope"
|
|
109
|
+
:key="slot"
|
|
99
110
|
>
|
|
100
|
-
<slot
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
111
|
+
<template v-if="typeof $slots[slot] === 'function'">
|
|
112
|
+
<slot
|
|
113
|
+
:name="slot"
|
|
114
|
+
v-bind="scope"
|
|
115
|
+
/>
|
|
116
|
+
</template>
|
|
104
117
|
</template>
|
|
105
118
|
</ArrayList>
|
|
106
119
|
</template>
|
|
@@ -13,6 +13,8 @@ import { LABEL_SELECT_NOT_OPTION_KINDS } from '@shell/types/components/labeledSe
|
|
|
13
13
|
export default {
|
|
14
14
|
name: 'LabeledSelect',
|
|
15
15
|
|
|
16
|
+
inheritAttrs: false,
|
|
17
|
+
|
|
16
18
|
components: { LabeledTooltip },
|
|
17
19
|
mixins: [
|
|
18
20
|
CompactInput,
|
|
@@ -247,17 +249,20 @@ export default {
|
|
|
247
249
|
<div
|
|
248
250
|
ref="select"
|
|
249
251
|
class="labeled-select"
|
|
250
|
-
:class="
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
252
|
+
:class="[
|
|
253
|
+
$attrs.class,
|
|
254
|
+
{
|
|
255
|
+
disabled: isView || disabled,
|
|
256
|
+
focused,
|
|
257
|
+
[mode]: true,
|
|
258
|
+
[status]: status,
|
|
259
|
+
taggable: $attrs.taggable,
|
|
260
|
+
taggable: $attrs.multiple,
|
|
261
|
+
hoverable: hoverTooltip,
|
|
262
|
+
'compact-input': isCompact,
|
|
263
|
+
'no-label': !hasLabel
|
|
264
|
+
}
|
|
265
|
+
]"
|
|
261
266
|
@click="focusSearch"
|
|
262
267
|
@focus="focusSearch"
|
|
263
268
|
>
|
|
@@ -81,6 +81,11 @@ export default {
|
|
|
81
81
|
type: Boolean,
|
|
82
82
|
default: true
|
|
83
83
|
},
|
|
84
|
+
|
|
85
|
+
compact: {
|
|
86
|
+
type: Boolean,
|
|
87
|
+
default: null
|
|
88
|
+
},
|
|
84
89
|
},
|
|
85
90
|
|
|
86
91
|
methods: {
|
|
@@ -206,6 +211,11 @@ export default {
|
|
|
206
211
|
},
|
|
207
212
|
canPaginate() {
|
|
208
213
|
return false;
|
|
214
|
+
},
|
|
215
|
+
deClassedAttrs() {
|
|
216
|
+
const { class: _, ...rest } = this.$attrs;
|
|
217
|
+
|
|
218
|
+
return rest;
|
|
209
219
|
}
|
|
210
220
|
}
|
|
211
221
|
};
|
|
@@ -222,13 +232,14 @@ export default {
|
|
|
222
232
|
[status]: status,
|
|
223
233
|
taggable: $attrs.taggable,
|
|
224
234
|
taggable: $attrs.multiple,
|
|
235
|
+
'compact-input': compact,
|
|
225
236
|
[$attrs.class]: $attrs.class
|
|
226
237
|
}"
|
|
227
238
|
@focus="focusSearch"
|
|
228
239
|
>
|
|
229
240
|
<v-select
|
|
230
241
|
ref="select-input"
|
|
231
|
-
v-bind="
|
|
242
|
+
v-bind="deClassedAttrs"
|
|
232
243
|
class="inline"
|
|
233
244
|
:class="{'select-input-view': mode === 'view'}"
|
|
234
245
|
:autoscroll="true"
|
|
@@ -325,5 +336,10 @@ export default {
|
|
|
325
336
|
}
|
|
326
337
|
|
|
327
338
|
@include input-status-color;
|
|
339
|
+
|
|
340
|
+
&.compact-input {
|
|
341
|
+
min-height: $unlabeled-input-height;
|
|
342
|
+
line-height: $input-line-height;
|
|
343
|
+
}
|
|
328
344
|
}
|
|
329
345
|
</style>
|
|
@@ -14,16 +14,17 @@ describe('component: Command', () => {
|
|
|
14
14
|
expect(inputWraps).toHaveLength(5);
|
|
15
15
|
});
|
|
16
16
|
|
|
17
|
-
it.
|
|
17
|
+
it.each([
|
|
18
18
|
'command',
|
|
19
19
|
'args',
|
|
20
20
|
'workingDir',
|
|
21
|
-
])('
|
|
21
|
+
])('should emit an update on %p input', (field) => {
|
|
22
22
|
const wrapper = mount(Command, { props: { mode: _EDIT } });
|
|
23
|
-
const
|
|
24
|
-
|
|
23
|
+
const inputComponent = wrapper.getComponent(`[data-testid="input-command-${ field }"]>*`);
|
|
24
|
+
|
|
25
|
+
const newValue = ['123'];
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
inputComponent.vm.$emit('update:value', newValue);
|
|
27
28
|
|
|
28
29
|
expect(wrapper.emitted('update:value')).toHaveLength(1);
|
|
29
30
|
});
|