@rancher/shell 3.0.2-rc.6 → 3.0.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 +3 -1
- package/assets/styles/themes/_light.scss +1 -2
- package/assets/styles/themes/_suse.scss +1 -0
- package/assets/translations/en-us.yaml +18 -3
- package/chart/monitoring/prometheus/index.vue +13 -10
- package/components/ButtonGroup.vue +4 -0
- package/components/FixedBanner.vue +19 -12
- package/components/LocaleSelector.vue +2 -0
- package/components/SortableTable/THead.vue +2 -0
- package/components/SortableTable/index.vue +35 -5
- package/components/StatusBadge.vue +71 -0
- package/components/__tests__/FixedBanner.test.ts +3 -3
- package/components/form/MatchExpressions.vue +4 -0
- package/components/form/Select.vue +11 -2
- package/components/form/UnitInput.vue +2 -2
- package/components/form/__tests__/UnitInput.test.ts +4 -5
- package/components/nav/Favorite.vue +5 -1
- package/components/nav/Group.vue +4 -0
- package/components/nav/Jump.vue +7 -0
- package/components/nav/Pinned.vue +1 -1
- package/components/nav/TopLevelMenu.vue +1 -12
- package/components/nav/Type.vue +1 -0
- package/components/nav/__tests__/TopLevelMenu.test.ts +0 -40
- package/config/router/routes.js +1 -0
- package/core/plugin-routes.ts +5 -115
- package/core/plugins.js +1 -1
- package/core/types.ts +18 -2
- package/detail/__tests__/autoscaling.horizontalpodautoscaler.test.ts +84 -23
- package/detail/autoscaling.horizontalpodautoscaler/index.vue +13 -3
- package/edit/auth/__tests__/oidc.test.ts +34 -3
- package/edit/auth/ldap/__tests__/config.test.ts +0 -14
- package/edit/auth/ldap/config.vue +0 -24
- package/edit/auth/oidc.vue +1 -1
- package/edit/autoscaling.horizontalpodautoscaler/metric-identifier.vue +5 -2
- package/edit/fleet.cattle.io.clustergroup.vue +5 -3
- package/edit/fleet.cattle.io.gitrepo.vue +1 -0
- package/edit/logging-flow/Match.vue +1 -1
- package/edit/provisioning.cattle.io.cluster/__tests__/Advanced.test.ts +0 -2
- package/edit/provisioning.cattle.io.cluster/rke2.vue +1 -1
- package/edit/provisioning.cattle.io.cluster/tabs/Advanced.vue +5 -2
- package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +1 -1
- package/edit/service.vue +0 -3
- package/edit/workload/Job.vue +6 -6
- package/edit/workload/__tests__/Job.test.ts +0 -1
- package/models/__tests__/logging.banzaicloud.io.flow.test.ts +88 -0
- package/models/logging.banzaicloud.io.flow.js +2 -1
- package/package.json +2 -2
- package/pages/auth/login.vue +1 -9
- package/rancher-components/Form/Checkbox/Checkbox.vue +9 -1
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +7 -2
- package/scripts/extension/helm/charts/ui-plugin-server/templates/_helpers.tpl +2 -2
- package/scripts/test-plugins-build.sh +4 -6
- package/store/aws.js +9 -2
- package/types/shell/index.d.ts +0 -10
- package/utils/banners.js +0 -45
- package/utils/color.js +9 -8
- package/utils/object.js +0 -3
|
@@ -26,7 +26,6 @@ $disabled : $medium;
|
|
|
26
26
|
$primary : #3D98D3;
|
|
27
27
|
$secondary : $darker;
|
|
28
28
|
$link : #3D98D3;
|
|
29
|
-
$keyboard-focus : #{darken($primary, 10%)};
|
|
30
29
|
|
|
31
30
|
// Status colors
|
|
32
31
|
$success : #5D995D;
|
|
@@ -54,7 +53,7 @@ BODY, .theme-light {
|
|
|
54
53
|
--primary-border : #{$primary};
|
|
55
54
|
--primary-banner-bg : #{rgba($primary, 0.15)};
|
|
56
55
|
--primary-light-bg : #{rgba($primary, 0.05)};
|
|
57
|
-
--primary-keyboard-focus :
|
|
56
|
+
--primary-keyboard-focus : hsl(from var(--primary) h s calc(l - 10));
|
|
58
57
|
|
|
59
58
|
|
|
60
59
|
.text-primary {
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
--primary-border : #{$primary};
|
|
13
13
|
--primary-banner-bg : #{rgba($primary, 0.15)};
|
|
14
14
|
--primary-light-bg : #{rgba($primary, 0.05)};
|
|
15
|
+
--primary-keyboard-focus : hsl(from var(--primary) h s calc(l - 10));
|
|
15
16
|
|
|
16
17
|
--info : #{$info};
|
|
17
18
|
--info-text : #{contrast-color($info)};
|
|
@@ -239,6 +239,7 @@ nav:
|
|
|
239
239
|
label: Resource Search
|
|
240
240
|
toolTip: Resource Search {key}
|
|
241
241
|
placeholder: Type to search for a resource...
|
|
242
|
+
filteringDescription: Using this input will immediately filter the results in the list below
|
|
242
243
|
header:
|
|
243
244
|
setLoginPage: Set as login page
|
|
244
245
|
restoreCards: Restore hidden cards
|
|
@@ -545,9 +546,6 @@ authConfig:
|
|
|
545
546
|
starttls:
|
|
546
547
|
label: Start TLS
|
|
547
548
|
tip: Upgrades non-encrypted connections by wrapping with TLS during the connection process. Can not be used in conjunction with TLS.
|
|
548
|
-
searchUsingServiceAccount:
|
|
549
|
-
label: Enable Service Account Search
|
|
550
|
-
tip: When enabled, Rancher will use the service account instead of the user account to search for users and groups.
|
|
551
549
|
tls: TLS
|
|
552
550
|
userEnabledAttribute: User Enabled Attribute
|
|
553
551
|
userMemberAttribute: User Member Attribute
|
|
@@ -2779,6 +2777,7 @@ hpa:
|
|
|
2779
2777
|
label: Metric Name
|
|
2780
2778
|
placeholder: e.g. packets-per-second
|
|
2781
2779
|
selector:
|
|
2780
|
+
header: Metric Selector
|
|
2782
2781
|
label: Add Selector
|
|
2783
2782
|
metricTarget:
|
|
2784
2783
|
averageVal:
|
|
@@ -5138,6 +5137,9 @@ resourceDetail:
|
|
|
5138
5137
|
stage: "Stage from {subtype} {name}"
|
|
5139
5138
|
view: "{subtype} {name}"
|
|
5140
5139
|
masthead:
|
|
5140
|
+
ariaLabel:
|
|
5141
|
+
favoriteAction: Add {resource} to your starred/favorites list
|
|
5142
|
+
unfavoriteAction: Remove {resource} from your starred/favorites list
|
|
5141
5143
|
age: Age
|
|
5142
5144
|
createdBy: Created by
|
|
5143
5145
|
restartCount: Pod Restarts
|
|
@@ -5490,6 +5492,18 @@ setup:
|
|
|
5490
5492
|
welcome: Welcome to {vendor}!
|
|
5491
5493
|
|
|
5492
5494
|
sortableTable:
|
|
5495
|
+
ariaLabel:
|
|
5496
|
+
firstPageBtn: First page of results
|
|
5497
|
+
prevPageBtn: Previous page of results
|
|
5498
|
+
nextPageBtn: Next page of results
|
|
5499
|
+
lastPageBtn: Last page of results
|
|
5500
|
+
alt:
|
|
5501
|
+
firstPageBtn: First page of results icon
|
|
5502
|
+
prevPageBtn: Previous page of results icon
|
|
5503
|
+
nextPageBtn: Next page of results icon
|
|
5504
|
+
lastPageBtn: Last page of results icon
|
|
5505
|
+
sortingIconDesc: Table header descending sort icon
|
|
5506
|
+
sortingIconAsc: Table header ascending sort icon
|
|
5493
5507
|
genericGroupCheckbox: Table group selection checkbox
|
|
5494
5508
|
genericRowCheckbox: Table row selection checkbox for item {item}
|
|
5495
5509
|
tableActionsLabel: More actions - { resource }
|
|
@@ -5518,6 +5532,7 @@ sortableTable:
|
|
|
5518
5532
|
searchLabel: Filter table results
|
|
5519
5533
|
in: in
|
|
5520
5534
|
addFilter: Add Filter
|
|
5535
|
+
filteringDescription: Using this input will immediately filter the results in the table below
|
|
5521
5536
|
filterFor: Filter for...
|
|
5522
5537
|
selectCol: Select a column
|
|
5523
5538
|
resetFilters: Reset
|
|
@@ -341,22 +341,25 @@ export default {
|
|
|
341
341
|
</div>
|
|
342
342
|
<div class="row">
|
|
343
343
|
<div class="col span-12">
|
|
344
|
-
<div class="mb-5 mt-5">
|
|
345
|
-
<h4 class=" mb-10">
|
|
346
|
-
{{ t('monitoring.prometheus.storage.selector') }}
|
|
347
|
-
</h4>
|
|
348
|
-
</div>
|
|
349
|
-
<Banner
|
|
350
|
-
color="warning"
|
|
351
|
-
:label="t('monitoring.prometheus.storage.selectorWarning', {}, true)"
|
|
352
|
-
/>
|
|
353
344
|
<MatchExpressions
|
|
354
345
|
:initial-empty-row="false"
|
|
355
346
|
:mode="mode"
|
|
356
347
|
:value="matchExpressions"
|
|
357
348
|
:show-remove="false"
|
|
358
349
|
@update:value="matchChanged($event)"
|
|
359
|
-
|
|
350
|
+
>
|
|
351
|
+
<template #header>
|
|
352
|
+
<div class="mb-5 mt-5">
|
|
353
|
+
<h4 class=" mb-10">
|
|
354
|
+
{{ t('monitoring.prometheus.storage.selector') }}
|
|
355
|
+
</h4>
|
|
356
|
+
</div>
|
|
357
|
+
<Banner
|
|
358
|
+
color="warning"
|
|
359
|
+
:label="t('monitoring.prometheus.storage.selectorWarning', {}, true)"
|
|
360
|
+
/>
|
|
361
|
+
</template>
|
|
362
|
+
</MatchExpressions>
|
|
360
363
|
</div>
|
|
361
364
|
</div>
|
|
362
365
|
</template>
|
|
@@ -77,6 +77,9 @@ export default {
|
|
|
77
77
|
const tooltip = opt.tooltipKey ? this.t(opt.tooltipKey) : opt.tooltip;
|
|
78
78
|
|
|
79
79
|
return ariaLabel || tooltip || label || undefined;
|
|
80
|
+
},
|
|
81
|
+
isPressed(opt) {
|
|
82
|
+
return this.value === opt.value;
|
|
80
83
|
}
|
|
81
84
|
}
|
|
82
85
|
};
|
|
@@ -97,6 +100,7 @@ export default {
|
|
|
97
100
|
:disabled="disabled || opt.disabled"
|
|
98
101
|
role="button"
|
|
99
102
|
:aria-label="actionAriaLabel(opt)"
|
|
103
|
+
:aria-pressed="isPressed(opt)"
|
|
100
104
|
@click="change(opt.value)"
|
|
101
105
|
>
|
|
102
106
|
<slot
|
|
@@ -37,7 +37,7 @@ export default {
|
|
|
37
37
|
handleLineBreaksConsentText(banner) {
|
|
38
38
|
if (banner.text?.length) {
|
|
39
39
|
// split text by newline char
|
|
40
|
-
const textArray = banner.text.split(
|
|
40
|
+
const textArray = banner.text.split('\n').filter((element) => element);
|
|
41
41
|
|
|
42
42
|
if (textArray.length > 1) {
|
|
43
43
|
textArray.forEach((str, i) => {
|
|
@@ -130,11 +130,11 @@ export default {
|
|
|
130
130
|
|
|
131
131
|
if (isEmpty(banner)) {
|
|
132
132
|
if (showHeader && this.header) {
|
|
133
|
-
bannerContent = bannerHeader || {};
|
|
133
|
+
bannerContent = this.handleLineBreaksConsentText(bannerHeader) || {};
|
|
134
134
|
} else if (showConsent && this.consent) {
|
|
135
135
|
bannerContent = this.handleLineBreaksConsentText(bannerConsent) || {};
|
|
136
136
|
} else if (showFooter && this.footer) {
|
|
137
|
-
bannerContent = bannerFooter || {};
|
|
137
|
+
bannerContent = this.handleLineBreaksConsentText(bannerFooter) || {};
|
|
138
138
|
} else {
|
|
139
139
|
bannerContent = {};
|
|
140
140
|
}
|
|
@@ -168,16 +168,20 @@ export default {
|
|
|
168
168
|
>
|
|
169
169
|
<!-- text as array to support line breaks programmatically rather than just exposing HTML -->
|
|
170
170
|
<div v-if="isTextAnArray">
|
|
171
|
-
<
|
|
171
|
+
<div
|
|
172
172
|
v-for="(text, index) in banner.text"
|
|
173
173
|
:key="index"
|
|
174
|
+
class="array-row"
|
|
174
175
|
>
|
|
175
176
|
{{ text }}
|
|
176
|
-
</
|
|
177
|
+
</div>
|
|
177
178
|
</div>
|
|
178
|
-
<
|
|
179
|
+
<div
|
|
180
|
+
v-else
|
|
181
|
+
class="single-row"
|
|
182
|
+
>
|
|
179
183
|
{{ banner.text }}
|
|
180
|
-
</
|
|
184
|
+
</div>
|
|
181
185
|
</div>
|
|
182
186
|
<div v-else-if="showDialog">
|
|
183
187
|
<div class="banner-dialog-glass" />
|
|
@@ -192,16 +196,20 @@ export default {
|
|
|
192
196
|
>
|
|
193
197
|
<!-- text as array to support line breaks programmatically rather than just exposing HTML -->
|
|
194
198
|
<div v-if="isTextAnArray">
|
|
195
|
-
<
|
|
199
|
+
<div
|
|
196
200
|
v-for="(text, index) in banner.text"
|
|
197
201
|
:key="index"
|
|
202
|
+
class="array-row"
|
|
198
203
|
>
|
|
199
204
|
{{ text }}
|
|
200
|
-
</
|
|
205
|
+
</div>
|
|
201
206
|
</div>
|
|
202
|
-
<
|
|
207
|
+
<div
|
|
208
|
+
v-else
|
|
209
|
+
class="single-row"
|
|
210
|
+
>
|
|
203
211
|
{{ banner.text }}
|
|
204
|
-
</
|
|
212
|
+
</div>
|
|
205
213
|
</div>
|
|
206
214
|
<button
|
|
207
215
|
class="btn role-primary"
|
|
@@ -223,7 +231,6 @@ export default {
|
|
|
223
231
|
padding: 0 20px;
|
|
224
232
|
|
|
225
233
|
&.banner-consent {
|
|
226
|
-
position: absolute;
|
|
227
234
|
height: unset;
|
|
228
235
|
min-height: 2em;
|
|
229
236
|
overflow: hidden;
|
|
@@ -119,6 +119,7 @@ export default {
|
|
|
119
119
|
tabindex="0"
|
|
120
120
|
role="menuitem"
|
|
121
121
|
class="hand"
|
|
122
|
+
:lang="name"
|
|
122
123
|
@click.stop="switchLocale(name)"
|
|
123
124
|
@keyup.enter.stop="switchLocale(name)"
|
|
124
125
|
@keyup.space.stop="switchLocale(name)"
|
|
@@ -134,6 +135,7 @@ export default {
|
|
|
134
135
|
<Select
|
|
135
136
|
:value="selectedOption"
|
|
136
137
|
:options="localesOptions"
|
|
138
|
+
:is-lang-select="true"
|
|
137
139
|
@update:value="switchLocale($event)"
|
|
138
140
|
/>
|
|
139
141
|
</div>
|
|
@@ -282,10 +282,12 @@ export default {
|
|
|
282
282
|
<i
|
|
283
283
|
v-if="isCurrent(col) && !descending"
|
|
284
284
|
class="icon icon-sort-down icon-stack-1x"
|
|
285
|
+
:alt="t('sortableTable.alt.sortingIconDesc')"
|
|
285
286
|
/>
|
|
286
287
|
<i
|
|
287
288
|
v-if="isCurrent(col) && descending"
|
|
288
289
|
class="icon icon-sort-up icon-stack-1x"
|
|
290
|
+
:alt="t('sortableTable.alt.sortingIconAsc')"
|
|
289
291
|
/>
|
|
290
292
|
</span>
|
|
291
293
|
</div>
|
|
@@ -1081,6 +1081,8 @@ export default {
|
|
|
1081
1081
|
:class="{[bulkActionClass]:true}"
|
|
1082
1082
|
:disabled="!act.enabled"
|
|
1083
1083
|
:data-testid="componentTestid + '-' + act.action"
|
|
1084
|
+
role="button"
|
|
1085
|
+
:aria-label="act.label"
|
|
1084
1086
|
@click="applyTableAction(act, null, $event)"
|
|
1085
1087
|
@keydown.enter.stop
|
|
1086
1088
|
@mouseover="setBulkActionOfInterest(act)"
|
|
@@ -1234,13 +1236,21 @@ export default {
|
|
|
1234
1236
|
</div>
|
|
1235
1237
|
</div>
|
|
1236
1238
|
</div>
|
|
1237
|
-
<
|
|
1239
|
+
<p
|
|
1238
1240
|
v-else-if="search"
|
|
1241
|
+
id="describe-filter-sortable-table"
|
|
1242
|
+
hidden
|
|
1243
|
+
>
|
|
1244
|
+
{{ t('sortableTable.filteringDescription') }}
|
|
1245
|
+
</p>
|
|
1246
|
+
<input
|
|
1247
|
+
v-if="search"
|
|
1239
1248
|
ref="searchQuery"
|
|
1240
1249
|
v-model="eventualSearchQuery"
|
|
1241
1250
|
type="search"
|
|
1242
1251
|
class="input-sm search-box"
|
|
1243
1252
|
:aria-label="t('sortableTable.searchLabel')"
|
|
1253
|
+
aria-describedby="describe-filter-sortable-table"
|
|
1244
1254
|
:placeholder="t('sortableTable.search')"
|
|
1245
1255
|
>
|
|
1246
1256
|
<slot name="header-button" />
|
|
@@ -1532,18 +1542,28 @@ export default {
|
|
|
1532
1542
|
class="btn btn-sm role-multi-action"
|
|
1533
1543
|
data-testid="pagination-first"
|
|
1534
1544
|
:disabled="page == 1 || loading"
|
|
1545
|
+
role="button"
|
|
1546
|
+
:aria-label="t('sortableTable.ariaLabel.firstPageBtn')"
|
|
1535
1547
|
@click="goToPage('first')"
|
|
1536
1548
|
>
|
|
1537
|
-
<i
|
|
1549
|
+
<i
|
|
1550
|
+
class="icon icon-chevron-beginning"
|
|
1551
|
+
:alt="t('sortableTable.alt.firstPageBtn')"
|
|
1552
|
+
/>
|
|
1538
1553
|
</button>
|
|
1539
1554
|
<button
|
|
1540
1555
|
type="button"
|
|
1541
1556
|
class="btn btn-sm role-multi-action"
|
|
1542
1557
|
data-testid="pagination-prev"
|
|
1543
1558
|
:disabled="page == 1 || loading"
|
|
1559
|
+
role="button"
|
|
1560
|
+
:aria-label="t('sortableTable.ariaLabel.prevPageBtn')"
|
|
1544
1561
|
@click="goToPage('prev')"
|
|
1545
1562
|
>
|
|
1546
|
-
<i
|
|
1563
|
+
<i
|
|
1564
|
+
class="icon icon-chevron-left"
|
|
1565
|
+
:alt="t('sortableTable.alt.prevPageBtn')"
|
|
1566
|
+
/>
|
|
1547
1567
|
</button>
|
|
1548
1568
|
<span>
|
|
1549
1569
|
{{ pagingDisplay }}
|
|
@@ -1553,18 +1573,28 @@ export default {
|
|
|
1553
1573
|
class="btn btn-sm role-multi-action"
|
|
1554
1574
|
data-testid="pagination-next"
|
|
1555
1575
|
:disabled="page == totalPages || loading"
|
|
1576
|
+
role="button"
|
|
1577
|
+
:aria-label="t('sortableTable.ariaLabel.nextPageBtn')"
|
|
1556
1578
|
@click="goToPage('next')"
|
|
1557
1579
|
>
|
|
1558
|
-
<i
|
|
1580
|
+
<i
|
|
1581
|
+
class="icon icon-chevron-right"
|
|
1582
|
+
:alt="t('sortableTable.alt.nextPageBtn')"
|
|
1583
|
+
/>
|
|
1559
1584
|
</button>
|
|
1560
1585
|
<button
|
|
1561
1586
|
type="button"
|
|
1562
1587
|
class="btn btn-sm role-multi-action"
|
|
1563
1588
|
data-testid="pagination-last"
|
|
1564
1589
|
:disabled="page == totalPages || loading"
|
|
1590
|
+
role="button"
|
|
1591
|
+
:aria-label="t('sortableTable.ariaLabel.lastPageBtn')"
|
|
1565
1592
|
@click="goToPage('last')"
|
|
1566
1593
|
>
|
|
1567
|
-
<i
|
|
1594
|
+
<i
|
|
1595
|
+
class="icon icon-chevron-end"
|
|
1596
|
+
:alt="t('sortableTable.alt.lastPageBtn')"
|
|
1597
|
+
/>
|
|
1568
1598
|
</button>
|
|
1569
1599
|
</div>
|
|
1570
1600
|
<button
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
|
|
3
|
+
const STATUS = {
|
|
4
|
+
success: {
|
|
5
|
+
color: 'text-success',
|
|
6
|
+
icon: 'icon-checkmark'
|
|
7
|
+
},
|
|
8
|
+
warning: {
|
|
9
|
+
color: 'text-warning',
|
|
10
|
+
icon: 'icon-warning'
|
|
11
|
+
},
|
|
12
|
+
info: {
|
|
13
|
+
color: 'text-info',
|
|
14
|
+
icon: 'icon-info'
|
|
15
|
+
},
|
|
16
|
+
error: {
|
|
17
|
+
color: 'text-error',
|
|
18
|
+
icon: 'icon-error'
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const { status = 'success', label } = defineProps<{
|
|
23
|
+
status?: 'success' | 'warning' | 'info' | 'error',
|
|
24
|
+
label?: string
|
|
25
|
+
}>();
|
|
26
|
+
|
|
27
|
+
</script>
|
|
28
|
+
<template>
|
|
29
|
+
<div
|
|
30
|
+
class="status-badge"
|
|
31
|
+
>
|
|
32
|
+
<i
|
|
33
|
+
class="status-badge__icon icon"
|
|
34
|
+
:class="{
|
|
35
|
+
[STATUS[status].icon]: true,
|
|
36
|
+
[STATUS[status].color]: true
|
|
37
|
+
}"
|
|
38
|
+
/>
|
|
39
|
+
<div
|
|
40
|
+
v-if="label"
|
|
41
|
+
class="status-badge__label"
|
|
42
|
+
>
|
|
43
|
+
{{ label }}
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
</template>
|
|
47
|
+
|
|
48
|
+
<style lang="scss" scoped>
|
|
49
|
+
.status-badge {
|
|
50
|
+
align-items: center;
|
|
51
|
+
display: inline-flex;
|
|
52
|
+
border: 1px solid;
|
|
53
|
+
border-color: var(--border);
|
|
54
|
+
margin-top: 20px;
|
|
55
|
+
|
|
56
|
+
& + & {
|
|
57
|
+
margin-left: 20px;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
&__label {
|
|
61
|
+
border-left: 1px solid var(--border);
|
|
62
|
+
padding: 5px 20px;
|
|
63
|
+
color: var(--body-text);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
&__icon {
|
|
67
|
+
text-align: center;
|
|
68
|
+
padding: 5px 10px;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
</style>
|
|
@@ -40,7 +40,7 @@ describe('component: FixedBanner', () => {
|
|
|
40
40
|
expect(wrapper.vm.showHeader).toStrictEqual(true);
|
|
41
41
|
|
|
42
42
|
const bannerElem = wrapper.find('.banner');
|
|
43
|
-
const noArrayTextElem = wrapper.find('.banner
|
|
43
|
+
const noArrayTextElem = wrapper.find('.banner .single-row');
|
|
44
44
|
|
|
45
45
|
expect(bannerElem.exists()).toBe(true);
|
|
46
46
|
expect(bannerElem.classes()).not.toContain('banner-consent');
|
|
@@ -60,7 +60,7 @@ describe('component: FixedBanner', () => {
|
|
|
60
60
|
expect(wrapper.vm.showFooter).toStrictEqual(true);
|
|
61
61
|
|
|
62
62
|
const bannerElem = wrapper.find('.banner');
|
|
63
|
-
const noArrayTextElem = wrapper.find('.banner
|
|
63
|
+
const noArrayTextElem = wrapper.find('.banner .single-row');
|
|
64
64
|
|
|
65
65
|
expect(bannerElem.exists()).toBe(true);
|
|
66
66
|
expect(bannerElem.classes()).not.toContain('banner-consent');
|
|
@@ -84,7 +84,7 @@ describe('component: FixedBanner', () => {
|
|
|
84
84
|
const bannerDialogElem = wrapper.find('.banner-dialog');
|
|
85
85
|
const bannerDialogFrameElem = wrapper.find('.banner-dialog-frame');
|
|
86
86
|
const buttonDialog = wrapper.find('.banner-dialog button');
|
|
87
|
-
const noArrayTextElem = wrapper.find('.banner
|
|
87
|
+
const noArrayTextElem = wrapper.find('.banner .single-row');
|
|
88
88
|
|
|
89
89
|
expect(bannerElem.exists()).toBe(true);
|
|
90
90
|
expect(bannerDialogGlassElem.exists()).toBe(true);
|
|
@@ -87,6 +87,10 @@ export default {
|
|
|
87
87
|
type: Boolean,
|
|
88
88
|
default: null
|
|
89
89
|
},
|
|
90
|
+
isLangSelect: {
|
|
91
|
+
type: Boolean,
|
|
92
|
+
default: false
|
|
93
|
+
},
|
|
90
94
|
},
|
|
91
95
|
|
|
92
96
|
methods: {
|
|
@@ -289,8 +293,13 @@ export default {
|
|
|
289
293
|
@open="resizeHandler"
|
|
290
294
|
@option:created="(e) => $emit('createdListItem', e)"
|
|
291
295
|
>
|
|
292
|
-
<template
|
|
293
|
-
|
|
296
|
+
<template
|
|
297
|
+
#option="option"
|
|
298
|
+
>
|
|
299
|
+
<div
|
|
300
|
+
:lang="isLangSelect ? option.value : undefined"
|
|
301
|
+
@mousedown="(e) => onClickOption(option, e)"
|
|
302
|
+
>
|
|
294
303
|
{{ getOptionLabel(option.label) }}
|
|
295
304
|
</div>
|
|
296
305
|
</template>
|
|
@@ -206,7 +206,7 @@ export default {
|
|
|
206
206
|
}
|
|
207
207
|
|
|
208
208
|
if (this.outputModifier) {
|
|
209
|
-
out = out === null ? null : `${ inputValue }${ this.unit }`;
|
|
209
|
+
out = out === null ? null : `${ parseInt(inputValue) }${ this.unit }`;
|
|
210
210
|
} else if ( this.outputAs === 'string' ) {
|
|
211
211
|
out = out === null ? '' : `${ inputValue }`;
|
|
212
212
|
} else if (out) {
|
|
@@ -235,7 +235,7 @@ export default {
|
|
|
235
235
|
:required="required"
|
|
236
236
|
:placeholder="placeholder"
|
|
237
237
|
:hide-arrows="hideArrows"
|
|
238
|
-
@
|
|
238
|
+
@update:value="update"
|
|
239
239
|
@blur="update($event.target.value)"
|
|
240
240
|
>
|
|
241
241
|
<template #suffix>
|
|
@@ -11,7 +11,7 @@ describe('component: UnitInput', () => {
|
|
|
11
11
|
expect(wrapper.isVisible()).toBe(true);
|
|
12
12
|
});
|
|
13
13
|
|
|
14
|
-
it.each(['blur', '
|
|
14
|
+
it.each(['blur', 'update:value'])('should emit input event when "%p" is fired', async(event) => {
|
|
15
15
|
const wrapper = mount(UnitInput, { props: { value: 1, delay: 0 } });
|
|
16
16
|
const input = wrapper.find('input');
|
|
17
17
|
|
|
@@ -20,7 +20,7 @@ describe('component: UnitInput', () => {
|
|
|
20
20
|
input.trigger(event);
|
|
21
21
|
|
|
22
22
|
expect(wrapper.emitted('update:value')).toBeTruthy();
|
|
23
|
-
expect(wrapper.emitted('update:value')[
|
|
23
|
+
expect(wrapper.emitted('update:value')[1]).toStrictEqual([4]);
|
|
24
24
|
});
|
|
25
25
|
|
|
26
26
|
it.each([
|
|
@@ -184,7 +184,7 @@ describe('component: UnitInput', () => {
|
|
|
184
184
|
input.trigger('blur');
|
|
185
185
|
|
|
186
186
|
expect(wrapper.emitted('update:value')).toBeTruthy();
|
|
187
|
-
expect(wrapper.emitted('update:value')[
|
|
187
|
+
expect(wrapper.emitted('update:value')[0][0]).toBe(value);
|
|
188
188
|
});
|
|
189
189
|
|
|
190
190
|
describe.each([
|
|
@@ -207,7 +207,7 @@ describe('component: UnitInput', () => {
|
|
|
207
207
|
expect(inputElement.value).toBe('123');
|
|
208
208
|
});
|
|
209
209
|
|
|
210
|
-
it.each(['
|
|
210
|
+
it.each(['update:value', 'blur'])('on %p 123 should display input value 123', async(trigger) => {
|
|
211
211
|
const wrapper = mount(UnitInput, {
|
|
212
212
|
props: {
|
|
213
213
|
value: '0',
|
|
@@ -248,7 +248,6 @@ describe('component: UnitInput', () => {
|
|
|
248
248
|
const input = wrapper.find('input');
|
|
249
249
|
|
|
250
250
|
await input.trigger('update:value');
|
|
251
|
-
await input.trigger('input');
|
|
252
251
|
|
|
253
252
|
expect(input.element.value).toBe('123');
|
|
254
253
|
});
|
|
@@ -10,6 +10,9 @@ export default {
|
|
|
10
10
|
computed: {
|
|
11
11
|
isFavorite() {
|
|
12
12
|
return this.$store.getters['type-map/isFavorite'](this.resource);
|
|
13
|
+
},
|
|
14
|
+
ariaLabel() {
|
|
15
|
+
return this.t(`resourceDetail.masthead.ariaLabel.${ this.isFavorite ? 'unfavoriteAction' : 'favoriteAction' }`, { resource: this.resource });
|
|
13
16
|
}
|
|
14
17
|
},
|
|
15
18
|
|
|
@@ -28,10 +31,11 @@ export default {
|
|
|
28
31
|
<template>
|
|
29
32
|
<i
|
|
30
33
|
:tabindex="0"
|
|
31
|
-
:aria-
|
|
34
|
+
:aria-pressed="!!isFavorite"
|
|
32
35
|
class="favorite icon"
|
|
33
36
|
:class="{'icon-star-open': !isFavorite, 'icon-star': isFavorite}"
|
|
34
37
|
aria-role="button"
|
|
38
|
+
:aria-label="ariaLabel"
|
|
35
39
|
@click.stop.prevent="toggle"
|
|
36
40
|
@keydown.enter.prevent="toggle"
|
|
37
41
|
@keydown.space.prevent="toggle"
|
package/components/nav/Group.vue
CHANGED
package/components/nav/Jump.vue
CHANGED
|
@@ -71,6 +71,12 @@ export default {
|
|
|
71
71
|
|
|
72
72
|
<template>
|
|
73
73
|
<div>
|
|
74
|
+
<p
|
|
75
|
+
id="describe-filter-resource-search"
|
|
76
|
+
hidden
|
|
77
|
+
>
|
|
78
|
+
{{ t('nav.resourceSearch.filteringDescription') }}
|
|
79
|
+
</p>
|
|
74
80
|
<input
|
|
75
81
|
ref="input"
|
|
76
82
|
v-model="value"
|
|
@@ -78,6 +84,7 @@ export default {
|
|
|
78
84
|
class="search"
|
|
79
85
|
role="textbox"
|
|
80
86
|
:aria-label="t('nav.resourceSearch.label')"
|
|
87
|
+
aria-describedby="describe-filter-resource-search"
|
|
81
88
|
@keyup.esc="$emit('closeSearch')"
|
|
82
89
|
>
|
|
83
90
|
<div class="results">
|
|
@@ -36,7 +36,7 @@ export default {
|
|
|
36
36
|
:aria-checked="!!pinned"
|
|
37
37
|
class="pin icon"
|
|
38
38
|
:class="{'icon-pin-outlined': !pinned, 'icon-pin': pinned}"
|
|
39
|
-
|
|
39
|
+
role="button"
|
|
40
40
|
:aria-label="t('nav.ariaLabel.pinCluster', { cluster: cluster.label })"
|
|
41
41
|
@click.stop.prevent="toggle"
|
|
42
42
|
@keydown.enter.prevent="toggle"
|
|
@@ -14,7 +14,6 @@ import { SETTING } from '@shell/config/settings';
|
|
|
14
14
|
import { getProductFromRoute } from '@shell/utils/router';
|
|
15
15
|
import { isRancherPrime } from '@shell/config/version';
|
|
16
16
|
import Pinned from '@shell/components/nav/Pinned';
|
|
17
|
-
import { getGlobalBannerFontSizes } from '@shell/utils/banners';
|
|
18
17
|
import { TopLevelMenuHelperPagination, TopLevelMenuHelperLegacy } from '@shell/components/nav/TopLevelMenu.helper';
|
|
19
18
|
import { debounce } from 'lodash';
|
|
20
19
|
import { sameContents } from '@shell/utils/array';
|
|
@@ -82,15 +81,6 @@ export default {
|
|
|
82
81
|
return this.$store.getters['prefs/get'](PINNED_CLUSTERS);
|
|
83
82
|
},
|
|
84
83
|
|
|
85
|
-
sideMenuStyle() {
|
|
86
|
-
const globalBannerSettings = getGlobalBannerFontSizes(this.$store);
|
|
87
|
-
|
|
88
|
-
return {
|
|
89
|
-
marginBottom: globalBannerSettings?.footerFont,
|
|
90
|
-
marginTop: globalBannerSettings?.headerFont
|
|
91
|
-
};
|
|
92
|
-
},
|
|
93
|
-
|
|
94
84
|
showClusterSearch() {
|
|
95
85
|
return this.allClustersCount > this.maxClustersToShow;
|
|
96
86
|
},
|
|
@@ -483,7 +473,6 @@ export default {
|
|
|
483
473
|
data-testid="side-menu"
|
|
484
474
|
class="side-menu"
|
|
485
475
|
:class="{'menu-open': shown, 'menu-close':!shown}"
|
|
486
|
-
:style="sideMenuStyle"
|
|
487
476
|
tabindex="-1"
|
|
488
477
|
role="navigation"
|
|
489
478
|
:aria-label="t('nav.ariaLabel.topLevelMenu')"
|
|
@@ -1002,7 +991,7 @@ export default {
|
|
|
1002
991
|
}
|
|
1003
992
|
}
|
|
1004
993
|
|
|
1005
|
-
position:
|
|
994
|
+
position: absolute;
|
|
1006
995
|
top: 0;
|
|
1007
996
|
left: 0px;
|
|
1008
997
|
bottom: 0;
|