@rancher/shell 0.3.28 → 0.3.29
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/.DS_Store +0 -0
- package/assets/translations/en-us.yaml +15 -1
- package/chart/monitoring/grafana/index.vue +2 -2
- package/components/AsyncButton.vue +9 -0
- package/components/SortableTable/THead.vue +7 -9
- package/components/SortableTable/index.vue +1 -2
- package/components/fleet/FleetStatus.vue +3 -3
- package/components/fleet/FleetSummary.vue +32 -27
- package/detail/provisioning.cattle.io.cluster.vue +2 -1
- package/edit/workload/index.vue +2 -1
- package/machine-config/__tests__/vmwarevsphere.test.ts +72 -0
- package/machine-config/vmwarevsphere.vue +68 -13
- package/package.json +2 -1
- package/rancher-components/BadgeState/BadgeState.vue +5 -1
- package/rancher-components/Banner/Banner.test.ts +51 -1
- package/rancher-components/Banner/Banner.vue +134 -53
- package/rancher-components/Card/Card.test.ts +37 -0
- package/rancher-components/Card/Card.vue +24 -7
- package/rancher-components/Form/Checkbox/Checkbox.test.ts +20 -29
- package/rancher-components/Form/Checkbox/Checkbox.vue +45 -20
- package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +2 -8
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +22 -10
- package/rancher-components/Form/Radio/RadioButton.test.ts +31 -0
- package/rancher-components/Form/Radio/RadioButton.vue +30 -13
- package/rancher-components/Form/Radio/RadioGroup.vue +26 -7
- package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +7 -6
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.test.ts +25 -38
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +23 -11
- package/rancher-components/LabeledTooltip/LabeledTooltip.vue +19 -5
- package/rancher-components/StringList/StringList.test.ts +453 -49
- package/rancher-components/StringList/StringList.vue +92 -58
- package/types/shell/index.d.ts +9 -9
- package/yarn-error.log +200 -0
package/.DS_Store
ADDED
|
Binary file
|
|
@@ -691,6 +691,15 @@ asyncButton:
|
|
|
691
691
|
successIcon: checkmark
|
|
692
692
|
waiting: ''
|
|
693
693
|
waitingIcon: refresh
|
|
694
|
+
manual-refresh:
|
|
695
|
+
action: ''
|
|
696
|
+
actionIcon: refresh
|
|
697
|
+
error: ''
|
|
698
|
+
errorIcon: error
|
|
699
|
+
success: ''
|
|
700
|
+
successIcon: checkmark
|
|
701
|
+
waiting: ''
|
|
702
|
+
waitingIcon: refresh
|
|
694
703
|
remove:
|
|
695
704
|
action: Remove
|
|
696
705
|
success: Removed
|
|
@@ -1525,6 +1534,9 @@ cluster:
|
|
|
1525
1534
|
host:
|
|
1526
1535
|
label: Host
|
|
1527
1536
|
note: Specific host to create VM on (leave blank for standalone ESXi or for cluster with DRS)
|
|
1537
|
+
gracefulShutdownTimeout:
|
|
1538
|
+
label: Graceful Shutdown Timeout
|
|
1539
|
+
note: The time in seconds to wait before forcing deleting VMs in the infrastructure. Zero means disable graceful shutdown.
|
|
1528
1540
|
instanceOptions:
|
|
1529
1541
|
label: Instance Options
|
|
1530
1542
|
description: Choose the size and OS of the virtual machine
|
|
@@ -5858,7 +5870,9 @@ workload:
|
|
|
5858
5870
|
exec: Command run inside the container exits with status 0
|
|
5859
5871
|
image: Container Image
|
|
5860
5872
|
imagePullPolicy: Pull Policy
|
|
5861
|
-
imagePullSecrets:
|
|
5873
|
+
imagePullSecrets:
|
|
5874
|
+
label: Pull Secrets
|
|
5875
|
+
tooltip: Must be of Type `kubernetes.io/dockercfg` or `kubernetes.io/dockerconfigjson`
|
|
5862
5876
|
init: Init Container
|
|
5863
5877
|
lifecycleHook:
|
|
5864
5878
|
postStart:
|
|
@@ -136,7 +136,7 @@ export default {
|
|
|
136
136
|
newValsOut = {
|
|
137
137
|
accessModes: null,
|
|
138
138
|
storageClassName: null,
|
|
139
|
-
size:
|
|
139
|
+
size: '10Gi',
|
|
140
140
|
subPath: null,
|
|
141
141
|
type: 'pvc',
|
|
142
142
|
annotations: null,
|
|
@@ -148,7 +148,7 @@ export default {
|
|
|
148
148
|
newValsOut = {
|
|
149
149
|
accessModes: null,
|
|
150
150
|
storageClassName: null,
|
|
151
|
-
size:
|
|
151
|
+
size: '10Gi',
|
|
152
152
|
subPath: null,
|
|
153
153
|
type: 'statefulset',
|
|
154
154
|
enabled: true,
|
|
@@ -273,6 +273,7 @@ export default Vue.extend<{ phase: string}, any, any, any>({
|
|
|
273
273
|
:data-testid="componentTestid + '-async-button'"
|
|
274
274
|
@click="clicked"
|
|
275
275
|
>
|
|
276
|
+
<span v-if="mode === 'manual-refresh'">{{ t('action.refresh') }}</span>
|
|
276
277
|
<i
|
|
277
278
|
v-if="displayIcon"
|
|
278
279
|
v-clean-tooltip="tooltip"
|
|
@@ -285,3 +286,11 @@ export default Vue.extend<{ phase: string}, any, any, any>({
|
|
|
285
286
|
/>
|
|
286
287
|
</button>
|
|
287
288
|
</template>
|
|
289
|
+
|
|
290
|
+
<style lang="scss" scoped>
|
|
291
|
+
// refresh mode has icon + text. We need to fix the positioning of the icon and sizing
|
|
292
|
+
.manual-refresh i {
|
|
293
|
+
margin: 0 0 0 8px !important;
|
|
294
|
+
font-size: 1rem !important;
|
|
295
|
+
}
|
|
296
|
+
</style>
|
|
@@ -162,15 +162,13 @@ export default {
|
|
|
162
162
|
const menu = document.querySelector('.table-options-container');
|
|
163
163
|
const elem = document.querySelector('.table-options-btn');
|
|
164
164
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
});
|
|
173
|
-
}
|
|
165
|
+
this.tableColsMenuPosition = fitOnScreen(menu, ev || elem, {
|
|
166
|
+
overlapX: true,
|
|
167
|
+
fudgeX: 326,
|
|
168
|
+
fudgeY: -22,
|
|
169
|
+
positionX: CENTER,
|
|
170
|
+
positionY: AUTO,
|
|
171
|
+
});
|
|
174
172
|
|
|
175
173
|
// toggle visibility
|
|
176
174
|
this.tableColsOptionsVisibility = !this.tableColsOptionsVisibility;
|
|
@@ -1026,9 +1026,8 @@ export default {
|
|
|
1026
1026
|
<slot name="header-right" />
|
|
1027
1027
|
<AsyncButton
|
|
1028
1028
|
v-if="isTooManyItemsToAutoUpdate"
|
|
1029
|
-
v-clean-tooltip="t('performance.manualRefresh.buttonTooltip')"
|
|
1030
1029
|
class="manual-refresh"
|
|
1031
|
-
mode="refresh"
|
|
1030
|
+
mode="manual-refresh"
|
|
1032
1031
|
:current-phase="currentPhase"
|
|
1033
1032
|
@click="debouncedRefreshTableData"
|
|
1034
1033
|
/>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { sortBy } from '@shell/utils/sort';
|
|
3
3
|
import { get } from '@shell/utils/object';
|
|
4
|
-
import { stateSort } from '@shell/plugins/dashboard-store/resource-class';
|
|
4
|
+
import { stateSort, STATES_ENUM } from '@shell/plugins/dashboard-store/resource-class';
|
|
5
5
|
|
|
6
6
|
export default {
|
|
7
7
|
|
|
@@ -50,8 +50,8 @@ export default {
|
|
|
50
50
|
computed: {
|
|
51
51
|
meta() {
|
|
52
52
|
return {
|
|
53
|
-
total: this.values.map((x) => x.value).reduce((a, b) => a + b),
|
|
54
|
-
readyCount: this.values.filter((x) => x.
|
|
53
|
+
total: this.values.map((x) => x.value).reduce((a, b) => a + b, 0),
|
|
54
|
+
readyCount: this.values.filter((x) => x.status === STATES_ENUM.SUCCESS || x.status === STATES_ENUM.READY).map((x) => x.value).reduce((a, b) => a + b, 0)
|
|
55
55
|
};
|
|
56
56
|
},
|
|
57
57
|
|
|
@@ -6,47 +6,52 @@ import FleetStatus from '@shell/components/fleet/FleetStatus';
|
|
|
6
6
|
const getResourceDefaultState = (labelGetter, stateKey) => {
|
|
7
7
|
return {
|
|
8
8
|
ready: {
|
|
9
|
-
count:
|
|
10
|
-
color:
|
|
11
|
-
label:
|
|
9
|
+
count: 0,
|
|
10
|
+
color: STATES[STATES_ENUM.READY].color,
|
|
11
|
+
label: labelGetter(`${ stateKey }.${ STATES_ENUM.READY }`, null, STATES[STATES_ENUM.READY].label ),
|
|
12
|
+
status: STATES_ENUM.READY
|
|
12
13
|
},
|
|
13
14
|
info: {
|
|
14
|
-
count:
|
|
15
|
-
color:
|
|
16
|
-
label:
|
|
15
|
+
count: 0,
|
|
16
|
+
color: STATES[STATES_ENUM.INFO].color,
|
|
17
|
+
label: labelGetter(`${ stateKey }.${ STATES_ENUM.INFO }`, null, STATES[STATES_ENUM.INFO].label ),
|
|
18
|
+
status: STATES_ENUM.INFO
|
|
17
19
|
},
|
|
18
20
|
warning: {
|
|
19
|
-
count:
|
|
20
|
-
color:
|
|
21
|
-
label:
|
|
21
|
+
count: 0,
|
|
22
|
+
color: STATES[STATES_ENUM.WARNING].color,
|
|
23
|
+
label: labelGetter(`${ stateKey }.${ STATES_ENUM.WARNING }`, null, STATES[STATES_ENUM.WARNING].label ),
|
|
24
|
+
status: STATES_ENUM.WARNING
|
|
22
25
|
},
|
|
23
26
|
notready: {
|
|
24
|
-
count:
|
|
25
|
-
color:
|
|
26
|
-
label:
|
|
27
|
+
count: 0,
|
|
28
|
+
color: STATES[STATES_ENUM.NOT_READY].color,
|
|
29
|
+
label: labelGetter(`${ stateKey }.${ STATES_ENUM.NOT_READY }`, null, STATES[STATES_ENUM.NOT_READY].label ),
|
|
30
|
+
status: STATES_ENUM.NOT_READY
|
|
27
31
|
},
|
|
28
32
|
error: {
|
|
29
|
-
count:
|
|
30
|
-
color:
|
|
31
|
-
label:
|
|
32
|
-
|
|
33
|
+
count: 0,
|
|
34
|
+
color: STATES[STATES_ENUM.ERROR].color,
|
|
35
|
+
label: labelGetter(`${ stateKey }.${ STATES_ENUM.ERROR }`, null, STATES[STATES_ENUM.ERROR].label ),
|
|
36
|
+
status: STATES_ENUM.ERROR
|
|
33
37
|
},
|
|
34
38
|
errapplied: {
|
|
35
|
-
count:
|
|
36
|
-
color:
|
|
37
|
-
label:
|
|
38
|
-
|
|
39
|
+
count: 0,
|
|
40
|
+
color: STATES[STATES_ENUM.ERR_APPLIED].color,
|
|
41
|
+
label: labelGetter(`${ stateKey }.${ STATES_ENUM.ERR_APPLIED }`, null, STATES[STATES_ENUM.ERR_APPLIED].label ),
|
|
42
|
+
status: STATES_ENUM.ERR_APPLIED,
|
|
39
43
|
},
|
|
40
44
|
waitapplied: {
|
|
41
|
-
count:
|
|
42
|
-
color:
|
|
43
|
-
label:
|
|
44
|
-
|
|
45
|
+
count: 0,
|
|
46
|
+
color: STATES[STATES_ENUM.WAIT_APPLIED].color,
|
|
47
|
+
label: labelGetter(`${ stateKey }.${ STATES_ENUM.WAIT_APPLIED }`, null, STATES[STATES_ENUM.WAIT_APPLIED].label ),
|
|
48
|
+
status: STATES_ENUM.WAIT_APPLIED
|
|
45
49
|
},
|
|
46
50
|
unknown: {
|
|
47
|
-
count:
|
|
48
|
-
color:
|
|
49
|
-
label:
|
|
51
|
+
count: 0,
|
|
52
|
+
color: STATES[STATES_ENUM.UNKNOWN].color,
|
|
53
|
+
label: labelGetter(`${ stateKey }.${ STATES_ENUM.UNKNOWN }`, null, STATES[STATES_ENUM.UNKNOWN].label ),
|
|
54
|
+
status: STATES_ENUM.UNKNOWN
|
|
50
55
|
}
|
|
51
56
|
};
|
|
52
57
|
};
|
|
@@ -782,10 +782,11 @@ export default {
|
|
|
782
782
|
</div>
|
|
783
783
|
</div>
|
|
784
784
|
<div
|
|
785
|
-
v-if="group.ref
|
|
785
|
+
v-if="group.ref"
|
|
786
786
|
class="right group-header-buttons mr-20"
|
|
787
787
|
>
|
|
788
788
|
<MachineSummaryGraph
|
|
789
|
+
v-if="poolSummaryInfo[group.ref]"
|
|
789
790
|
:row="poolSummaryInfo[group.ref]"
|
|
790
791
|
:horizontal="true"
|
|
791
792
|
class="mr-20"
|
package/edit/workload/index.vue
CHANGED
|
@@ -235,7 +235,7 @@ export default {
|
|
|
235
235
|
<div class="col span-6">
|
|
236
236
|
<LabeledSelect
|
|
237
237
|
v-model="imagePullSecrets"
|
|
238
|
-
:label="t('workload.container.imagePullSecrets')"
|
|
238
|
+
:label="t('workload.container.imagePullSecrets.label')"
|
|
239
239
|
:multiple="true"
|
|
240
240
|
:taggable="true"
|
|
241
241
|
:options="imagePullNamespacedSecrets"
|
|
@@ -243,6 +243,7 @@ export default {
|
|
|
243
243
|
option-label="metadata.name"
|
|
244
244
|
:reduce="service=>service.metadata.name"
|
|
245
245
|
:create-option="createOption"
|
|
246
|
+
:tooltip="t('workload.container.imagePullSecrets.tooltip')"
|
|
246
247
|
/>
|
|
247
248
|
</div>
|
|
248
249
|
</div>
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { mount } from '@vue/test-utils';
|
|
2
|
+
import vmwarevsphere, { DEFAULT_VALUES } from '@shell/machine-config/vmwarevsphere.vue';
|
|
3
|
+
|
|
4
|
+
describe('component: vmwarevsphere', () => {
|
|
5
|
+
it('should mount successfully with correct default values', () => {
|
|
6
|
+
const defaultGetters = { 'i18n/t': jest.fn() };
|
|
7
|
+
const wrapper = mount(vmwarevsphere, {
|
|
8
|
+
propsData: {
|
|
9
|
+
poolId: 'poolId',
|
|
10
|
+
credentialId: 'credentialId',
|
|
11
|
+
disabled: false,
|
|
12
|
+
mode: 'create',
|
|
13
|
+
value: {
|
|
14
|
+
initted: false,
|
|
15
|
+
network: [],
|
|
16
|
+
tag: []
|
|
17
|
+
},
|
|
18
|
+
provider: 'vmwarevsphere'
|
|
19
|
+
},
|
|
20
|
+
mocks: {
|
|
21
|
+
$fetchState: { pending: false },
|
|
22
|
+
$store: { getters: defaultGetters },
|
|
23
|
+
},
|
|
24
|
+
stubs: { CodeMirror: true }
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const dataCenterElement = wrapper.find(`[data-testid="datacenter"]`).element;
|
|
28
|
+
const resourcePoolElement = wrapper.find(`[data-testid="resourcePool"]`).element;
|
|
29
|
+
const dataStoreElement = wrapper.find(`[data-testid="dataStore"]`).element;
|
|
30
|
+
const folderElement = wrapper.find(`[data-testid="folder"]`).element;
|
|
31
|
+
const hostElement = wrapper.find(`[data-testid="host"]`).element;
|
|
32
|
+
const gracefulShutdownTimeoutElement = wrapper.find(`[data-testid="gracefulShutdownTimeout"]`).element;
|
|
33
|
+
|
|
34
|
+
expect(dataCenterElement).toBeDefined();
|
|
35
|
+
expect(resourcePoolElement).toBeDefined();
|
|
36
|
+
expect(dataStoreElement).toBeDefined();
|
|
37
|
+
expect(folderElement).toBeDefined();
|
|
38
|
+
expect(hostElement).toBeDefined();
|
|
39
|
+
expect(gracefulShutdownTimeoutElement).toBeDefined();
|
|
40
|
+
|
|
41
|
+
const {
|
|
42
|
+
cpuCount: defaultCpuCount,
|
|
43
|
+
diskSize: defaultDiskSize,
|
|
44
|
+
memorySize: defaultMemorySize,
|
|
45
|
+
hostsystem: defaultHostsystem,
|
|
46
|
+
cloudConfig: defaultCloudConfig,
|
|
47
|
+
gracefulShutdownTimeout: defaultGracefulShutdownTimeout,
|
|
48
|
+
cfgparam: defaultCfgparam,
|
|
49
|
+
os: defaultOs
|
|
50
|
+
} = DEFAULT_VALUES;
|
|
51
|
+
|
|
52
|
+
const {
|
|
53
|
+
cpuCount,
|
|
54
|
+
diskSize,
|
|
55
|
+
memorySize,
|
|
56
|
+
hostsystem,
|
|
57
|
+
cloudConfig,
|
|
58
|
+
gracefulShutdownTimeout,
|
|
59
|
+
cfgparam,
|
|
60
|
+
os
|
|
61
|
+
} = wrapper.vm.$options.propsData.value;
|
|
62
|
+
|
|
63
|
+
expect(cpuCount).toStrictEqual(defaultCpuCount);
|
|
64
|
+
expect(diskSize).toStrictEqual(defaultDiskSize);
|
|
65
|
+
expect(memorySize).toStrictEqual(defaultMemorySize);
|
|
66
|
+
expect(hostsystem).toStrictEqual(defaultHostsystem);
|
|
67
|
+
expect(cloudConfig).toStrictEqual(defaultCloudConfig);
|
|
68
|
+
expect(gracefulShutdownTimeout).toStrictEqual(defaultGracefulShutdownTimeout);
|
|
69
|
+
expect(cfgparam).toStrictEqual(defaultCfgparam);
|
|
70
|
+
expect(os).toStrictEqual(defaultOs);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
@@ -39,7 +39,17 @@ const OS_OPTIONS = [
|
|
|
39
39
|
'linux',
|
|
40
40
|
'windows'
|
|
41
41
|
];
|
|
42
|
-
|
|
42
|
+
|
|
43
|
+
export const DEFAULT_VALUES = {
|
|
44
|
+
cpuCount: '2',
|
|
45
|
+
diskSize: '20000',
|
|
46
|
+
memorySize: '4096',
|
|
47
|
+
hostsystem: '',
|
|
48
|
+
cloudConfig: '#cloud-config\n\n',
|
|
49
|
+
gracefulShutdownTimeout: '0',
|
|
50
|
+
cfgparam: ['disk.enableUUID=TRUE'],
|
|
51
|
+
os: OS_OPTIONS[0]
|
|
52
|
+
};
|
|
43
53
|
|
|
44
54
|
const getDefaultVappOptions = (networks) => {
|
|
45
55
|
return {
|
|
@@ -217,15 +227,27 @@ export default {
|
|
|
217
227
|
if (this.mode === _CREATE && !this.value.initted) {
|
|
218
228
|
Object.defineProperty(this.value, 'initted', { value: true, enumerable: false });
|
|
219
229
|
|
|
230
|
+
const {
|
|
231
|
+
cpuCount,
|
|
232
|
+
diskSize,
|
|
233
|
+
memorySize,
|
|
234
|
+
hostsystem,
|
|
235
|
+
cloudConfig,
|
|
236
|
+
gracefulShutdownTimeout,
|
|
237
|
+
cfgparam,
|
|
238
|
+
os
|
|
239
|
+
} = DEFAULT_VALUES;
|
|
240
|
+
|
|
220
241
|
set(this.value, 'creationType', creationMethods[0].value);
|
|
221
|
-
set(this.value, 'cpuCount',
|
|
222
|
-
set(this.value, 'diskSize',
|
|
223
|
-
set(this.value, 'memorySize',
|
|
224
|
-
set(this.value, 'hostsystem',
|
|
225
|
-
set(this.value, '
|
|
226
|
-
set(this.value, '
|
|
242
|
+
set(this.value, 'cpuCount', cpuCount);
|
|
243
|
+
set(this.value, 'diskSize', diskSize);
|
|
244
|
+
set(this.value, 'memorySize', memorySize);
|
|
245
|
+
set(this.value, 'hostsystem', hostsystem);
|
|
246
|
+
set(this.value, 'gracefulShutdownTimeout', gracefulShutdownTimeout);
|
|
247
|
+
set(this.value, 'cloudConfig', cloudConfig);
|
|
248
|
+
set(this.value, 'cfgparam', cfgparam);
|
|
227
249
|
set(this.value, 'vappProperty', this.value.vappProperty);
|
|
228
|
-
set(this.value, 'os',
|
|
250
|
+
set(this.value, 'os', os);
|
|
229
251
|
Object.entries(INITIAL_VAPP_OPTIONS).forEach(([key, value]) => {
|
|
230
252
|
set(this.value, key, value);
|
|
231
253
|
});
|
|
@@ -326,6 +348,8 @@ export default {
|
|
|
326
348
|
memorySize: integerString('value.memorySize'),
|
|
327
349
|
diskSize: integerString('value.diskSize'),
|
|
328
350
|
|
|
351
|
+
gracefulShutdownTimeout: integerString('value.gracefulShutdownTimeout'),
|
|
352
|
+
|
|
329
353
|
showCloudConfigYaml() {
|
|
330
354
|
return this.value.creationType !== 'legacy';
|
|
331
355
|
},
|
|
@@ -731,7 +755,10 @@ export default {
|
|
|
731
755
|
</p>
|
|
732
756
|
</h4>
|
|
733
757
|
<div slot="body">
|
|
734
|
-
<div
|
|
758
|
+
<div
|
|
759
|
+
class="row"
|
|
760
|
+
data-testid="datacenter"
|
|
761
|
+
>
|
|
735
762
|
<div class="col span-6">
|
|
736
763
|
<LabeledSelect
|
|
737
764
|
v-model="value.datacenter"
|
|
@@ -742,7 +769,10 @@ export default {
|
|
|
742
769
|
:disabled="disabled"
|
|
743
770
|
/>
|
|
744
771
|
</div>
|
|
745
|
-
<div
|
|
772
|
+
<div
|
|
773
|
+
class="col span-6"
|
|
774
|
+
data-testid="resourcePool"
|
|
775
|
+
>
|
|
746
776
|
<LabeledSelect
|
|
747
777
|
v-model="value.pool"
|
|
748
778
|
:loading="resourcePoolsLoading"
|
|
@@ -754,7 +784,10 @@ export default {
|
|
|
754
784
|
</div>
|
|
755
785
|
</div>
|
|
756
786
|
<div class="row mt-10">
|
|
757
|
-
<div
|
|
787
|
+
<div
|
|
788
|
+
class="col span-6"
|
|
789
|
+
data-testid="dataStore"
|
|
790
|
+
>
|
|
758
791
|
<LabeledSelect
|
|
759
792
|
v-model="value.datastore"
|
|
760
793
|
:loading="dataStoresLoading"
|
|
@@ -764,7 +797,10 @@ export default {
|
|
|
764
797
|
:disabled="disabled"
|
|
765
798
|
/>
|
|
766
799
|
</div>
|
|
767
|
-
<div
|
|
800
|
+
<div
|
|
801
|
+
class="col span-6"
|
|
802
|
+
data-testid="folder"
|
|
803
|
+
>
|
|
768
804
|
<LabeledSelect
|
|
769
805
|
v-model="value.folder"
|
|
770
806
|
:loading="foldersLoading"
|
|
@@ -776,7 +812,10 @@ export default {
|
|
|
776
812
|
</div>
|
|
777
813
|
</div>
|
|
778
814
|
<div class="row mt-10">
|
|
779
|
-
<div
|
|
815
|
+
<div
|
|
816
|
+
class="col span-6"
|
|
817
|
+
data-testid="host"
|
|
818
|
+
>
|
|
780
819
|
<LabeledSelect
|
|
781
820
|
v-model="host"
|
|
782
821
|
:loading="hostsLoading"
|
|
@@ -789,6 +828,22 @@ export default {
|
|
|
789
828
|
{{ t('cluster.machineConfig.vsphere.scheduling.host.note') }}
|
|
790
829
|
</p>
|
|
791
830
|
</div>
|
|
831
|
+
<div
|
|
832
|
+
class="col span-6"
|
|
833
|
+
data-testid="gracefulShutdownTimeout"
|
|
834
|
+
>
|
|
835
|
+
<UnitInput
|
|
836
|
+
v-model="gracefulShutdownTimeout"
|
|
837
|
+
:mode="mode"
|
|
838
|
+
:label="t('cluster.machineConfig.vsphere.scheduling.gracefulShutdownTimeout.label')"
|
|
839
|
+
:suffix="t('suffix.seconds', { count: gracefulShutdownTimeout})"
|
|
840
|
+
:disabled="disabled"
|
|
841
|
+
min="0"
|
|
842
|
+
/>
|
|
843
|
+
<p class="text-muted mt-5">
|
|
844
|
+
{{ t('cluster.machineConfig.vsphere.scheduling.gracefulShutdownTimeout.note') }}
|
|
845
|
+
</p>
|
|
846
|
+
</div>
|
|
792
847
|
</div>
|
|
793
848
|
</div>
|
|
794
849
|
</Card>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rancher/shell",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.29",
|
|
4
4
|
"description": "Rancher Dashboard Shell",
|
|
5
5
|
"repository": "https://github.com/rancherlabs/dashboard",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
"@nuxtjs/eslint-config-typescript": "6.0.1",
|
|
42
42
|
"@nuxtjs/webpack-profile": "0.1.0",
|
|
43
43
|
"@popperjs/core": "2.4.4",
|
|
44
|
+
"@types/is-url": "1.2.30",
|
|
44
45
|
"@types/node": "16.4.3",
|
|
45
46
|
"@typescript-eslint/eslint-plugin": "4.33.0",
|
|
46
47
|
"@typescript-eslint/parser": "4.33.0",
|
|
@@ -60,7 +60,11 @@ export default Vue.extend({
|
|
|
60
60
|
|
|
61
61
|
<template>
|
|
62
62
|
<span :class="{'badge-state': true, [bg]: true}">
|
|
63
|
-
<i
|
|
63
|
+
<i
|
|
64
|
+
v-if="icon"
|
|
65
|
+
class="icon"
|
|
66
|
+
:class="{[icon]: true, 'mr-5': !!msg}"
|
|
67
|
+
/>{{ msg }}
|
|
64
68
|
</span>
|
|
65
69
|
</template>
|
|
66
70
|
|
|
@@ -1,13 +1,63 @@
|
|
|
1
1
|
import { mount } from '@vue/test-utils';
|
|
2
2
|
import { Banner } from './index';
|
|
3
|
+
import { cleanHtmlDirective } from '@shell/plugins/clean-html-directive';
|
|
3
4
|
|
|
4
5
|
describe('component: Banner', () => {
|
|
5
6
|
it('should display text based on label', () => {
|
|
6
7
|
const label = 'test';
|
|
7
|
-
const wrapper = mount(
|
|
8
|
+
const wrapper = mount(
|
|
9
|
+
Banner,
|
|
10
|
+
{
|
|
11
|
+
directives: { cleanHtmlDirective },
|
|
12
|
+
propsData: { label }
|
|
13
|
+
});
|
|
8
14
|
|
|
9
15
|
const element = wrapper.find('span').element;
|
|
10
16
|
|
|
11
17
|
expect(element.textContent).toBe(label);
|
|
12
18
|
});
|
|
19
|
+
|
|
20
|
+
it('should display an icon', () => {
|
|
21
|
+
const icon = 'my-icon';
|
|
22
|
+
const wrapper = mount(Banner, { propsData: { icon } });
|
|
23
|
+
|
|
24
|
+
const element = wrapper.find(`.${ icon }`).element;
|
|
25
|
+
|
|
26
|
+
expect(element.classList).toContain(icon);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('should not display an icon', () => {
|
|
30
|
+
const wrapper = mount(Banner);
|
|
31
|
+
|
|
32
|
+
const element = wrapper.find(`[data-testid="banner-icon"]`).element;
|
|
33
|
+
|
|
34
|
+
expect(element).not.toBeDefined();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should emit close event', () => {
|
|
38
|
+
const wrapper = mount(Banner, { propsData: { closable: true } });
|
|
39
|
+
const element = wrapper.find(`[data-testid="banner-close"]`).element;
|
|
40
|
+
|
|
41
|
+
element.click();
|
|
42
|
+
|
|
43
|
+
expect(wrapper.emitted('close')).toHaveLength(1);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('should add the right color', () => {
|
|
47
|
+
const color = 'red';
|
|
48
|
+
const wrapper = mount(Banner, { propsData: { color } });
|
|
49
|
+
|
|
50
|
+
const element = wrapper.element;
|
|
51
|
+
|
|
52
|
+
expect(element.classList).toContain(color);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('should stack the banner messages', () => {
|
|
56
|
+
const stacked = true;
|
|
57
|
+
const wrapper = mount(Banner, { propsData: { stacked } });
|
|
58
|
+
|
|
59
|
+
const element = wrapper.find(`[data-testid="banner-content"]`).element;
|
|
60
|
+
|
|
61
|
+
expect(element.classList).toContain('stacked');
|
|
62
|
+
});
|
|
13
63
|
});
|