@rancher/shell 3.0.2 → 3.0.4

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.
Files changed (58) hide show
  1. package/assets/styles/themes/_light.scss +1 -2
  2. package/assets/styles/themes/_suse.scss +1 -0
  3. package/assets/translations/en-us.yaml +19 -3
  4. package/chart/monitoring/prometheus/index.vue +13 -10
  5. package/components/ButtonGroup.vue +4 -0
  6. package/components/LocaleSelector.vue +2 -0
  7. package/components/PromptRemove.vue +1 -1
  8. package/components/SortableTable/THead.vue +2 -0
  9. package/components/SortableTable/index.vue +68 -12
  10. package/components/StatusBadge.vue +10 -4
  11. package/components/auth/Principal.vue +9 -3
  12. package/components/form/ArrayList.vue +9 -0
  13. package/components/form/KeyValue.vue +1 -1
  14. package/components/form/MatchExpressions.vue +4 -0
  15. package/components/form/Select.vue +11 -2
  16. package/components/nav/Favorite.vue +5 -1
  17. package/components/nav/Group.vue +4 -0
  18. package/components/nav/Jump.vue +7 -0
  19. package/components/nav/Pinned.vue +1 -1
  20. package/components/nav/Type.vue +1 -0
  21. package/config/router/routes.js +1 -0
  22. package/core/plugin-routes.ts +5 -115
  23. package/core/plugins.js +1 -1
  24. package/core/types.ts +18 -2
  25. package/detail/__tests__/autoscaling.horizontalpodautoscaler.test.ts +84 -23
  26. package/detail/autoscaling.horizontalpodautoscaler/index.vue +13 -3
  27. package/dialog/DeactivateDriverDialog.vue +4 -4
  28. package/dialog/GitRepoForceUpdateDialog.vue +1 -1
  29. package/edit/auth/ldap/__tests__/config.test.ts +0 -14
  30. package/edit/auth/ldap/config.vue +0 -24
  31. package/edit/autoscaling.horizontalpodautoscaler/metric-identifier.vue +5 -2
  32. package/edit/fleet.cattle.io.clustergroup.vue +5 -3
  33. package/edit/fleet.cattle.io.gitrepo.vue +2 -0
  34. package/edit/logging-flow/Match.vue +1 -1
  35. package/edit/provisioning.cattle.io.cluster/tabs/Advanced.vue +5 -2
  36. package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +1 -1
  37. package/machine-config/__tests__/vmwarevsphere.test.ts +48 -3
  38. package/machine-config/vmwarevsphere.vue +16 -0
  39. package/models/__tests__/logging.banzaicloud.io.flow.test.ts +88 -0
  40. package/models/logging.banzaicloud.io.flow.js +2 -1
  41. package/package.json +2 -2
  42. package/pages/about.vue +16 -8
  43. package/promptRemove/management.cattle.io.fleetworkspace.vue +1 -1
  44. package/promptRemove/management.cattle.io.globalrole.vue +1 -1
  45. package/promptRemove/management.cattle.io.project.vue +2 -2
  46. package/promptRemove/management.cattle.io.roletemplate.vue +1 -1
  47. package/promptRemove/pod.vue +1 -1
  48. package/rancher-components/Form/Checkbox/Checkbox.vue +9 -1
  49. package/rancher-components/Form/LabeledInput/LabeledInput.vue +7 -2
  50. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +3 -3
  51. package/rancher-components/RcDropdown/RcDropdown.vue +3 -3
  52. package/rancher-components/RcDropdown/RcDropdownMenu.vue +4 -2
  53. package/rancher-components/RcDropdown/RcDropdownTrigger.vue +2 -2
  54. package/scripts/test-plugins-build.sh +4 -6
  55. package/types/shell/index.d.ts +1 -1
  56. package/utils/__tests__/string.test.ts +2 -2
  57. package/utils/color.js +9 -8
  58. package/utils/string.js +1 -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 : #{$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
@@ -2523,6 +2521,7 @@ fleet:
2523
2521
  placeholder: "Paste in one or more certificates, starting with -----BEGIN CERTIFICATE----"
2524
2522
  paths:
2525
2523
  label: Paths
2524
+ ariaLabel: Enter path for Git Repo
2526
2525
  placeholder: e.g. /directory/in/your/repo
2527
2526
  addLabel: Add Path
2528
2527
  empty: The root of the repo is used by default. Multiple different directories can be provided.
@@ -2779,6 +2778,7 @@ hpa:
2779
2778
  label: Metric Name
2780
2779
  placeholder: e.g. packets-per-second
2781
2780
  selector:
2781
+ header: Metric Selector
2782
2782
  label: Add Selector
2783
2783
  metricTarget:
2784
2784
  averageVal:
@@ -5138,6 +5138,9 @@ resourceDetail:
5138
5138
  stage: "Stage from {subtype} {name}"
5139
5139
  view: "{subtype} {name}"
5140
5140
  masthead:
5141
+ ariaLabel:
5142
+ favoriteAction: Add {resource} to your starred/favorites list
5143
+ unfavoriteAction: Remove {resource} from your starred/favorites list
5141
5144
  age: Age
5142
5145
  createdBy: Created by
5143
5146
  restartCount: Pod Restarts
@@ -5490,6 +5493,18 @@ setup:
5490
5493
  welcome: Welcome to {vendor}!
5491
5494
 
5492
5495
  sortableTable:
5496
+ ariaLabel:
5497
+ firstPageBtn: First page of results
5498
+ prevPageBtn: Previous page of results
5499
+ nextPageBtn: Next page of results
5500
+ lastPageBtn: Last page of results
5501
+ alt:
5502
+ firstPageBtn: First page of results icon
5503
+ prevPageBtn: Previous page of results icon
5504
+ nextPageBtn: Next page of results icon
5505
+ lastPageBtn: Last page of results icon
5506
+ sortingIconDesc: Table header descending sort icon
5507
+ sortingIconAsc: Table header ascending sort icon
5493
5508
  genericGroupCheckbox: Table group selection checkbox
5494
5509
  genericRowCheckbox: Table row selection checkbox for item {item}
5495
5510
  tableActionsLabel: More actions - { resource }
@@ -5518,6 +5533,7 @@ sortableTable:
5518
5533
  searchLabel: Filter table results
5519
5534
  in: in
5520
5535
  addFilter: Add Filter
5536
+ filteringDescription: Using this input will immediately filter the results in the table below
5521
5537
  filterFor: Filter for...
5522
5538
  selectCol: Select a column
5523
5539
  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
@@ -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>
@@ -354,7 +354,7 @@ export default {
354
354
  <div class="mb-10">
355
355
  <template v-if="!hasCustomRemove">
356
356
  {{ t('promptRemove.attemptingToRemove', { type }) }} <span
357
- v-clean-html="resourceNames(names, t)"
357
+ v-clean-html="resourceNames(names, null, t)"
358
358
  />
359
359
  </template>
360
360
 
@@ -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>
@@ -1,7 +1,8 @@
1
1
  <script>
2
2
  import { mapGetters } from 'vuex';
3
- import { defineAsyncComponent, useTemplateRef, onMounted, onBeforeUnmount } from 'vue';
3
+ import { defineAsyncComponent, ref, onMounted, onBeforeUnmount } from 'vue';
4
4
  import day from 'dayjs';
5
+ import semver from 'semver';
5
6
  import isEmpty from 'lodash/isEmpty';
6
7
  import { dasherize, ucFirst } from '@shell/utils/string';
7
8
  import { get, clone } from '@shell/utils/object';
@@ -24,6 +25,7 @@ import { getParent } from '@shell/utils/dom';
24
25
  import { FORMATTERS } from '@shell/components/SortableTable/sortable-config';
25
26
  import ButtonMultiAction from '@shell/components/ButtonMultiAction.vue';
26
27
  import ActionMenu from '@shell/components/ActionMenuShell.vue';
28
+ import { getVersionInfo } from '@shell/utils/version';
27
29
 
28
30
  // Uncomment for table performance debugging
29
31
  // import tableDebug from './debug';
@@ -528,7 +530,7 @@ export default {
528
530
  },
529
531
  },
530
532
  setup(_props, { emit }) {
531
- const table = useTemplateRef('table');
533
+ const table = ref(null);
532
534
 
533
535
  const handleEnterKey = (event) => {
534
536
  if (event.key === 'Enter' && !event.target?.classList?.contains('checkbox-custom')) {
@@ -543,6 +545,8 @@ export default {
543
545
  onBeforeUnmount(() => {
544
546
  table.value.removeEventListener('keyup', handleEnterKey);
545
547
  });
548
+
549
+ return { table };
546
550
  },
547
551
 
548
552
  created() {
@@ -763,6 +767,12 @@ export default {
763
767
  });
764
768
 
765
769
  return rows;
770
+ },
771
+
772
+ featureDropdownMenu() {
773
+ const { fullVersion } = getVersionInfo(this.$store);
774
+
775
+ return semver.gte(semver.coerce(fullVersion).version, '2.11.0');
766
776
  }
767
777
  },
768
778
 
@@ -1081,6 +1091,8 @@ export default {
1081
1091
  :class="{[bulkActionClass]:true}"
1082
1092
  :disabled="!act.enabled"
1083
1093
  :data-testid="componentTestid + '-' + act.action"
1094
+ role="button"
1095
+ :aria-label="act.label"
1084
1096
  @click="applyTableAction(act, null, $event)"
1085
1097
  @keydown.enter.stop
1086
1098
  @mouseover="setBulkActionOfInterest(act)"
@@ -1234,13 +1246,21 @@ export default {
1234
1246
  </div>
1235
1247
  </div>
1236
1248
  </div>
1237
- <input
1249
+ <p
1238
1250
  v-else-if="search"
1251
+ id="describe-filter-sortable-table"
1252
+ hidden
1253
+ >
1254
+ {{ t('sortableTable.filteringDescription') }}
1255
+ </p>
1256
+ <input
1257
+ v-if="search"
1239
1258
  ref="searchQuery"
1240
1259
  v-model="eventualSearchQuery"
1241
1260
  type="search"
1242
1261
  class="input-sm search-box"
1243
1262
  :aria-label="t('sortableTable.searchLabel')"
1263
+ aria-describedby="describe-filter-sortable-table"
1244
1264
  :placeholder="t('sortableTable.search')"
1245
1265
  >
1246
1266
  <slot name="header-button" />
@@ -1477,11 +1497,27 @@ export default {
1477
1497
  :row="row.row"
1478
1498
  :index="i"
1479
1499
  >
1480
- <ActionMenu
1481
- :resource="row.row"
1482
- :data-testid="componentTestid + '-' + i + '-action-button'"
1483
- :button-aria-label="t('sortableTable.tableActionsLabel', { resource: row?.row?.id || '' })"
1484
- />
1500
+ <template v-if="featureDropdownMenu">
1501
+ <ActionMenu
1502
+ :resource="row.row"
1503
+ :data-testid="componentTestid + '-' + i + '-action-button'"
1504
+ :button-aria-label="t('sortableTable.tableActionsLabel', { resource: row?.row?.id || '' })"
1505
+ />
1506
+ </template>
1507
+ <template v-else>
1508
+ <ButtonMultiAction
1509
+ :id="`actionButton+${i}+${(row.row && row.row.name) ? row.row.name : ''}`"
1510
+ :ref="`actionButton${i}`"
1511
+ aria-haspopup="true"
1512
+ aria-expanded="false"
1513
+ :aria-label="t('sortableTable.tableActionsLabel', { resource: row?.row?.id || '' })"
1514
+ :data-testid="componentTestid + '-' + i + '-action-button'"
1515
+ :borderless="true"
1516
+ @click="handleActionButtonClick(i, $event)"
1517
+ @keyup.enter="handleActionButtonClick(i, $event)"
1518
+ @keyup.space="handleActionButtonClick(i, $event)"
1519
+ />
1520
+ </template>
1485
1521
  </slot>
1486
1522
  </td>
1487
1523
  </tr>
@@ -1532,18 +1568,28 @@ export default {
1532
1568
  class="btn btn-sm role-multi-action"
1533
1569
  data-testid="pagination-first"
1534
1570
  :disabled="page == 1 || loading"
1571
+ role="button"
1572
+ :aria-label="t('sortableTable.ariaLabel.firstPageBtn')"
1535
1573
  @click="goToPage('first')"
1536
1574
  >
1537
- <i class="icon icon-chevron-beginning" />
1575
+ <i
1576
+ class="icon icon-chevron-beginning"
1577
+ :alt="t('sortableTable.alt.firstPageBtn')"
1578
+ />
1538
1579
  </button>
1539
1580
  <button
1540
1581
  type="button"
1541
1582
  class="btn btn-sm role-multi-action"
1542
1583
  data-testid="pagination-prev"
1543
1584
  :disabled="page == 1 || loading"
1585
+ role="button"
1586
+ :aria-label="t('sortableTable.ariaLabel.prevPageBtn')"
1544
1587
  @click="goToPage('prev')"
1545
1588
  >
1546
- <i class="icon icon-chevron-left" />
1589
+ <i
1590
+ class="icon icon-chevron-left"
1591
+ :alt="t('sortableTable.alt.prevPageBtn')"
1592
+ />
1547
1593
  </button>
1548
1594
  <span>
1549
1595
  {{ pagingDisplay }}
@@ -1553,18 +1599,28 @@ export default {
1553
1599
  class="btn btn-sm role-multi-action"
1554
1600
  data-testid="pagination-next"
1555
1601
  :disabled="page == totalPages || loading"
1602
+ role="button"
1603
+ :aria-label="t('sortableTable.ariaLabel.nextPageBtn')"
1556
1604
  @click="goToPage('next')"
1557
1605
  >
1558
- <i class="icon icon-chevron-right" />
1606
+ <i
1607
+ class="icon icon-chevron-right"
1608
+ :alt="t('sortableTable.alt.nextPageBtn')"
1609
+ />
1559
1610
  </button>
1560
1611
  <button
1561
1612
  type="button"
1562
1613
  class="btn btn-sm role-multi-action"
1563
1614
  data-testid="pagination-last"
1564
1615
  :disabled="page == totalPages || loading"
1616
+ role="button"
1617
+ :aria-label="t('sortableTable.ariaLabel.lastPageBtn')"
1565
1618
  @click="goToPage('last')"
1566
1619
  >
1567
- <i class="icon icon-chevron-end" />
1620
+ <i
1621
+ class="icon icon-chevron-end"
1622
+ :alt="t('sortableTable.alt.lastPageBtn')"
1623
+ />
1568
1624
  </button>
1569
1625
  </div>
1570
1626
  <button
@@ -19,10 +19,16 @@ const STATUS = {
19
19
  }
20
20
  };
21
21
 
22
- const { status = 'success', label } = defineProps<{
23
- status?: 'success' | 'warning' | 'info' | 'error',
24
- label?: string
25
- }>();
22
+ withDefaults(
23
+ defineProps<{
24
+ status?: 'success' | 'warning' | 'info' | 'error',
25
+ label?: string
26
+ }>(),
27
+ {
28
+ status: 'success',
29
+ label: '',
30
+ }
31
+ );
26
32
 
27
33
  </script>
28
34
  <template>
@@ -98,9 +98,9 @@ export default {
98
98
  >
99
99
  <table>
100
100
  <tbody>
101
- <tr><td>{{ t('principal.name') }}: </td><td>{{ principal.name || principal.loginName }}</td></tr>
102
- <tr><td>{{ t('principal.loginName') }}: </td><td>{{ principal.loginName }}</td></tr>
103
- <tr><td>{{ t('principal.type') }}: </td><td>{{ principal.displayType }}</td></tr>
101
+ <tr><th>{{ t('principal.name') }}: </th><td>{{ principal.name || principal.loginName }}</td></tr>
102
+ <tr><th>{{ t('principal.loginName') }}: </th><td>{{ principal.loginName }}</td></tr>
103
+ <tr><th>{{ t('principal.type') }}: </th><td>{{ principal.displayType }}</td></tr>
104
104
  </tbody>
105
105
  </table>
106
106
  </div>
@@ -164,6 +164,12 @@ export default {
164
164
  grid-template-rows: auto math.div($size, 2);
165
165
  column-gap: 10px;
166
166
 
167
+ th {
168
+ text-align: left;
169
+ font-weight: normal;
170
+ padding-right: 10px;
171
+ }
172
+
167
173
  &.showLabels {
168
174
  grid-template-areas:
169
175
  "avatar name";
@@ -94,6 +94,10 @@ export default {
94
94
  // we only want functions in the rules array
95
95
  validator: (rules) => rules.every((rule) => ['function'].includes(typeof rule))
96
96
  },
97
+ a11yLabel: {
98
+ type: String,
99
+ default: '',
100
+ },
97
101
  },
98
102
  data() {
99
103
  const input = (Array.isArray(this.value) ? this.value : []).slice();
@@ -316,6 +320,7 @@ export default {
316
320
  :data-testid="`input-${idx}`"
317
321
  :placeholder="valuePlaceholder"
318
322
  :disabled="isView || disabled"
323
+ :aria-label="a11yLabel ? a11yLabel : undefined"
319
324
  @paste="onPaste(idx, $event)"
320
325
  >
321
326
  </slot>
@@ -336,6 +341,8 @@ export default {
336
341
  :disabled="isView"
337
342
  class="btn role-link"
338
343
  :data-testid="`remove-item-${idx}`"
344
+ :aria-label="`${_removeLabel} ${idx + 1}`"
345
+ role="button"
339
346
  @click="remove(row, idx)"
340
347
  >
341
348
  {{ _removeLabel }}
@@ -368,6 +375,8 @@ export default {
368
375
  class="btn role-tertiary add"
369
376
  :disabled="loading || disableAdd"
370
377
  data-testid="array-list-button"
378
+ :aria-label="_addLabel"
379
+ role="button"
371
380
  @click="add()"
372
381
  >
373
382
  <i
@@ -823,7 +823,7 @@ export default {
823
823
  type="button"
824
824
  role="button"
825
825
  :disabled="isView || isProtected(row.key) || disabled"
826
- :aria-label="removeLabel || t('generic.remove')"
826
+ :aria-label="`${removeLabel || t('generic.remove')} ${ i+1 }`"
827
827
  class="btn role-link"
828
828
  @click="remove(i)"
829
829
  >
@@ -242,6 +242,10 @@ export default {
242
242
 
243
243
  <template>
244
244
  <div>
245
+ <slot
246
+ v-if="rules.length"
247
+ name="header"
248
+ />
245
249
  <button
246
250
  v-if="showRemove && !isView"
247
251
  type="button"
@@ -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 #option="option">
293
- <div @mousedown="(e) => onClickOption(option, e)">
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>
@@ -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-checked="!!isFavorite"
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"
@@ -403,6 +403,10 @@ export default {
403
403
  padding: 10px 7px 9px 7px !important;
404
404
  }
405
405
  }
406
+
407
+ &:deep() .type-link > .label {
408
+ padding-left: 10px;
409
+ }
406
410
  }
407
411
 
408
412
  &:not(.depth-0) {
@@ -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
- aria-role="button"
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"
@@ -122,6 +122,7 @@ export default {
122
122
  :aria-label="type.labelKey ? t(type.labelKey) : (type.labelDisplay || type.label)"
123
123
  :href="href"
124
124
  class="type-link"
125
+ :aria-current="isActive ? 'page' : undefined"
125
126
  @click="selectType(); navigate($event);"
126
127
  @mouseenter="setNear(true)"
127
128
  @mouseleave="setNear(false)"
@@ -23,6 +23,7 @@ const interopDefault = (promise) => promise.then((page) => page.default || page)
23
23
  */
24
24
  export default [
25
25
  {
26
+ name: 'root',
26
27
  path: '/',
27
28
  component: () => interopDefault(import('@shell/pages/index.vue')),
28
29
  meta: { requiresAuthentication: true },