@rancher/shell 3.0.0-rc.2 → 3.0.0-rc.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/assets/styles/global/_layout.scss +9 -0
- package/assets/styles/global/_tooltip.scss +13 -1
- package/assets/translations/en-us.yaml +1 -0
- package/components/ActionDropdown.vue +1 -1
- package/components/CodeMirror.vue +82 -67
- package/components/CruResource.vue +59 -61
- package/components/Import.vue +0 -1
- package/components/LocaleSelector.vue +4 -2
- package/components/SortableTable/index.vue +2 -1
- package/components/Wizard.vue +2 -0
- package/components/YamlEditor.vue +1 -1
- package/components/__tests__/ContainerResourceLimit.test.ts +35 -0
- package/components/auth/SelectPrincipal.vue +1 -1
- package/components/fleet/FleetStatus.vue +2 -2
- package/components/form/Labels.vue +11 -13
- package/components/form/UnitInput.vue +2 -0
- package/components/form/__tests__/UnitInput.test.ts +68 -0
- package/components/formatter/AppSummaryGraph.vue +2 -2
- package/components/formatter/FleetSummaryGraph.vue +2 -2
- package/components/formatter/InternalExternalIP.vue +13 -15
- package/components/formatter/MachineSummaryGraph.vue +2 -2
- package/components/formatter/Scale.vue +2 -2
- package/components/formatter/Weight.vue +2 -2
- package/components/nav/NamespaceFilter.vue +2 -1
- package/components/nav/TopLevelMenu.vue +4 -4
- package/components/nav/WindowManager/ContainerLogs.vue +2 -1
- package/composables/useUserRetentionValidation.test.ts +1 -1
- package/composables/useUserRetentionValidation.ts +1 -1
- package/core/{plugin-helpers.js → plugin-helpers.ts} +25 -7
- package/core/plugin-routes.ts +5 -6
- package/core/plugin.ts +30 -3
- package/detail/helm.cattle.io.projecthelmchart.vue +6 -8
- package/edit/auth/ldap/config.vue +280 -280
- package/edit/auth/saml.vue +1 -4
- package/edit/cis.cattle.io.clusterscan.vue +80 -82
- package/edit/cis.cattle.io.clusterscanprofile.vue +29 -31
- package/edit/management.cattle.io.clusterroletemplatebinding.vue +1 -0
- package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +30 -32
- package/edit/resources.cattle.io.backup.vue +95 -97
- package/edit/resources.cattle.io.restore.vue +96 -98
- package/edit/service.vue +10 -2
- package/edit/workload/__tests__/index.test.ts +9 -7
- package/edit/workload/index.vue +15 -9
- package/initialize/install-plugins.js +2 -2
- package/mixins/fetch.client.js +2 -1
- package/package.json +3 -3
- package/pages/auth/login.vue +2 -1
- package/pages/c/_cluster/auth/user.retention/index.vue +1 -1
- package/pages/c/_cluster/uiplugins/AddExtensionRepos.vue +34 -36
- package/pages/index.vue +10 -2
- package/plugins/i18n.js +1 -1
- package/promptRemove/management.cattle.io.roletemplate.vue +3 -5
- package/rancher-components/LabeledTooltip/LabeledTooltip.vue +4 -33
- package/store/type-map.js +3 -2
- package/composables/useStore.ts +0 -16
|
@@ -131,6 +131,15 @@ HEADER {
|
|
|
131
131
|
outline: 0;
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
+
&[data-popper-placement^="top"] {
|
|
135
|
+
.v-popper__arrow-container {
|
|
136
|
+
.v-popper__arrow-inner {
|
|
137
|
+
top: 0;
|
|
138
|
+
border-color: var(--tooltip-bg);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
134
143
|
li {
|
|
135
144
|
padding: 8px 20px;
|
|
136
145
|
|
|
@@ -123,7 +123,6 @@
|
|
|
123
123
|
color: var(--popover-text);
|
|
124
124
|
padding: 10px;
|
|
125
125
|
border-radius: var(--border-radius);
|
|
126
|
-
box-shadow: 0 5px 20px var(--shadow);
|
|
127
126
|
border: none;
|
|
128
127
|
|
|
129
128
|
a {
|
|
@@ -133,6 +132,19 @@
|
|
|
133
132
|
|
|
134
133
|
.v-popper__arrow-container {
|
|
135
134
|
border-color: transparent;
|
|
135
|
+
.v-popper__arrow-outer {
|
|
136
|
+
border-color: transparent;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.v-popper__popper.v-popper--theme-dropdown {
|
|
142
|
+
z-index: z-index('tooltip');
|
|
143
|
+
|
|
144
|
+
&.containerLogsDropdown {
|
|
145
|
+
.v-popper__arrow-container {
|
|
146
|
+
display: none;
|
|
147
|
+
}
|
|
136
148
|
}
|
|
137
149
|
}
|
|
138
150
|
|
|
@@ -57,7 +57,7 @@ export default {
|
|
|
57
57
|
theme: `base16-${ theme }`,
|
|
58
58
|
lineNumbers: true,
|
|
59
59
|
line: true,
|
|
60
|
-
styleActiveLine:
|
|
60
|
+
styleActiveLine: false,
|
|
61
61
|
lineWrapping: true,
|
|
62
62
|
foldGutter: true,
|
|
63
63
|
styleSelectedText: true,
|
|
@@ -66,6 +66,7 @@ export default {
|
|
|
66
66
|
|
|
67
67
|
if (this.asTextArea) {
|
|
68
68
|
out.lineNumbers = false;
|
|
69
|
+
out.foldGutter = false;
|
|
69
70
|
out.tabSize = 0;
|
|
70
71
|
out.extraKeys = { Tab: false };
|
|
71
72
|
}
|
|
@@ -178,6 +179,7 @@ export default {
|
|
|
178
179
|
:value="value"
|
|
179
180
|
:options="combinedOptions"
|
|
180
181
|
:disabled="isDisabled"
|
|
182
|
+
:original-style="true"
|
|
181
183
|
@ready="onReady"
|
|
182
184
|
@input="onInput"
|
|
183
185
|
@changes="onChanges"
|
|
@@ -194,72 +196,8 @@ export default {
|
|
|
194
196
|
<style lang="scss">
|
|
195
197
|
$code-mirror-animation-time: 0.1s;
|
|
196
198
|
|
|
197
|
-
.
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
// Keyboard mapping overlap
|
|
201
|
-
.keymap.overlay {
|
|
202
|
-
position: absolute;
|
|
203
|
-
display: flex;
|
|
204
|
-
top: 7px;
|
|
205
|
-
right: 7px;
|
|
206
|
-
z-index: 1;
|
|
207
|
-
cursor: pointer;
|
|
208
|
-
|
|
209
|
-
.keymap-indicator {
|
|
210
|
-
width: 48px;
|
|
211
|
-
height: 32px;
|
|
212
|
-
display: flex;
|
|
213
|
-
align-items: center;
|
|
214
|
-
justify-content: center;
|
|
215
|
-
border: 1px solid transparent;
|
|
216
|
-
color: var(--darker);
|
|
217
|
-
background-color: var(--overlay-bg);
|
|
218
|
-
font-size: 12px;
|
|
219
|
-
|
|
220
|
-
.close-indicator {
|
|
221
|
-
width: 0;
|
|
222
|
-
|
|
223
|
-
.icon-close {
|
|
224
|
-
color: var(--primary);
|
|
225
|
-
opacity: 0;
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
.keymap-icon {
|
|
230
|
-
font-size: 24px;
|
|
231
|
-
opacity: 0.8;
|
|
232
|
-
transition: margin-right $code-mirror-animation-time ease-in-out;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
&:hover {
|
|
236
|
-
border: 1px solid var(--primary);
|
|
237
|
-
border-radius: var(--border-radius);;
|
|
238
|
-
|
|
239
|
-
.close-indicator {
|
|
240
|
-
margin-left: -6px;
|
|
241
|
-
width: auto;
|
|
242
|
-
|
|
243
|
-
.icon-close {
|
|
244
|
-
opacity: 1;
|
|
245
|
-
transition: opacity $code-mirror-animation-time ease-in-out $code-mirror-animation-time; // Only animate when being shown
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
.keymap-icon {
|
|
250
|
-
opacity: 0.6;
|
|
251
|
-
margin-right: 10px;
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
.vue-codemirror .CodeMirror {
|
|
258
|
-
height: initial;
|
|
259
|
-
background: none
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
&.as-text-area {
|
|
199
|
+
.code-mirror {
|
|
200
|
+
&.as-text-area .codemirror-container{
|
|
263
201
|
min-height: 40px;
|
|
264
202
|
position: relative;
|
|
265
203
|
display: block;
|
|
@@ -345,6 +283,83 @@ export default {
|
|
|
345
283
|
color: var(--primary-text);
|
|
346
284
|
background-color: var(--primary);
|
|
347
285
|
}
|
|
286
|
+
|
|
287
|
+
.CodeMirror-gutters .CodeMirror-foldgutter:empty {
|
|
288
|
+
display: none;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
.code-mirror .codemirror-container {
|
|
294
|
+
z-index: 0;
|
|
295
|
+
font-size: inherit !important;
|
|
296
|
+
|
|
297
|
+
// Keyboard mapping overlap
|
|
298
|
+
.keymap.overlay {
|
|
299
|
+
position: absolute;
|
|
300
|
+
display: flex;
|
|
301
|
+
top: 7px;
|
|
302
|
+
right: 7px;
|
|
303
|
+
z-index: 1;
|
|
304
|
+
cursor: pointer;
|
|
305
|
+
|
|
306
|
+
.keymap-indicator {
|
|
307
|
+
width: 48px;
|
|
308
|
+
height: 32px;
|
|
309
|
+
display: flex;
|
|
310
|
+
align-items: center;
|
|
311
|
+
justify-content: center;
|
|
312
|
+
border: 1px solid transparent;
|
|
313
|
+
color: var(--darker);
|
|
314
|
+
background-color: var(--overlay-bg);
|
|
315
|
+
font-size: 12px;
|
|
316
|
+
|
|
317
|
+
.close-indicator {
|
|
318
|
+
width: 0;
|
|
319
|
+
|
|
320
|
+
.icon-close {
|
|
321
|
+
color: var(--primary);
|
|
322
|
+
opacity: 0;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
.keymap-icon {
|
|
327
|
+
font-size: 24px;
|
|
328
|
+
opacity: 0.8;
|
|
329
|
+
transition: margin-right $code-mirror-animation-time ease-in-out;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
&:hover {
|
|
333
|
+
border: 1px solid var(--primary);
|
|
334
|
+
border-radius: var(--border-radius);;
|
|
335
|
+
|
|
336
|
+
.close-indicator {
|
|
337
|
+
margin-left: -6px;
|
|
338
|
+
width: auto;
|
|
339
|
+
|
|
340
|
+
.icon-close {
|
|
341
|
+
opacity: 1;
|
|
342
|
+
transition: opacity $code-mirror-animation-time ease-in-out $code-mirror-animation-time; // Only animate when being shown
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
.keymap-icon {
|
|
347
|
+
opacity: 0.6;
|
|
348
|
+
margin-right: 10px;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
//rm no longer extant selector
|
|
355
|
+
.CodeMirror {
|
|
356
|
+
height: initial;
|
|
357
|
+
background: none
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
.CodeMirror-gutters {
|
|
361
|
+
background: inherit;
|
|
348
362
|
}
|
|
363
|
+
|
|
349
364
|
}
|
|
350
365
|
</style>
|
|
@@ -587,76 +587,74 @@ export default {
|
|
|
587
587
|
</template>
|
|
588
588
|
</template>
|
|
589
589
|
<template #controlsContainer="{showPrevious, next, back, activeStep, canNext, activeStepIndex, visibleSteps}">
|
|
590
|
-
<
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
590
|
+
<CruResourceFooter
|
|
591
|
+
class="cru__footer"
|
|
592
|
+
:mode="mode"
|
|
593
|
+
:is-form="showAsForm"
|
|
594
|
+
:show-cancel="showCancel"
|
|
595
|
+
@cancel-confirmed="confirmCancel"
|
|
596
|
+
>
|
|
597
|
+
<!-- Pass down templates provided by the caller -->
|
|
598
|
+
<template
|
|
599
|
+
v-for="(_, slot) of $slots"
|
|
600
|
+
#[slot]="scope"
|
|
601
|
+
:key="slot"
|
|
597
602
|
>
|
|
598
|
-
|
|
603
|
+
<template v-if="shouldProvideSlot(slot)">
|
|
604
|
+
<slot
|
|
605
|
+
:name="slot"
|
|
606
|
+
v-bind="scope"
|
|
607
|
+
/>
|
|
608
|
+
</template>
|
|
609
|
+
</template>
|
|
610
|
+
<div class="controls-steps">
|
|
611
|
+
<button
|
|
612
|
+
v-if="showYaml"
|
|
613
|
+
type="button"
|
|
614
|
+
class="btn role-secondary"
|
|
615
|
+
@click="showPreviewYaml"
|
|
616
|
+
>
|
|
617
|
+
<t k="cruResource.previewYaml" />
|
|
618
|
+
</button>
|
|
599
619
|
<template
|
|
600
|
-
v-
|
|
601
|
-
|
|
602
|
-
:key="slot"
|
|
620
|
+
v-if="showPrevious"
|
|
621
|
+
name="back"
|
|
603
622
|
>
|
|
604
|
-
<template v-if="shouldProvideSlot(slot)">
|
|
605
|
-
<slot
|
|
606
|
-
:name="slot"
|
|
607
|
-
v-bind="scope"
|
|
608
|
-
/>
|
|
609
|
-
</template>
|
|
610
|
-
</template>
|
|
611
|
-
<div class="controls-steps">
|
|
612
623
|
<button
|
|
613
|
-
v-if="showYaml"
|
|
614
624
|
type="button"
|
|
615
625
|
class="btn role-secondary"
|
|
616
|
-
@click="
|
|
626
|
+
@click="back()"
|
|
617
627
|
>
|
|
618
|
-
<t k="
|
|
628
|
+
<t k="wizard.previous" />
|
|
619
629
|
</button>
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
/>
|
|
643
|
-
</template>
|
|
644
|
-
<template
|
|
645
|
-
v-else
|
|
646
|
-
name="next"
|
|
630
|
+
</template>
|
|
631
|
+
<template
|
|
632
|
+
v-if="activeStepIndex === visibleSteps.length-1"
|
|
633
|
+
name="finish"
|
|
634
|
+
>
|
|
635
|
+
<AsyncButton
|
|
636
|
+
v-if="!showSubtypeSelection && !isView"
|
|
637
|
+
ref="save"
|
|
638
|
+
:disabled="!activeStep.ready"
|
|
639
|
+
:mode="finishButtonMode || mode"
|
|
640
|
+
@click="$emit('finish', $event)"
|
|
641
|
+
/>
|
|
642
|
+
</template>
|
|
643
|
+
<template
|
|
644
|
+
v-else
|
|
645
|
+
name="next"
|
|
646
|
+
>
|
|
647
|
+
<button
|
|
648
|
+
:disabled="!canNext"
|
|
649
|
+
type="button"
|
|
650
|
+
class="btn role-primary"
|
|
651
|
+
@click="next()"
|
|
647
652
|
>
|
|
648
|
-
<
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
>
|
|
654
|
-
<t k="wizard.next" />
|
|
655
|
-
</button>
|
|
656
|
-
</template>
|
|
657
|
-
</div>
|
|
658
|
-
</CruResourceFooter>
|
|
659
|
-
</template>
|
|
653
|
+
<t k="wizard.next" />
|
|
654
|
+
</button>
|
|
655
|
+
</template>
|
|
656
|
+
</div>
|
|
657
|
+
</CruResourceFooter>
|
|
660
658
|
</template>
|
|
661
659
|
</Wizard>
|
|
662
660
|
</div>
|
package/components/Import.vue
CHANGED
|
@@ -52,9 +52,11 @@ export default {
|
|
|
52
52
|
<div v-if="mode === 'login'">
|
|
53
53
|
<div v-if="showLocale">
|
|
54
54
|
<v-dropdown
|
|
55
|
-
|
|
55
|
+
popperClass="localeSelector"
|
|
56
56
|
placement="top"
|
|
57
|
-
|
|
57
|
+
distance="8"
|
|
58
|
+
skidding="12"
|
|
59
|
+
:triggers="['click']"
|
|
58
60
|
>
|
|
59
61
|
<a
|
|
60
62
|
data-testid="locale-selector"
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { mapGetters } from 'vuex';
|
|
3
|
+
import { defineAsyncComponent } from 'vue';
|
|
3
4
|
import day from 'dayjs';
|
|
4
5
|
import isEmpty from 'lodash/isEmpty';
|
|
5
6
|
import { dasherize, ucFirst } from '@shell/utils/string';
|
|
@@ -682,7 +683,7 @@ export default {
|
|
|
682
683
|
const pluginFormatter = this.$plugin?.getDynamic('formatters', c.formatter);
|
|
683
684
|
|
|
684
685
|
if (pluginFormatter) {
|
|
685
|
-
component = pluginFormatter;
|
|
686
|
+
component = defineAsyncComponent(pluginFormatter);
|
|
686
687
|
needRef = true;
|
|
687
688
|
}
|
|
688
689
|
}
|
package/components/Wizard.vue
CHANGED
|
@@ -4,6 +4,7 @@ import AsyncButton from '@shell/components/AsyncButton';
|
|
|
4
4
|
import { Banner } from '@components/Banner';
|
|
5
5
|
import Loading from '@shell/components/Loading';
|
|
6
6
|
import { stringify } from '@shell/utils/error';
|
|
7
|
+
import LazyImage from '@shell/components/LazyImage';
|
|
7
8
|
|
|
8
9
|
/*
|
|
9
10
|
Wizard accepts an array of steps (see props), and creates named slots for each step.
|
|
@@ -26,6 +27,7 @@ export default {
|
|
|
26
27
|
AsyncButton,
|
|
27
28
|
Banner,
|
|
28
29
|
Loading,
|
|
30
|
+
LazyImage,
|
|
29
31
|
},
|
|
30
32
|
|
|
31
33
|
props: {
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { mount } from '@vue/test-utils';
|
|
2
|
+
import ContainerResourceLimit from '@shell/components/ContainerResourceLimit.vue';
|
|
3
|
+
|
|
4
|
+
describe('component: ContainerResourceLimit', () => {
|
|
5
|
+
it.each([
|
|
6
|
+
['limitsCpu', 'cpu-limit', '111m', '111'],
|
|
7
|
+
['limitsMemory', 'memory-limit', '111Mi', '111'],
|
|
8
|
+
['requestsCpu', 'cpu-reservation', '111m', '111'],
|
|
9
|
+
['requestsMemory', 'memory-reservation', '111Mi', '111'],
|
|
10
|
+
// ['limitsGpu', 'gpu-limit', 1000], // Input does not work atm
|
|
11
|
+
])('given value prop key %p as %p should display value %p', (key, id, value, expectation) => {
|
|
12
|
+
const wrapper = mount(ContainerResourceLimit, { propsData: { value: { [key]: value } } });
|
|
13
|
+
|
|
14
|
+
const element = wrapper.find(`[data-testid="${ id }"]`).element as HTMLInputElement;
|
|
15
|
+
|
|
16
|
+
expect(element.value).toBe(expectation);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
describe.each([
|
|
20
|
+
'cpu-reservation',
|
|
21
|
+
'memory-reservation',
|
|
22
|
+
'cpu-limit',
|
|
23
|
+
'memory-limit',
|
|
24
|
+
])('given input %p', (id) => {
|
|
25
|
+
it.each(['input', 'blur'])('on %p 123 should display input value 123', async(trigger) => {
|
|
26
|
+
const wrapper = mount(ContainerResourceLimit);
|
|
27
|
+
const input = wrapper.find(`[data-testid="${ id }"]`);
|
|
28
|
+
|
|
29
|
+
await input.setValue('123');
|
|
30
|
+
await input.trigger(trigger);
|
|
31
|
+
|
|
32
|
+
expect((input.element as HTMLInputElement).value).toBe('123');
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
});
|
|
@@ -160,9 +160,9 @@ function toPercent(value, min, max) {
|
|
|
160
160
|
ref="popover"
|
|
161
161
|
placement="bottom-end"
|
|
162
162
|
offset="-10"
|
|
163
|
-
|
|
163
|
+
:triggers="[]"
|
|
164
164
|
:delay="{show: 0, hide: 0}"
|
|
165
|
-
:
|
|
165
|
+
:flip="false"
|
|
166
166
|
:container="false"
|
|
167
167
|
>
|
|
168
168
|
<div class="meta-title">
|
|
@@ -97,19 +97,17 @@ export default {
|
|
|
97
97
|
name="labels"
|
|
98
98
|
:toggler="toggler"
|
|
99
99
|
>
|
|
100
|
-
<
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
/>
|
|
112
|
-
</template>
|
|
100
|
+
<KeyValue
|
|
101
|
+
key="labels"
|
|
102
|
+
:value="value.labels"
|
|
103
|
+
:protected-keys="value.systemLabels || []"
|
|
104
|
+
:toggle-filter="toggler"
|
|
105
|
+
:add-label="t('labels.addLabel')"
|
|
106
|
+
:mode="mode"
|
|
107
|
+
:read-allowed="false"
|
|
108
|
+
:value-can-be-empty="true"
|
|
109
|
+
@update:value="value.setLabels($event)"
|
|
110
|
+
/>
|
|
113
111
|
</slot>
|
|
114
112
|
</div>
|
|
115
113
|
</div>
|
|
@@ -2,6 +2,7 @@ import { mount } from '@vue/test-utils';
|
|
|
2
2
|
import { UNITS } from '@shell/utils/units';
|
|
3
3
|
import UnitInput from '@shell/components/form/UnitInput.vue';
|
|
4
4
|
import LabeledInput from '@components/Form/LabeledInput/LabeledInput.vue';
|
|
5
|
+
import { defineComponent } from 'vue';
|
|
5
6
|
|
|
6
7
|
describe('component: UnitInput', () => {
|
|
7
8
|
it('should renders', () => {
|
|
@@ -184,4 +185,71 @@ describe('component: UnitInput', () => {
|
|
|
184
185
|
expect(wrapper.emitted('update:value')).toBeTruthy();
|
|
185
186
|
expect(wrapper.emitted('update:value')[4][0]).toBe(value);
|
|
186
187
|
});
|
|
188
|
+
|
|
189
|
+
describe.each([
|
|
190
|
+
['123m', -1, 1000, 'CPUs', true],
|
|
191
|
+
// ['123Mi', 2, 1024, '', true],
|
|
192
|
+
])('given real use case with value %p, exponent %p, increment %p, baseUnit %p, modifier %p', (value, inputExponent, increment, baseUnit, outputModifier) => {
|
|
193
|
+
it('should display input value 123', () => {
|
|
194
|
+
const wrapper = mount(UnitInput, {
|
|
195
|
+
props: {
|
|
196
|
+
value,
|
|
197
|
+
inputExponent,
|
|
198
|
+
increment,
|
|
199
|
+
outputModifier,
|
|
200
|
+
baseUnit
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
const inputElement = wrapper.find('input').element as HTMLInputElement;
|
|
205
|
+
|
|
206
|
+
expect(inputElement.value).toBe('123');
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it.each(['input', 'blur'])('on %p 123 should display input value 123', async(trigger) => {
|
|
210
|
+
const wrapper = mount(UnitInput, {
|
|
211
|
+
props: {
|
|
212
|
+
value: '0',
|
|
213
|
+
inputExponent,
|
|
214
|
+
increment,
|
|
215
|
+
outputModifier,
|
|
216
|
+
baseUnit
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
const input = wrapper.find('input');
|
|
220
|
+
|
|
221
|
+
await input.setValue('123');
|
|
222
|
+
await input.trigger(trigger);
|
|
223
|
+
|
|
224
|
+
expect(wrapper.emitted('update:value')).toBeTruthy();
|
|
225
|
+
expect(input.element.value).toBe('123');
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
it('should keep parent value to 123 on input', async() => {
|
|
229
|
+
const ParentComponent = defineComponent({
|
|
230
|
+
components: { UnitInput },
|
|
231
|
+
template: `
|
|
232
|
+
<UnitInput
|
|
233
|
+
:value="value"
|
|
234
|
+
:input-exponent="inputExponent"
|
|
235
|
+
:output-modifier="outputModifier"
|
|
236
|
+
:base-unit="baseUnit"
|
|
237
|
+
@update:value="event => value = event.target.value"
|
|
238
|
+
/>
|
|
239
|
+
`,
|
|
240
|
+
data() {
|
|
241
|
+
return {
|
|
242
|
+
value, inputExponent, outputModifier, baseUnit
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
const wrapper = mount(ParentComponent);
|
|
247
|
+
const input = wrapper.find('input');
|
|
248
|
+
|
|
249
|
+
await input.trigger('update:value');
|
|
250
|
+
await input.trigger('input');
|
|
251
|
+
|
|
252
|
+
expect(input.element.value).toBe('123');
|
|
253
|
+
});
|
|
254
|
+
});
|
|
187
255
|
});
|